2017-02-14 1 views
4

Ich frage mich, ob möglich ist, mehr als eine Zeile in einer SELECT Abfrage in Firebird 1.5, wie Sie unten zurück:Ist es möglich, mehrere Zeilen in einer Firebird gespeicherten Prozedur zurückzugeben?

| FIELD1 | FIELD 2 | 
-------------------- 
| 1.00 | 1  | 
| 2.00 | 2  | 
| 3.00 | 3  | 

SET TERM /; 

CREATE OR ALTER PROCEDURE TEST 
RETURNS (VARIABLE1 DOUBLE PRECISION, VARIABLE2 INTEGER) 
AS 
BEGIN 
    SELECT FIELD1, FIELD2 FROM TABLE INTO :VARIABLE1, :VARIABLE2; 
END/ 

EXECUTE PROCEDURE TEST/ 

SET TERM ;/ 

Unter der Annahme, die Abfrage mehr als ein Ergebnis/Zeile zurückgibt, wird der folgende Fehler ausgelöst:

Statement ist fehlgeschlagen, SQLCODE = -811

Mehrere Zeilen in Singleton wählen

Offensichtlich erlaubt die Firebird-Engine mir nicht, mehr als einen Wert in einer Variablen zurückzugeben. Ich entwickle eine Python-Software, wo ich als Tupel zum Beispiel so etwas [(1.00, 1), (2.00, 2), (3.00, 3)] bekommen möchte, basierend auf der Prozedur TEST. Ich verwende das Modul kinterbasdb, um eine Verbindung mit der GDB herzustellen.

Gibt es eine Möglichkeit, das zu tun?

+0

Bitte überprüfen http://stackoverflow.com/questions/34900648/how-to-execute-procedure-returning-resultset-in-firebird – Tajinder

+0

Aus Neugier : warum benutzt du immer noch kinterbasdb? Es wurde durch Treiber wie [FDB] (https://pypi.python.org/pypi/fdb/) und [firebirdsql] (https://pypi.python.org/pypi/firebirdsql) ersetzt. –

Antwort

3

Was Sie brauchen, heißt "Selectable Stored Procedure". Grundsätzlich müssen Sie Ihren Code so etwas wie dies ändern:

CREATE OR ALTER PROCEDURE TEST 
RETURNS (VARIABLE1 DOUBLE PRECISION, VARIABLE2 INTEGER) 
AS 
BEGIN 
    for SELECT FIELD1, FIELD2 FROM TABLE INTO :VARIABLE1, :VARIABLE2 
    do SUSPEND; 
END 

und rufen Sie die Prozedur mit einem SELECT, wie folgt aus:

SELECT * FROM TEST; 

Viel Glück!

+0

Siehe auch https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-psql-storedprocs.html#fblangref25-psql-storedprocs-types –

4

Firebird hat zwei types of stored procedures:

  • ausführbaren Prozeduren erzeugen höchstens eine Zeile, und werden unter Verwendung ausgeführt:

    execute procedure <procedurename> 
    
  • Wählbare Verfahren können mehrere Zeilen erzeugen und verwenden, ausgeführt:

    select * from <procedurename> 
    

    Oder mit Parametern:

    select * from <procedurename>(param, ...) 
    

ein selektierbaren Verfahren enthält das SUSPEND Schlüsselwort, das die Zeilenausgänge und wartet auf den nächsten Abruf. Das Vorhandensein dieses Schlüsselworts ist das einzige, was zwischen den beiden Typen unterscheidet.

Warnung: Es ist möglich, execute procedure mit einer auswählbaren Prozedur zu verwenden, aber in diesem Fall wird nur eine einzelne Zeile erzeugt, und die Ausführung endet, nachdem die erste Zeile erzeugt wurde: der Rest der gespeicherten Prozedur nach SUSPEND nicht ausgeführt werden! Es war auch möglich, aus einer ausführbaren gespeicherten Prozedur auszuwählen, aber in Firebird 3 ist das nicht mehr möglich.

Der spezifische Grund des Fehlers „Mehrere Zeilen in Singleton wählen“ ist die Zeile:

SELECT FIELD1, FIELD2 FROM TABLE INTO :VARIABLE1, :VARIABLE2; 

Diese select ... into ... Aussage nur eine einzige Zeile (auch bekannt als ein Singleton wählen) erlaubt ist, zu erzeugen.Wenn Sie mehr als eine Zeile erwarten, müssen Sie for select ... into ... do verwenden, damit Sie über die resultierenden Zeilen iterieren können.

dies mit suspend Die Kombination wird dann zur Folge:

CREATE OR ALTER PROCEDURE TEST 
RETURNS (VARIABLE1 DOUBLE PRECISION, VARIABLE2 INTEGER) 
AS 
BEGIN 
    FOR SELECT FIELD1, FIELD2 FROM TABLE INTO :VARIABLE1, :VARIABLE2 
    DO 
    BEGIN 
     SUSPEND; 
    END 
END 

Die BEGIN ... END -Block technisch nicht notwendig ist, aber ich ziehe immer hier einen Block zu verwenden.

Sie können dann ausführen dies mit:

select variable1, variable2 from test; 
Verwandte Themen