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.

È stato utile?

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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top