Вызов хранимой процедуры с таблицей параметров ЦЕЛОЧИСЛЕННОГО параметра

#c# #.net-core #entity-framework-core #ado.net #oracle18c

#c# #.net-ядро #сущность-фреймворк-ядро #ado.net #oracle18c

Вопрос:

Мне трудно работать с самым недружелюбным по совместимости движком базы данных, когда-либо известным как Oracle.

У меня есть этот пользовательский тип:

 CREATE OR REPLACE TYPE INTEGERS_ARRAY AS TABLE OF INTEGER;
  

И эта простая хранимая процедура:

 CREATE OR REPLACE PROCEDURE TEST_PROCEDURE_MAHMOUD(
    holy_array              IN INTEGERS_ARRAY,
    some_kind_of_number1    IN NUMBER,
    some_kind_of_number2    IN NUMBER,
    query_result            OUT SYS_REFCURSOR
)
AS
    BEGIN
        OPEN query_result FOR
            SELECT CODE,AIRWAYBILL_DATE,REFERENCE1,REFERENCE2 FROM SHIPMENTS
                ORDER BY AIRWAYBILL_DATE DESC
                FETCH NEXT 10 ROWS ONLY;
    end;
  

Эта хранимая процедура является упрощенной версией другой очень сложной процедуры, которая также не работает. У меня одно и то же исключение для обоих:

Oracle.Управляемый доступ к данным.Клиент.Исключение
OracleException ORA-06550: строка 1, столбец 7:
PLS-00306: неправильное число или типы аргументов при вызове ‘TEST_PROCEDURE_MAHMOUD’
ORA-06550: строка 1, столбец 7: PL / SQL: оператор игнорируется

Это то, что я пытался сделать на C#:

 var result = new List<string>();

using(var con = new OracleConnection(connectionString))
{
    using(var command = con.CreateCommand())
    {
        con.Open();
        command.CommandText = "TEST_PROCEDURE_MAHMOUD";
        command.CommandType = System.Data.CommandType.StoredProcedure;

        // Parameters
        var array = new OracleParameter("holy_array", OracleDbType.Int64, ParameterDirection.Input);
        array.UdtTypeName = "MY_SCHEMA.INTEGERS_ARRAY";
        array.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
        array.Size = 100;
        array.Value = new int[] { 100, 101 };

        var number1 = new OracleParameter("some_kind_of_number1", OracleDbType.Int64, 1, ParameterDirection.Input);
        var number2 = new OracleParameter("some_kind_of_number2", OracleDbType.Int64, 1, ParameterDirection.Input);
        var cursor = new OracleParameter("query_result", OracleDbType.RefCursor, ParameterDirection.Output);
        command.Parameters.AddRange(new[] { array, number1, number2, cursor });

        var reader = command.ExecuteReader();

        while (reader.Read())
        {
            var awb = reader.GetString(0);
            result.Add(awb);
        }
    }
}

return resu<
  

Разве Oracle не должен понимать очень простой (таблица целых чисел) тип и принимать массив целых чисел для этого типа? Как я могу решить эту проблему? Я просмотрел документацию на официальном сайте, я прочитал примеры кода на GitHub, я много искал и не смог найти ни одного рабочего примера, только обходные решения, такие как создание временной таблицы, которую я не хочу делать.

Заранее спасибо.

РЕДАКТИРОВАТЬ: основной тег Entity Framework связан с тем, что сначала я пытался сделать это с EF Core, но это не сработало, я переключился на ADO.NET , думая, что это может быть проблемой EF Core. Но оказывается, что ядро EF слишком хорошо, чтобы так меня подвести.

Ответ №1:

К сожалению, ядро Entity Framework по-прежнему не полностью поддерживает базы данных Oracle, одним из ограничений являются пользовательские типы:

Ограничения Выделенная команда успешно реализовала большинство функций, максимально поддерживающих функциональность Entity Framework для сервера Oracle, но есть некоторые ограничения, которые невозможно преодолеть.

Oracle не имеет своих эквивалентов для конструкций ВНЕШНЕГО ПРИМЕНЕНИЯ и ПЕРЕКРЕСТНОГО ПРИМЕНЕНИЯ SQL Server. Пользовательские типы, включая объекты Oracle, типы массивов и вложенные таблицы, не поддерживаются.

Источник

Комментарии:

1. Абсолютно неясно, к какой версии это относится. 2nd? Сейчас я использую EFCore 5 и до сих пор не могу понять, актуально ли это (данное сообщение относится к 2018 году).

2. Это всегда актуально, к сожалению, Oracle и .Net просто плохо сочетаются. Но когда я писал вопрос, я использовал Ef core 2

3. Я использовал следующий подход, который, кажется, работает гладко: if (command.Parameters["PATH_LIST"].Value is OracleRefCursor oracleRefCursor) и если — да, то считывание с этого курсора… (PATH_LIST — это мой выходной параметр курсора)