2017-11-15 4 views
0

Ich habe eine gespeicherte Prozedur, die Einfügungen und Aktualisierungen in den Tabellen ausführt. Die Notwendigkeit, es zu erstellen, war zu versuchen, alle Scanfunktionen vor dem Einfügen oder Aktualisieren von Datensätzen zu zentralisieren. Heute ergab sich die Notwendigkeit, den Wert des Feldes ID der Tabelle zurückzugeben, damit meine Anwendung die Registrierung finden und andere gespeicherte Prozeduren ausführen kann.Wie gibt man Werte vom dynamisch generierten Befehl "insert" zurück?

Stored Procedure

SET TERM^; 

CREATE OR ALTER procedure sp_insupd (
    iaction varchar(3), 
    iusuario varchar(20), 
    iip varchar(15), 
    imodulo varchar(30), 
    ifieldsvalues varchar(2000), 
    iwhere varchar(1000), 
    idesclogs varchar(200)) 
returns (
    oid integer) 
as 
declare variable vdesc varchar(10000); 
begin 
    if (iaction = 'ins') then 
    begin 
    vdesc = idesclogs; 

    /*** the error is on the line below ***/ 
    execute statement 'insert into '||:imodulo||' '||:ifieldsvalues||' returning ID into '||:oid||';'; 
    end else 
    if (iaction = 'upd') then 
    begin 
    execute statement 'select '||:idesclogs||' from '||:imodulo||' where '||:iwhere into :vdesc; 

    execute statement 'execute procedure SP_CREATE_AUDIT('''||:imodulo||''');'; 

    execute statement 'update '||:imodulo||' set '||:ifieldsvalues||' where '||:iwhere||';'; 
    end 

    insert into LOGS(USUARIO, IP, MODULO, TIPO, DESCRICAO) values (
    :iusuario, :iip, :imodulo, (case :iaction when 'ins' then 1 when 'upd' then 2 end), :vdesc); 
end^ 

SET TERM ;^

Der Fehler in der obigen Zeile auftritt aufgrund Syntaxfehler. Die Prozedur wird normal kompiliert, dh der Fehler tritt bei der Kompilierung nicht auf, da die betreffende Zeile über die "Anweisung ausführen" ausgeführt wird. Wenn es nicht erforderlich, den Wert des ID Feld zurückzukehren war, arbeitete das Verfahren normalerweise mit der Zeile wie folgt aus:

... 
execute statement 'insert into '||:imodulo||' '||:ifieldsvalues||';'; 
... 

Was der richtige Weg wäre für den Wert des ID Feld in der OID gespeichert werden Variable?

Antwort

2

Was ist REALWERT in ifieldsvalues?

Sie können nicht beide

  • 'insert into '||:imodulo||' '||:ifieldsvalues
  • 'update '||:imodulo||' set '||:ifieldsvalues

haben, weil Methoden Spaltennamen und Spaltenwerte in INSERT und UPDATE Aussagen zu spezifizieren grundsätzlich verschieden ist !!! Du hättest entweder update-stmt oder broken insert-stmt gebrochen!

Der Fehler in der obigen Zeile auftritt aufgrund Syntaxfehler

dies nicht genug ist. Zeige den echten Fehlertext, alles. Es enthält den tatsächlichen Befehl, den Sie generieren, und es scheint, Sie hatten es wirklich falsch erzeugt.


alle Scan-Funktionen vor dem Einsetzen oder Aktualisieren von Datensätzen

verschieben diese Funktionen aus dem SQL Server und in Ihren Anwendungsserver. Dann müssten Sie nicht einfügen/update in diesem "Strings Splicing" Weise, die sehr fragile und "SQL-Injektion" freundlich ist. Du bist hier auf die Straße zur Hölle getreten.

der Fehler nicht passiert in der Zusammenstellung

Genau. Und das ist nur für den Anfang. Sie entfernen alle Sicherheitsüberprüfungen, die Ihnen bei der Anwendungsentwicklung hätten helfen sollen.


Auf modernen Firebird-Versionen EXECUTE STATEMENT Befehl die gleiche INTO Klausel als PSQL SELECT Befehl haben.

https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-psql-coding.html#fblangref25-psql-execstmt

Verwenden http://translate.ruhttp://www.firebirdsql.su/doku.php?id=execute_statement

zu lesen oder einfach nur SQL Beispiele dort sehen. Beachten Sie jedoch, dass diese Beispiele alle den dynamischen Befehl SELECT verwenden, nicht INSERT. Ich bin mir also nicht sicher, ob es so funktionieren würde.

Dies funktioniert in Firebird 2.5 (aber nicht in Firebird 2.1) PSQL-Blöcken.

execute statement 'insert into Z(payload) values(2) returning id' into :i; 

Um es von IBExpert/Flamerobin/iSQL interaktiv Shell ausgeführt, dass offensichtlich vorformulierten hinzufügen:

execute block returns (i integer) as 
begin 
    execute statement 'insert into Z(payload) values(2) returning id' into :i; 
    suspend; 
end 
+0

ich die Änderungen mach deine Antwort nach. Ich werde das Ergebnis bald veröffentlichen. Vielen Dank! –

+0

@CarlosAndrade naja, schätze ich lag falsch. Sie müssen nur exec-stmt-in verwenden. exec-block ist schwieriger mit string variable/expression als stmt-Quelle zu kombinieren. Um die Rückgabewerte von EB zu erhalten, müssten Sie außerdem die FOR EXECUTE BLOCK-Schleife ausführen. Welches ist viel mehr Boilerplate –

+0

Okay, ich versuche all diese Möglichkeiten. –

Verwandte Themen