2016-08-02 5 views
1

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

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

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

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

набор член ^;

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, ничего не происходит.

Уверен, что мне не хватает чего-то важного здесь, и был бы признателен, если бы он помог!

EDIT: я изменил выражение exceute 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 
^ 

 Смежные вопросы

  • Нет связанных вопросов^_^