Firebird stored procedure per concatenare tutti i valori di campo da più righe
-
06-07-2019 - |
Domanda
il mio obiettivo è quello di scrivere un proc memorizzato in grado di raccogliere tutti i valori di campo da più righe in una singola variabile di output (forse varchar (some_length)). Può sembrare una soluzione strana, ma sono abbastanza positivo che sia l'unico che posso usare in quella situazione. Non ho mai usato Firebird prima e i proc memorizzati hanno un aspetto diverso rispetto ad altri noti sistemi db. Il mio Firebird è 1.5 e il dialetto 3 (non sono sicuro di cosa significhi). Quindi forse qualcuno potrebbe aiutarmi con un esempio di algoritmo.
Soluzione
La seguente procedura fa ciò che descrivi:
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;
Ma metto in dubbio la saggezza di questa soluzione. Come fai a sapere che VARCHAR è abbastanza lungo per tutte le righe nel set di dati desiderato?
È molto più semplice e sicuro eseguire una query per restituire il risultato a un'applicazione riga per riga. Ogni linguaggio di programmazione dell'applicazione ha metodi per concatenare le stringhe, ma soprattutto hanno metodi più flessibili per gestire la crescita dei dati.
A proposito, " dialetto " in Firebird e InterBase si riferisce a una modalità di compatibilità introdotta in modo che le applicazioni sviluppate per InterBase 5.x possano funzionare con le versioni successive di InterBase e Firebird. È successo quasi dieci anni fa e oggi AFAIK non è necessario usare qualcosa di inferiore al dialetto 3.
Altri suggerimenti
Devi verificare i valori null durante la concatenazione, ecco un esempio per due campi e un separatore tra loro:
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
Restituire più righe usando le stored procedure di Firebird è molto semplice.
Non utilizzare:
execute procedure proc_name(value);
Utilizza invece:
select * from proc_name(value);