2008-10-08 12 views
5

Mein Ziel ist es, einen gespeicherten Proc zu schreiben, der alle Feldwerte aus mehreren Zeilen in einer einzigen Ausgabevariablen (vielleicht varchar (some_length)) sammeln kann. Es mag eine merkwürdige Lösung sein, aber ich bin ziemlich positiv, es ist die einzige, die ich in dieser Situation verwenden kann. Ich habe Firebird vorher noch nicht benutzt und gespeicherte Prozeduren sehen anders aus als in anderen bekannten db Systemen. Mein Firebird ist 1,5 und Dialekt 3 (nicht sicher, was es bedeutet). Also vielleicht könnte mir jemand mit einem Algorithmus Beispiel helfen.Firebird gespeicherte Prozedur zum Verketten aller Feldwerte aus mehreren Zeilen

Antwort

5

Das folgende Verfahren tut, was Sie beschreiben:

SET TERM !!; 
CREATE PROCEDURE concat_names 
    RETURNS (concat VARCHAR(2000)) 
AS 
DECLARE VARIABLE name VARCHAR(100); 
BEGIN 
    concat = ''; 
    FOR SELECT first_name || ' ' || last_name FROM employee INTO :name 
    DO BEGIN 
    concat = concat || name || ', '; 
    END 
END!! 
SET TERM ;!! 
EXECUTE PROCEDURE concat_names; 

Aber ich frage die Weisheit dieser Lösung. Woher wissen Sie, dass der VARCHAR für alle Zeilen in Ihrem gewünschten Datensatz lang genug ist?

Es ist viel einfacher und sicherer, eine Abfrage auszuführen, um das Ergebnis Zeile für Zeile an eine Anwendung zurückzugeben. Jede Anwendungsprogrammiersprache hat Methoden zum Verketten von Strings, aber noch wichtiger, sie haben flexiblere Methoden, um das Wachstum von Daten zu verwalten.

Übrigens, "Dialekt" in Firebird und InterBase bezieht sich auf einen Kompatibilitätsmodus, der eingeführt wurde, damit für InterBase 5.x entwickelte Anwendungen mit späteren Versionen von InterBase und Firebird funktionieren können. Das war vor fast zehn Jahren, und AFAIK gibt keine Notwendigkeit, heute ist alles zu verwenden, niedriger als Dialekt 3.

+0

Wenn Sie Firebird 2.1 verwenden, können Sie die Liste Aggregatfunktion verwenden, mit als Ergebnis Text BLOB zur Verfügung stellt. I.e. keine Begrenzung des varchar-Feldes. –

+1

Wenn ich mich erinnere, können Sie einen Prozedurparameter oder Rückgabewert mit einem BLOB- oder ARRAY-Datentyp nicht deklarieren. –

+1

Jeder Nullwert würde diese Lösung durchbrechen. – Nelson

0

Sie haben für NULL-Werte zu testen, wenn verketten, hier ist ein Beispiel für zwei Felder und ein Separator zwischen ihnen:

CREATE PROCEDURE CONCAT(
    F1 VARCHAR(385), 
    F2 VARCHAR(385), 
    SEPARATOR VARCHAR(10)) 
RETURNS (
    RESULT VARCHAR(780)) 
AS 
begin 

    if ((:f1 is not null) and (:f1 <> '')) then 
    result = :f1; 

    if ((:f2 is not null) and (:f2 <> '')) then 
    if ((result is not null) and (result <> '')) then 
     begin 
     if ((:separator is not null) and (separator <> '')) then 
      result = result||separator||f2; 
     else 
      result = result||f2; 
     end 
    else 
     result = f2; 

    suspend; 
end 
0

Das Zurückgeben mehrerer Zeilen mit Firebird gespeicherten Prozeduren ist sehr, sehr einfach.

nicht verwenden:

execute procedure proc_name(value); 

Stattdessen verwenden Sie die:

select * from proc_name(value);