Значение привязки массива Oracle.DataAccess (ODP.NET) не попадает в ожидаемый диапазон

мой сценарий

я использую поставщика оракулов ODP.NET с С# 3.5, и я пытаюсь передать массив в качестве параметра для процедуры... вот так:

var paramNames = new OracleParameter();
paramNames.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
paramNames.ParameterName = "P_JOB_TITLE";
paramNames.Size = 2;
paramNames.Value =  new string[2]{ "name1", "name1" };
cmd.Parameters.Add(paramNames);

когда код среды выполнения переходит к paramNames.Value = new string[2]{ "name1", "name1" }; он ловит эту ошибку

"Значение не соответствует ожидаемому диапазону"

Кто-нибудь может это исправить?

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ

Указание OracleDbType ошибка исправлена, но выполнение дает мне некоторые ошибки

paramNames.OracleDbType = OracleDbType.Varchar2;

«Невозможно преобразовать объект типа «System.String[]» в тип «System.IConvertible».

моя цель сделать что-то вроде этого

http://aspalliance.com/621_Using_ODPNET_to_Insert_Multiple_Rows_within_a_Single_Round_Trip.3

ДРУГАЯ ПРОБЛЕМА БЕЗ ПАРАМЕТРА

Вставка параметра out, подобного этому

            paramNames = new OracleParameter();
            paramNames.ParameterName = "O_JOB_ID";
            paramNames.Size = 3;
            paramNames.Direction = ParameterDirection.Output;
            paramNames.OracleDbType = OracleDbType.Int32;
            paramNames.Value = new int[3] { 0, 0, 0 }; ;
            cmd.Parameters.Add(paramNames);

он правильно заполняется после завершения ExecuteNonQuery. Например, процедура pls-sql выполняет 3 вставки, и я возвращаю идентификатор строки каждой записи массива.

Но я что-то пошло не так, например, если 2-я строка, все параметры OUT (массив) всегда установлены на 0. Я ожидал, что по крайней мере параметр params[0].value был расширен

Спасибо


person user756037    schedule 20.06.2011    source источник


Ответы (1)


Я думаю, вы пытаетесь объединить привязку массива {просто привязываете массив к параметру, чтобы он выполнялся несколько раз — так это делается в приведенном вами примере} с Ассоциативный массив {re: PLSQLAssociativeArray с параметром INPUT TABLE OF}.

Поскольку вы не опубликовали свой пакет/процедуру, которую вы используете, я предполагаю, что вы делаете что-то вроде этого (просто кладете это, чтобы подтвердить предположение)

procedure insertdata(P_JOB_TITLE IN VARCHAR2) as
begin
insert into myTable(x) value (P_JOB_TITLE);
end  insertdata;

Чтобы выполнить это, как автор статьи, вам нужно использовать ArrayBindCount (см. эта ссылка, в ней также есть пример). Это также означает, что если у вас есть несколько параметров, для каждого из них будет ожидаться МАССИВ.

Теперь, чтобы выполнить это для всех P_JOB_TITLE(), которые вы передаете

//this was missing in your example and MUST be there to tell ODP how many array elements to expect
cmd.ArrayBindCount = 2;

 string[] jobTitleArray = {"name1", "name1"};

OracleParameter paramNames= new OracleParameter("P_JOB_TITLE", OracleDbType.Varchar2);

   //paramNames.CollectionType = OracleCollectionType.PLSQLAssociativeArray;/*once again, you are passing in an array of values to be executed and not a pl-sql table*/

    //paramNames.Size = 2; /* this is unnecessary since it is for a plsql-associative array*/
    paramNames.Value =  jobTitleArray ;
    cmd.Parameters.Add(paramNames);

Для примера plSQLAssociativeArray взгляните на примеры, предоставленные при установке ODP @ %ORA_HOME%\odp.net\samples\2.x\AssocArray.

и для примеров привязки массива (как из предоставленной вами ссылки) @%ORA_HOME%\odp.net\samples\2.x\ArrayBind

person Harrison    schedule 20.06.2011
comment
Хорошо, чувак, спасибо, я это исправил..... НО теперь у меня другая проблема... я ввожу параметр OUT в виде массива, и он работает как шарм, НО только КОГДА процедура PLSQL выполняется успешно. Если во время зацикливания массива что-то пойдет не так, все параметры массива OUT сбрасываются - person user756037; 20.06.2011
comment
@user756037 user756037 Вы выполняете какую-либо обработку исключений в выполняемом блоке pl/sql? вы должны иметь возможность захватывать и обрабатывать (или, по крайней мере, не прерывать другие элементы в массиве), не позволяя исключению всплывать. - person Harrison; 20.06.2011
comment
я вызываю только cmd.ExecuteNonQuery(); в операторе try{}catch{} и в finally{} я проверяю параметры - person user756037; 20.06.2011
comment
@user756037 user756037, если вы не можете изменить процедуру инкапсуляции ошибки, вы можете сделать то же самое через анона. block в вашем C# с обработкой исключений. например 'НАЧАЛО myProc(:myParam); исключение, когда **** заканчивается;' - person Harrison; 20.06.2011
comment
я уже реализовал обработку исключений в моей функции С#. я пытаюсь {} поймать {} код ExecuteNonQuery(). Он улавливает, как и ожидалось (нарушение ограничения уникального ключа моего теста для строки 2), но затем все параметры OUT отбеливаются - person user756037; 20.06.2011
comment
@user756037 user756037 Думаю, я не слежу за вами на 100%, но я думаю, что это гарантирует, что новый вопрос с фрагментом кода будет простым как день. - person Harrison; 20.06.2011