Передача массива в хранимую процедуру Oracle

aidynchik

Всем доброго дня! Знаю, что это не раз обсуждалось, но решения я не нашел, в интернете полно примеров простого одномерного массива.В Оракле в процедуре следующее
procedure Load_currency_course_reuters(
 Cur_Arr_ in gs_currency_course_load.TCur_Arr,
 WORK_DATE_ in date,
...
где TCur_Arr это
type TCur_Rec is record (
 curId integer,
 curCode varchar2(3),
 val numeric,
 course numeric,
 curNameRus varchar2(100),
 curNameKaz varchar2(100),
 curFactor integer
);

type TCur_Arr is table of TCur_Rec index by binary_integer;
В C# имеется массив вида
public struct CurArr
 {
 public int curId;
 public String curCode;
 public ****** val;
 public ****** course;
 public String curNameRus;
 public String curNameKaz;
 public int curFactor;
 }
Я пишу так
OracleCommand command = new OracleCommand("begin gs_currency_course_load.load_currency_course_reuters(:Cur_Arr_, :WORK_DATE_, :Err_Code, :Err_Msg); end;", conn);
 OracleParameter p = new OracleParameter();
 p.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
 p.ParameterName = "Cur_Arr_";
 p.Size = curArr.Length;
 //p.ArrayBindSize = new [][curArr.Length];
 p.Value = curArr;
 p.Direction = ParameterDirection.Input;
Ошибка на "p.Value = curArr;" - Значение не попадает в ожидаемый диапазон.Пробовал по-разному, что находил в интернете, но ничего не получилось.
12 ответов

aidynchik

aidynchik,Передавайте в виде строки с элементами через разделитель.А внутри сразу в табличку для join.Мало ли какие типы в базе есть.imho.


aidynchik

Petro123,да, я думал над этим, но хочется как-то покрасивше


aidynchik

покрасивше
Очень сложное понятие в архитектуре.Неоднозначное.Например, технически красиво это когда бд не зависит от клиента.В веб к клиенту передается json а не HTML.Так и в шарпе красивее передавать через простые типы.Особенно когда у вас передается массив размеров обуви))))Удачи!


aidynchik

Так и в шарпе красивее передавать через простые типы.
К таким заявлениям следовало бы добавлять "по моему мнению" - а то еще кто-нибудь воспримет их всерьез.aidynchik,есть подозрение, что передача массивов работает только для примитивных типов - см. здесь: https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:1857352500346934865
ODP.NET does not support binding a table of records (multidimensional array) as this is a limitation of the Oracle Call Interface API.
Fix 1: ODP.NET does support PL/SQL Associative arrays in which you can pass an array of single scalar types.
Выход - сериализуйте массив в XML, передавайте как XMLType (ну, или CLOB - не помню, поддерживает ли ODP xml-тип), и внутри процедуры разбирайте через XMLTable.


aidynchik

Сон Веры Павловны,ок, спасибо!


aidynchik

Сон Веры Павловны,В архитектуре всегда неоднозначно и компромиссы)Сначала xml, потом bulk insert, потом...табличный тип, потом...


aidynchik

Сон Веры Павловны,Кстати вы Point передаете как x, y или Point?


aidynchik

Сон Веры Павловны,Кстати вы Point передаете как x, y или Point?
Point - скалярный тип, а не массив, как у ТС. В случае массива и при наличии возможности - разумеется, как массив Point.


aidynchik

Сон Веры Павловны,Возможности понаставить библиотек для поддержки геометрии всегда полно.А вот понять границу лишних преобразований (оверхед) сложнее.Какого фига я должен в оракле разбирать xml, если строка 22;44;66 таи парсится одним оператором?


aidynchik

Сон Веры Павловны,
open v_refcur for select * from table where instr(входнаяСтрока||',', to_char(id) || ',')>0;
...NUMBER_LIST_TYPE_GET_LIST_ELEMENTSIMHO


aidynchik

Какого фига я должен в оракле разбирать xml, если строка 22;44;66 таи парсится одним оператором?
Не хочется - ради б-га, не разбирайте, и стройте свои костыли. У автора случай несколько сложнее, чем три числа в строчку, его структура в т.ч. содержит строковые поля - что будете делать, если в одно из них попадет разделитель?Ну и парсинг XML ничего сверх из себя не представляет, все тот же один оператор XMLTable, на выходе дающий нормальную типизированную выборку.


aidynchik

один оператор XMLTable,
Раньше загружался целый COM об. Парсер операционки. Счас не знаю.Конечно, нужно смотреть в самой бд и ветке по бд.Согласен.Я type is record в базе делал в исключительных случаях.Удачи!