powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / FireDac array insert
25 сообщений из 31, страница 1 из 2
FireDac array insert
    #39747961
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день.

Исходные данные:
- Postgres
- Delphi Berlin

В Postgres написана тестовая функция (возвращающая void) вида:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE OR REPLACE FUNCTION "public"."testproc"("par" numeric)
  RETURNS "pg_catalog"."void" AS $BODY$
BEGIN
  insert into test_table (id) values (par);
END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100




Необходимо из Delphi, вызвать функцию testproc в анонимном блоке с множественной вставкой.
В компоненте TFDQuery записан вызов функции в анонимном блоке:
Код: plsql
1.
2.
3.
DO $$ BEGIN
  perform testproc(:par);
end $$;



Сам вызов вставки 10 записей:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
procedure TForm1.Button5Click(Sender: TObject);
Var
  I: Integer;
begin
  TRY
    If Not FDConnection1.InTransaction Then
      FDConnection1.StartTransaction;
    FDQuery2.Params.ArraySize := 10;
    For I := 0 To 10 - 1 Do
      FDQuery2.Params[0].AsIntegers[I] := I;
    FDQuery2.Execute(10, 0);
    If FDConnection1.InTransaction Then
      FDConnection1.Commit;
    ShowMessage(IntToStr(FDQuery2.RowsAffected));
  EXCEPT
    On E: Exception Do
    Begin
      ShowMessage(E.Message);
    End;
  END;
end;



Компонент TFDQuery не определяет мой параметр :par по не известным мне причинам.

Как быть??? Как мне вызвать множественную вставку в анонимном блоке на сервере???

Вариант с явным запросом для вставки типа Insert into не предлагать, т.к. в самой функции "testproc" есть своя бизнес логика.

Всех с наступающим Новым Годом!!!!!!1
...
Рейтинг: 0 / 0
FireDac array insert
    #39747964
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimka07,

Что означает "не определяет" ? В чем выражается?
...
Рейтинг: 0 / 0
FireDac array insert
    #39747969
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В редакторе компонента TFDQuery на вкладке Parameters параметр :par просто не определен, его там просто нет
...
Рейтинг: 0 / 0
FireDac array insert
    #39747971
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimka07,

А тебе оно надо? в редакторе? В коде, перед присвоением значений Params.Count чему равно?
...
Рейтинг: 0 / 0
FireDac array insert
    #39747974
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Равно 0
...
Рейтинг: 0 / 0
FireDac array insert
    #39747978
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimka07,

А если на инсерт с тем же параметром перепмсать, то не нулю? Ну дела, тут без Арефьева не разобраться.
Но ты бы не маскировал суть проблемы использованием пакетной вставки, проверь/добейся
воспроизведения на одном одиночном инсерте вообще без циклов и массивов.
...
Рейтинг: 0 / 0
FireDac array insert
    #39747979
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Также могу создавать этот параметр динамически
Код: 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.
procedure TForm1.Button5Click(Sender: TObject);
Var
  I: Integer;
begin
  TRY
    If Not FDConnection1.InTransaction Then
      FDConnection1.StartTransaction;
    ShowMessage(fdquery2.Params.Count.ToString);
    With FDQuery2.Params Do
    Begin
      Clear;
      With Add Do
      Begin
        Name := 'par';
        ParamType := ptInput;
        DataType := ftInteger;
      End;
    End;
    ShowMessage(fdquery2.Params.Count.ToString);
    FDQuery2.Params.ArraySize := 10;
    For I := 0 To 10 - 1 Do
      FDQuery2.Params[0].AsIntegers[I] := I;
    FDQuery2.Execute(10, 0);
    If FDConnection1.InTransaction Then
      FDConnection1.Commit;
    ShowMessage(IntToStr(FDQuery2.RowsAffected));
  EXCEPT
    On E: Exception Do
    Begin
      ShowMessage(E.Message);
    End;
  END;
end;



В этом случае количество параметров равно 1, но при выполнении запроса появляется ошибка:
Ошибка синтаксиса (примерное положение: ":")
...
Рейтинг: 0 / 0
FireDac array insert
    #39747992
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimka07,

Ты можешь "раздеть" пример, оставив ровно одну вставку с одним параметром без циклов и массивов?
И как он будет выполняться, если присвоение значения параметру закомментировать?
...
Рейтинг: 0 / 0
FireDac array insert
    #39748002
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
с простым запросом на вставку работает
Код: plsql
1.
2.
3.
DO $$ BEGIN
  perform testproc(1001);
end $$;
...
Рейтинг: 0 / 0
FireDac array insert
    #39748047
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
https://www.postgresql.org/docs/9/sql-do.html:
авторThe code block is treated as though it were the body of a function with no parameters , returning void. It is parsed and executed a single time.
...
Рейтинг: 0 / 0
FireDac array insert
    #39748064
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry Arefiev,

Дмитрий, когда мы использовали Oracle, то с помощью FireDac, мы спокойно использовали анонимные блоки и выполняли вставку в массиве.
Может быть Вы подскажете в этом случае обходной путь для Postgres с использованием firedac???
...
Рейтинг: 0 / 0
FireDac array insert
    #39748068
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dmitry Arefiev,

Дмитрий, когда мы использовали Oracle, то с помощью FireDac, мы спокойно использовали анонимные блоки и выполняли вставку в массиве.
Может быть Вы подскажете в этом случае обходной путь для Postgres с использованием firedac???
...
Рейтинг: 0 / 0
FireDac array insert
    #39748080
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А зачем там вообще анонимный блок, который содержит единственный вызов функции ? Либо вызывать эту функцию, либо напрямую вызывать INSERT. Последнее лучше, с точки зрения производительности.
...
Рейтинг: 0 / 0
FireDac array insert
    #39748175
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На клиенте кэшируются в словарь значения для вставки в БД, в порядке от 100 до 5000 записей.

По требованию клиента - событию, эти данные должны вставиться в БД Postgres. Из Вашего примера со студией Array DML, операция Insert работает очень производительно. Но в моей случае мне нужно вызвать функцию в БД для вставки. В теле функции перед самой вставкой есть определенная бизнес-логика, так что напрямую вызвать Insert я не могу.

Вот у меня и возник вопрос, как вызвать функцию из Базы для вставки. Через FDStoredProc параметр определяется:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
FDStoredProc2.Params.ArraySize := 10000;
    For I := 0 To 10000 - 1 Do
      FDStoredProc2.ParamByName('par').AsSmallInts[I] := I;
    FDStoredProc2.Execute(10000, 0);
    If FDConnection1.InTransaction Then
      FDConnection1.Commit;
    ShowMessage(IntToStr(FDStoredProc2.RowsAffected));



Но в данном случае, получается не производительно, т.к. 10000 раз будет вызвана функция.

Через FDQuery параметр :par вообще не определяется:

Код: plsql
1.
2.
3.
DO $$ BEGIN
  perform testproc(:par);
end $$;
...
Рейтинг: 0 / 0
FireDac array insert
    #39748183
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimka07,

Ты не ответил (возможно я пропустил) на самое главное, - если с тем же текстом запроса
пытаться послать одну параметризированную запись без использования институтов Array DML,
ошибка проявляется или нет? Если да, то, имхо, это надо однозначно оформлять как багу.
...
Рейтинг: 0 / 0
FireDac array insert
    #39748185
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С точки зрения Oracle я вызывал функцию из пакета в анонимном блоке, через FDQuery:
Код: plsql
1.
2.
3.
BEGIN
  PCKG_TEST.test_proc(:par);
END;



и сам код на Delphi:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
procedure TForm1.Button5Click(Sender: TObject);
Var
  I: Integer;
begin
  TRY
    FDQuery1.Params.ArraySize := 10000;
    For I := 0 To 10000 - 1 Do
    Begin
      FDQuery1.ParamByName('par').AsIntegers[I] := I;
    End;
    FDQuery1.Execute(10000, 0);
    ShowMessage('Yes');
    If FDConnection1.InTransaction Then
      FDConnection1.Commit;
  EXCEPT
    On E: Exception Do
    Begin
      If FDConnection1.InTransaction Then
        FDConnection1.Rollback;
      ShowMessage(E.Message);
    End;
  END;
end;




и все эти команды единым пакетом вызывались на сервере, что дает производительность. 10 000 записей вставилось за 2 секунды, с удаленного компьютера.

А с точки зрения PG у меня такое не получается
...
Рейтинг: 0 / 0
FireDac array insert
    #39748186
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vlad F,
проявляется
...
Рейтинг: 0 / 0
FireDac array insert
    #39748193
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimka07Vlad F,
проявляется
Оформляйте однозначно, голосую.))
...
Рейтинг: 0 / 0
FireDac array insert
    #39748195
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но только безо всякого упоминания FireDAC Array DML.
...
Рейтинг: 0 / 0
FireDac array insert
    #39748198
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не надо мешать анонимные блоки и прочь из разных БД. Что в одной радость, то в другой может быть боль. PL/SQL блоки сильно другое по природе в отличии от PgSQL блоков. Кроме общего слова - мало общего.
...
Рейтинг: 0 / 0
FireDac array insert
    #39748201
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий,
насколько я понимаю решения в данном вопросе нет, кроме как прямой вставкой через insert????
...
Рейтинг: 0 / 0
FireDac array insert
    #39748205
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отец-основатель в пятницу вечером, однозначно, стоит того чтобы к нему прислушаться.))
...
Рейтинг: 0 / 0
FireDac array insert
    #39748207
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прямой INSERT - лучшая производительность.
Функция - делай что хочешь внутри. Но это будет элемент за элементом.
Временная таблица - Array DML в таблицу, потом функция это перелопачивает.
ХЗ ... может FireDAC заведется от массива и засунет его в функцию ...
...
Рейтинг: 0 / 0
FireDac array insert
    #39748210
dimka07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vlad F,
Если же это действительно бага, то ее решения (исправления бага) ждать долго, следующей версии RAD :)

А нам надо сдавать проект до Нового года, вот поэтому и спрашиваю у основателя и других форумчан обходное решение данной проблемы.

P.S.

С Oracle на PG считай весь функционал решения считай перевели, кроме этого момента, к большому сожалению, и если не успеем, то по шапке в качестве подарка к НГ очень сильно влетит.
...
Рейтинг: 0 / 0
FireDac array insert
    #39748217
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimka07, хех ... бага ... Ну надейся дальше.
...
Рейтинг: 0 / 0
25 сообщений из 31, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / FireDac array insert
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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