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
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.
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
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);
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. –
Wenn ich mich erinnere, können Sie einen Prozedurparameter oder Rückgabewert mit einem BLOB- oder ARRAY-Datentyp nicht deklarieren. –
Jeder Nullwert würde diese Lösung durchbrechen. – Nelson