Правильная передача перечисления для Firebird

 
0
 
Delphi, Kylix and Pascal
ava
Matrex | 07.10.2016, 10:34
Доброго дня коллеги!

Есть функция для удаления строк из БД Firebird 2.5 по идентификатору:


function DEL(const ID: string; IBT: TIBTransaction): Integer;
begin
  fIBS_D := TIBSQL.Create(nil);
  fIBS_D.Transaction := IBT;
  fIBS_D.Database := IBT.DefaultDatabase;
  fIBS_D.SQL.ADD('DELETE FROM SR_USER WHERE id in (:id)');
  fIBS_D.Prepare;
  fIBS_D.ParamByName('id').Value := ID;
  fIBS_D.ExecQuery;
  result := 0;
end;


Если удалять по одной записи:
DEL('10'; fIBT) – все работает

Если удалять серию записей через перечисление:
DEL('10,11,12,13'; fIBT)– функция не работает – просто записи не удаляются.

Я так понимаю необходимо правильно передавать перечисление в качестве параметра – вопрос как это сделать?

Ответы (7)
ava
Matrex | 07.10.2016, 11:52 #
Похоже что никак. См
http://www.ibase.ru/ibfaq/#inparam
ava
Alexeis | 07.10.2016, 12:17 #
Не встречался с такой задачей. Обычно групповое удаление идет каскадно. Т.е. удаление группы записей объединенных общим ключом. Удаляешь мастер запись и каскадно труртся все зависимости. Если стоит вопрос производительности, то можно попробовать написать хранимую процедуру.
ava
Matrex | 07.10.2016, 15:44 #
Дело не в каскадном удалении. Задача стоит следующая: пользователь в гриде выделяет несколько записей и удаляет их одновременно...
ava
mixxxa | 08.10.2016, 16:13 #
А так пробовали?

function DEL(const ID: string; IBT: TIBTransaction): Integer;
begin
  fIBS_D := TIBSQL.Create(nil);
  fIBS_D.Transaction := IBT;
  fIBS_D.Database := IBT.DefaultDatabase;
  fIBS_D.SQL.ADD('DELETE FROM SR_USER WHERE id in ('+ID+')');
  fIBS_D.Prepare;
  fIBS_D.ExecQuery;
  result := 0;
end;
ava
G.Alexander | 25.10.2016, 08:42 #
Спасибо за совет. Пока сделал именно так. Но по словам нашего админа это не "тру вэй" т.к. подобная конструкция для некоторых БД, например Oracle (проект разрабатывается для нескольких БД, по этой же причине использование встроенных процедур сведено к минимуму) заставляет механизм построения плана выполнения запроса сервера БД постоянно парсить данный запрос...
ava
Akella | 10.10.2016, 08:51 #
Передавать нужно в скобках + закавычить, т.к. это же текстовый параметр.
И сделайте лучше без параметра, сразу сгенерируйте запрос.
ava
Akella | 10.10.2016, 09:04 #
Ещё можно создать процедуру UNLIST


SET TERM ^ ;

create or alter procedure UNLIST (
    STRING varchar(2048),
    SEPARATOR varchar(1))
returns (
    ROW varchar(20))
as
begin
  Separator = coalesce(Separator, ';');
  if (Separator = '') then Separator = ';';
  Row = '';

  while (String != '') do
  begin
    if (substring(String from 1 for 1) != Separator) then
      Row = Row || substring(String from 1 for 1);
    else
    begin
      if (Row != '') then suspend;
      Row = '';
    end
    String = substring(String from 2);

  end
  if (Row != '') then suspend;
end^

SET TERM ; ^


использовать потом так:


SELECT P.TEL, P.ID FROM PHONES P
INNER JOIN UNLIST(:ID, ',') UL ON P.ID = UL.ROW


в ID передаём текст в виде чисел через запятую
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить