Firebird 1.5 "выполнить если" процедура

В моем приложении я запускаю скрипты для расширения и изменения базы данных при каждом обновлении. Я все еще должен поддерживать Firebird 1.5, так как некоторые пользователи просто не будут обновляться.

Иногда сценарии терпят неудачу, и я должен предоставить обновления, исправляющие ошибки. Поскольку они не всегда случаются, мне нужны такие вещи, как:

  1. отбросить, если существует (для представлений, поскольку в FB 1.5 нет измененных представлений) добавить
  2. столбец, если он не существует (добавить столбцы таблицы)
  3. выполнить sql, если в столбце таблицы не найдено val

Первые два работают хорошо, но последний не работает:

установить срок ^;

create or alter procedure addif(tab_name varchar(31), col_name varchar(31),data_type varchar(100)) as
BEGIN
  if (not exists(select 1 from rdb$relation_fields  where upper(rdb$relation_name) = upper(:tab_name) and upper(rdb$field_name) = upper(:col_name))) then
    execute statement 'alter table '||tab_name||' add '||:col_name||' '||:data_type;
END
^

create or alter procedure dropif(object_name varchar(31)) as
begin
  if (exists(select 1 from rdb$relations where rdb$view_blr is not null and
       (rdb$system_flag is null or rdb$system_flag = 0) and upper(rdb$relation_name) = upper(:object_name))) then
    execute statement 'drop view '||object_name;
end
^

create or alter procedure execif(tab_name varchar(31), col_name varchar(31), val varchar(100), sql varchar(8192)) as
declare s varchar(500);
declare i integer;
begin
  s = 'select 1 from ' || :tab_name || ' where ' || :col_name || ' = ' || :val;
  execute statement s into i;
  if (i=0) then
    execute statement sql;
end
^
set term ; ^

Если я выполню

 execute procedure execif('prs','id','0','insert into ini(aval,akey) values (''555555'',''555555'');');

Ничего не произошло. Отладка процедуры показала, что (если условие выполнено) строка

выполнить заявление sql;

выполняется, но ничего не происходит. Даже если sql содержит недействительный sql, ничего не происходит.

Я уверен, что упускаю что-то важное здесь и был бы признателен, если бы никто не мог помочь!

РЕДАКТИРОВАТЬ: я изменил оператор выгрузки sql для выполнения оператора:sql, а также изменил sql на asql безрезультатно.

1 ответ

Решение

После некоторого тестирования я обнаружил, что по крайней мере Firebird 1.5 не может обрабатывать два оператора "execute Statement" в одной процедуре. Итак, я разделил все это на две процедуры, и это работает!

Первая функция возвращает 1 значения, существующего в столбце таблицы, вторая использует эту функцию и выполняет инструкцию, если первая функция не возвращает 1.

Вот код:

create or alter procedure valexists(tab_name varchar(31), col_name varchar(31), val varchar(100)) returns (result integer)  as
begin
  execute statement ('select 1 from ' || :tab_name || ' where ' || :col_name || ' = ' || :val) into result;
  suspend;
end
^

create or alter procedure execif(tab_name varchar(31), col_name varchar(31), val varchar(100), sql varchar(8192)) as
begin
if (not exists (select 1 from valexists(:tab_name,:col_name,:val) where result=1)) then
    execute statement :sql;
end
^
Другие вопросы по тегам