Stored procedures 火鸟1.5“;执行“如果”;程序

Stored procedures 火鸟1.5“;执行“如果”;程序,stored-procedures,execute,firebird1.5,Stored Procedures,Execute,Firebird1.5,在我的应用程序中,每次更新时我都会运行脚本来扩展和更改数据库。我仍然需要支持Firebird 1.5,因为有些用户不愿意升级 有时脚本失败,我必须提供更新来纠正错误。因为它们并不总是发生,我需要这样的事情: 如果存在,则删除(对于视图,因为FB 1.5中没有alter视图)添加 列(如果不存在)(添加表列) 如果在表的列中找不到val,则执行sql 前两个很好,但后一个不行: 设定期限^ create or alter procedure addif(tab_name varchar(31),

在我的应用程序中,每次更新时我都会运行脚本来扩展和更改数据库。我仍然需要支持Firebird 1.5,因为有些用户不愿意升级

有时脚本失败,我必须提供更新来纠正错误。因为它们并不总是发生,我需要这样的事情:

  • 如果存在,则删除(对于视图,因为FB 1.5中没有alter视图)添加
  • 列(如果不存在)(添加表列)
  • 如果在表的列中找不到val,则执行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,也不会发生任何事情

    我确信我错过了一些重要的东西,如果有人能帮忙,我将不胜感激


    编辑:我将exceute语句sql更改为execute语句:sql,并将sql更改为asql,但没有效果。

    经过一些测试,我发现至少firebird 1.5无法在一个过程中处理两个“execute语句”。所以我把整个过程分成了两个步骤,它成功了

    第一个函数返回表列中存在的值的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
    ^