powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / ODAC. Передать массив в качестве параметра ХП
20 сообщений из 20, страница 1 из 1
ODAC. Передать массив в качестве параметра ХП
    #39797209
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подскажите, как правильно передать массив?

На стороне БД

Код: plsql
1.
2.
TYPE TAB_pl_dt IS TABLE OF date INDEX BY PLS_INTEGER;
procedure ins_buf(mDate  in TAB_pl_dt);



Код

1)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
oProc:= TOraStoredProc.Create(nil);
oProc.Params.Clear;
oProc.StoredProcName:= 'pkg.ins_buf';
oProc.Connection := oConnection;
oProc.Prepare;

mDate:= VarArrayCreate([0, SizeArr-1], varDate);

oProc.Params[0].DataType:= ftDateTime;
oProc.Params[0].ParamType:= ptInput;
oProc.Params[0].Table:= True;
oProc.Params[0].Length:= SizeArr;
oProc.Params[0].Value:= mDate;  //Invalid class type cast



Пробовал через oProc.Params[0].AsArray.AllocObject (вылетает с AV т.к. тип определен в пакете)
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797296
Фотография devart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте присовить значения в цикле:
Код: pascal
1.
2.
  for i := 0 to SizeArr-1 do
    oProc.Params[0][i].AsDateTime := mDate[i];
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797355
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
devart, так получается. спасибо.
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797438
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я создаю объекты ToraStoredProc и задаю параметры вручную, потому что на момент создания у меня нет сессии и поэтому использовать Prepare не могу.
Когда в главном потоке создаю объекты ToraStoredProc, то все отрабатывает хорошо, но как только я пытаюсь создать в потоках, то у меня выскакивает ошибка:
data type is not allowed for a dml array

Почему так происходит. Какая из операций не потокобезопасна?
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797445
Фотография devart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
приведите, пожалуйста, пример кода: как и что вы создаете в потоках
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797448
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
function SP_ODAC_ADD(ASize: integer): TOraStoredProc;
begin
  try
    Result:= TOraStoredProc.Create(nil);
    Result.Params.Clear;
    Result.StoredProcName:= 'pkg.ins_buf';

    Result.Params.CreateParam(ftTable, 'm1',  ptInput);
    Result.ParamByName('m1').DataType:= ftDateTime;
    Result.ParamByName('m1').Table:= True;
    Result.ParamByName('m1').Length:= ASize;

    Result.Params.CreateParam(ftTable, 'm2',  ptInput);
    Result.ParamByName('m2').DataType:= ftDateTime;
    Result.ParamByName('m2').Table:= True;
    Result.ParamByName('m2').Length:= ASize;

    Result.Params.CreateParam(ftTable, 'm3',  ptInput);
    Result.ParamByName('m3').DataType:= ftString;
    Result.ParamByName('m3').Table:= True;
    Result.ParamByName('m3').Length:= ASize;
    Result.ParamByName('m3').Size:= 10;

    Result.Params.CreateParam(ftTable, 'm4',  ptInput);
    Result.ParamByName('m4').DataType:= ftString;
    Result.ParamByName('m4').Table:= True;
    Result.ParamByName('m4').Length:= ASize;
    Result.ParamByName('m4').Size:= 10;

    Result.Params.CreateParam(ftTable, 'm5',  ptInput);
    Result.ParamByName('m5').DataType:= ftString;
    Result.ParamByName('m5').Table:= True;
    Result.ParamByName('m5').Length:= ASize;
    Result.ParamByName('m5').Size:= 10;

    Result.Params.CreateParam(ftTable, 'm6',  ptInput);
    Result.ParamByName('m6').Length:= ASize;
    Result.ParamByName('m6').DataType:= ftInteger;
    Result.ParamByName('m6').Table:= True;

    Result.Params.CreateParam(ftTable, 'm7',  ptInput);
    Result.ParamByName('m7').Length:= ASize;
    Result.ParamByName('m7').DataType:= ftInteger;
    Result.ParamByName('m7').Table:= True;

    Result.Params.CreateParam(ftTable, 'm8',  ptInput);
    Result.ParamByName('m8').Length:= ASize;
    Result.ParamByName('m8').DataType:= ftInteger;
    Result.ParamByName('m8').Table:= True;

    Result.Params.CreateParam(ftInteger, 'v_cnt',  ptInput);

  except
    on E : Exception do begin
      Result:= nil;
      WRITE_LOGER.WriteLog('(!ОШИБКА) Процедура создания SP_ODAC_ADD: ' + E.Message);
    end;
  end;
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797496
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
я вот прямо на днях столкнулся с ситуацией,
когда передать в процедуру массив через ODAC оказалось в два-три раза медленее,
чем вызвать процедуру (которая не использует массив) для каждого значения массива
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797549
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrb
Код: pascal
1.
2.
3.
4.
  Result.ParamByName('m4').DataType:= ftString;
    Result.ParamByName('m4').Table:= True;
    Result.ParamByName('m4').Length:= ASize;
    Result.ParamByName('m4').Size:= 10;

Это просто праздник какой-то! (с)
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797560
Фотография Gator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecator, white_nigger et al

Вы о каких массивах толкуете, Други?!
В сиквелах есть массивы?

Ясен пень, через временные таблицы, вьюшки, OLAP, парсеры строк (ограниченных длиной)
ну былв у меня к функция разборки вида fn '-10,0,1,2,3,10-40,99' в tempteble, но ОЧЕНЬ медленная - говно короче

Покажите квази-пенсионеру DDL please.
А если план исполнения нарисуете, вы вообще монстры!
______
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797626
энди
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну в том же mssql есть табличный параметр, с клиента на сервер можно передать данные в виде датасета. SDAC от девартов это умеет.
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797662
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_nigger, а в чем праздник?

Prepare делать не могу, так как сессию получаю непосредственно перед выполнением запроса, а по другому как параметры установить?
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797951
Фотография devart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrb
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
function SP_ODAC_ADD(ASize: integer): TOraStoredProc;
begin
  try
    Result:= TOraStoredProc.Create(nil);
    Result.Params.Clear;
    Result.StoredProcName:= 'pkg.ins_buf';

    Result.Params.CreateParam(ftTable, 'm1',  ptInput);
    Result.ParamByName('m1').DataType:= ftDateTime;
    Result.ParamByName('m1').Table:= True;
    Result.ParamByName('m1').Length:= ASize;

    Result.Params.CreateParam(ftTable, 'm2',  ptInput);
    Result.ParamByName('m2').DataType:= ftDateTime;
    Result.ParamByName('m2').Table:= True;
    Result.ParamByName('m2').Length:= ASize;

    Result.Params.CreateParam(ftTable, 'm3',  ptInput);
    Result.ParamByName('m3').DataType:= ftString;
    Result.ParamByName('m3').Table:= True;
    Result.ParamByName('m3').Length:= ASize;
    Result.ParamByName('m3').Size:= 10;

    Result.Params.CreateParam(ftTable, 'm4',  ptInput);
    Result.ParamByName('m4').DataType:= ftString;
    Result.ParamByName('m4').Table:= True;
    Result.ParamByName('m4').Length:= ASize;
    Result.ParamByName('m4').Size:= 10;

    Result.Params.CreateParam(ftTable, 'm5',  ptInput);
    Result.ParamByName('m5').DataType:= ftString;
    Result.ParamByName('m5').Table:= True;
    Result.ParamByName('m5').Length:= ASize;
    Result.ParamByName('m5').Size:= 10;

    Result.Params.CreateParam(ftTable, 'm6',  ptInput);
    Result.ParamByName('m6').Length:= ASize;
    Result.ParamByName('m6').DataType:= ftInteger;
    Result.ParamByName('m6').Table:= True;

    Result.Params.CreateParam(ftTable, 'm7',  ptInput);
    Result.ParamByName('m7').Length:= ASize;
    Result.ParamByName('m7').DataType:= ftInteger;
    Result.ParamByName('m7').Table:= True;

    Result.Params.CreateParam(ftTable, 'm8',  ptInput);
    Result.ParamByName('m8').Length:= ASize;
    Result.ParamByName('m8').DataType:= ftInteger;
    Result.ParamByName('m8').Table:= True;

    Result.Params.CreateParam(ftInteger, 'v_cnt',  ptInput);

  except
    on E : Exception do begin
      Result:= nil;
      WRITE_LOGER.WriteLog('(!ОШИБКА) Процедура создания SP_ODAC_ADD: ' + E.Message);
    end;
  end;


мы вставили этот код в пустое консольное приложение - он выполнился без ошибок.
не могли бы вы привести полный пример: начиная с создания потоков и заканчивая их выполнением, который будет воспроизводить проблему с описаной вами ошибкой.
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39797956
Foxpc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: pascal
1.
2.
3.
4.
5.
6.
7.
    Result.Params.CreateParam(ftTable, 'm8',  ptInput);
    with Result.ParamByName('m8') do 
    begin
       Length:= ASize;
       DataType:= ftInteger;
       Table:= True;
    end;
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39798008
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Foxpc, в чем разница?
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39798010
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrbwhite_nigger, а в чем праздник?C ODAC не работал, но я бы сделал что-то вроде (на коленке)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
procedure CreateParameter(AStoredProc: TOraStoredProc; const AParamName: string; ADataType: TFieldType; ALength: Integer; ASize: Integer = 0);
begin
  with AStoredProc.Params.CreateParam(ftTable, AParamName,  ptInput) do
  begin
     Length:= ALength;
     DataType:= ADataType;
     Table:= True;
     if ASize <> 0 then
       Size := ASize;
  end;
end;

function SP_ODAC_ADD(ASize: integer): TOraStoredProc;
begin
  try
    Result:= TOraStoredProc.Create(nil);
    Result.Params.Clear;
    Result.StoredProcName:= 'pkg.ins_buf';
    
    CreateParameter(Result, 'm1', ftDateTime, ASize);
    CreateParameter(Result, 'm2', ftDateTime, ASize);
    CreateParameter(Result, 'm3', ftString, ASize, 10);
    CreateParameter(Result, 'm4', ftString, ASize, 10);
...
  except
    on E : Exception do begin
      Result:= nil;
      WRITE_LOGER.WriteLog('(!ОШИБКА) Процедура создания SP_ODAC_ADD: ' + E.Message);
    end;
  end;


Не люблю портянки. Число параметров - по вкусу...
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39798015
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_nigger, ааа
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39798022
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
devart, да, на пустом проекте без ошибок. буду копать глубже
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39798241
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
devart, мой код выполняется с ошибками ЕСЛИ поменять очередность установки параметров

рабочий код
Код: pascal
1.
2.
3.
Result.ParamByName('m5').DataType:= ftString;
  Result.ParamByName('m5').Table:= True;
  Result.ParamByName('m5').Length:= ASize;



не рабочий код

Код: pascal
1.
2.
3.
Result.ParamByName('m6').Length:= ASize;
 Result.ParamByName('m6').DataType:= ftInteger;
 Result.ParamByName('m6').Table:= True;



Видимо при выделении памяти нужно заранее знать тип данных

P.S. Использую демку, исходников нет, строю догадки
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39799182
Фотография devart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cptngrbне рабочий код

Код: pascal
1.
2.
3.
  Result.ParamByName('m6').Length:= ASize;
  Result.ParamByName('m6').DataType:= ftInteger;
  Result.ParamByName('m6').Table:= True;


Видимо при выделении памяти нужно заранее знать тип данных


вот пример имеенно с таким порядком заполнения атрибутов параметра - ошибок нет:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, DB, Ora;

function SP_ODAC_ADD(ASize: integer): TOraStoredProc;
begin
  Result:= TOraStoredProc.Create(nil);
  Result.Params.Clear;
  Result.StoredProcName:= 'pkg.ins_buf';

  Result.Params.CreateParam(ftTable, 'm1',  ptInput);
  Result.ParamByName('m1').DataType:= ftDateTime;
  Result.ParamByName('m1').Table:= True;
  Result.ParamByName('m1').Length:= ASize;

  Result.Params.CreateParam(ftTable, 'm2',  ptInput);
  Result.ParamByName('m2').DataType:= ftDateTime;
  Result.ParamByName('m2').Table:= True;
  Result.ParamByName('m2').Length:= ASize;

  Result.Params.CreateParam(ftTable, 'm3',  ptInput);
  Result.ParamByName('m3').DataType:= ftString;
  Result.ParamByName('m3').Table:= True;
  Result.ParamByName('m3').Length:= ASize;
  Result.ParamByName('m3').Size:= 10;

  Result.Params.CreateParam(ftTable, 'm4',  ptInput);
  Result.ParamByName('m4').DataType:= ftString;
  Result.ParamByName('m4').Table:= True;
  Result.ParamByName('m4').Length:= ASize;
  Result.ParamByName('m4').Size:= 10;

  Result.Params.CreateParam(ftTable, 'm5',  ptInput);
  Result.ParamByName('m5').DataType:= ftString;
  Result.ParamByName('m5').Table:= True;
  Result.ParamByName('m5').Length:= ASize;
  Result.ParamByName('m5').Size:= 10;

  Result.Params.CreateParam(ftTable, 'm6',  ptInput);
  Result.ParamByName('m6').Length:= ASize;
  Result.ParamByName('m6').DataType:= ftInteger;
  Result.ParamByName('m6').Table:= True;

  Result.Params.CreateParam(ftTable, 'm7',  ptInput);
  Result.ParamByName('m7').Length:= ASize;
  Result.ParamByName('m7').DataType:= ftInteger;
  Result.ParamByName('m7').Table:= True;

  Result.Params.CreateParam(ftTable, 'm8',  ptInput);
  Result.ParamByName('m8').Length:= ASize;
  Result.ParamByName('m8').DataType:= ftInteger;
  Result.ParamByName('m8').Table:= True;

  Result.Params.CreateParam(ftInteger, 'v_cnt',  ptInput);
end;

var
  sp: TOraStoredProc;
begin
  try
    sp := SP_ODAC_ADD(10);
    sp.Free;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.


мы уже писали: если вы хотите, чтобы вам помогли, то приведите весь код, который приводит к возникновению ошибок.
...
Рейтинг: 0 / 0
ODAC. Передать массив в качестве параметра ХП
    #39799187
cptngrb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
12000 строк кода приводить не удобно. при изменении порядка параметров ошибка ушла. Спасибо за внимание
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / ODAC. Передать массив в качестве параметра ХП
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]