2016-08-02 26 views
1

In meiner Anwendung verwende ich Skripte, um die Datenbank mit jedem Update zu erweitern und zu ändern. Ich muss Firebird 1.5 noch unterstützen, da einige Benutzer gerade nicht aufwerten würden.Firebird 1.5 "execute if" Prozedur

Manchmal scheitern Skripte und ich muss Updates zur Verfügung stellen, die die Fehler korrigieren. Da sie passieren nicht immer, ich brauche Dinge wie:

  1. Drop if (für Ansichten, wie es in FB 1.5 keine alte Ansicht ist) besteht hinzufügen
  2. Spalt, wenn es (add Tabellenspalten) existieren tut
  3. sQL ausführen, wenn ein val nicht in einer Spalte einer Tabelle

die ersten beiden arbeiten gut, aber die letzte nicht gefunden wird:

Satz Begriff ^;

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 ;^

Wenn ich ausführen

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

nichts passiert. Das Debugging der Prozedur ergab, dass (unter der Bedingung, dass die Bedingung erfüllt ist) die Zeile

Anweisung ausführen sql;

wird ausgeführt, aber nichts passiert. Selbst wenn sql ungültige sql enthält, passiert nichts.

Ich bin mir sicher, dass mir hier etwas Wichtiges fehlt und wäre dankbar, wenn mir jemand helfen könnte!

EDIT: Ich habe excute Anweisung sql geändert, um Anweisung auszuführen: sql und änderte auch sql zu asql ohne Erfolg.

Antwort

1

Nach einigen Tests habe ich herausgefunden, dass Firebird 1.5 mindestens zwei Anweisungen "Anweisung ausführen" nicht in einer Prozedur verarbeiten kann. Also habe ich das Ganze in zwei Prozeduren aufgeteilt und es funktioniert!

Die erste Funktion gibt 1 des Wertes besteht in der Spalte der Tabelle verwendet die zweite dieser Funktion und führt die Anweisung, wenn die erste Funktion nicht 1.

Hier ist der Code zurückgibt:

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 
^