Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / ODAC. Передать массив в качестве параметра ХП / 20 сообщений из 20, страница 1 из 1
05.04.2019, 12:51
    #39797209
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
Подскажите, как правильно передать массив?

На стороне БД

Код: 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
05.04.2019, 14:22
    #39797296
devart
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
Попробуйте присовить значения в цикле:
Код: pascal
1.
2.
  for i := 0 to SizeArr-1 do
    oProc.Params[0][i].AsDateTime := mDate[i];
...
Рейтинг: 0 / 0
05.04.2019, 15:39
    #39797355
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
devart, так получается. спасибо.
...
Рейтинг: 0 / 0
05.04.2019, 16:40
    #39797438
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
Я создаю объекты ToraStoredProc и задаю параметры вручную, потому что на момент создания у меня нет сессии и поэтому использовать Prepare не могу.
Когда в главном потоке создаю объекты ToraStoredProc, то все отрабатывает хорошо, но как только я пытаюсь создать в потоках, то у меня выскакивает ошибка:
data type is not allowed for a dml array

Почему так происходит. Какая из операций не потокобезопасна?
...
Рейтинг: 0 / 0
05.04.2019, 16:49
    #39797445
devart
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
приведите, пожалуйста, пример кода: как и что вы создаете в потоках
...
Рейтинг: 0 / 0
05.04.2019, 16:56
    #39797448
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
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.
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
05.04.2019, 18:17
    #39797496
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
я вот прямо на днях столкнулся с ситуацией,
когда передать в процедуру массив через ODAC оказалось в два-три раза медленее,
чем вызвать процедуру (которая не использует массив) для каждого значения массива
...
Рейтинг: 0 / 0
05.04.2019, 22:10
    #39797549
white_nigger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
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
06.04.2019, 00:30
    #39797560
Gator
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
defecator, white_nigger et al

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

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

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

Prepare делать не могу, так как сессию получаю непосредственно перед выполнением запроса, а по другому как параметры установить?
...
Рейтинг: 0 / 0
08.04.2019, 09:50
    #39797951
devart
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
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
08.04.2019, 09:55
    #39797956
Foxpc
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
Код: 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
08.04.2019, 11:42
    #39798008
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
Foxpc, в чем разница?
...
Рейтинг: 0 / 0
08.04.2019, 11:47
    #39798010
white_nigger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
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
08.04.2019, 12:10
    #39798015
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
white_nigger, ааа
...
Рейтинг: 0 / 0
08.04.2019, 12:36
    #39798022
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
devart, да, на пустом проекте без ошибок. буду копать глубже
...
Рейтинг: 0 / 0
08.04.2019, 16:09
    #39798241
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
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
10.04.2019, 10:05
    #39799182
devart
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
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
10.04.2019, 10:12
    #39799187
cptngrb
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ODAC. Передать массив в качестве параметра ХП
12000 строк кода приводить не удобно. при изменении порядка параметров ошибка ушла. Спасибо за внимание
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / ODAC. Передать массив в качестве параметра ХП / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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