Procédure stockée Firebird pour concaténer toutes les valeurs de champs de plusieurs lignes
-
06-07-2019 - |
Question
Mon objectif est d’écrire un proc stocké capable de rassembler toutes les valeurs de champs de plusieurs lignes dans une seule variable de sortie (peut-être varchar (longueur_unle)). Cela peut sembler une solution étrange, mais j’ai la certitude que c’est le seul que je puisse utiliser dans cette situation. Je n’avais jamais utilisé Firebird auparavant, et les procs stockés ont une apparence différente de celle des autres systèmes de base de données bien connus. Mon Firebird est 1.5 et dialecte 3 (pas sûr de ce que cela signifie). Alors peut-être que quelqu'un pourrait m'aider avec un exemple d'algorithme.
La solution
La procédure suivante fait ce que vous décrivez:
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;
Mais je doute de la sagesse de cette solution. Comment savez-vous que VARCHAR est suffisamment long pour toutes les lignes de votre jeu de données souhaité?
Il est beaucoup plus facile et sûr d’exécuter une requête pour renvoyer le résultat à une application, ligne par ligne. Chaque langage de programmation d'application dispose de méthodes pour concaténer des chaînes, mais plus important encore, il dispose de méthodes plus souples pour gérer la croissance des données.
Au fait, "dialecte" dans Firebird et InterBase fait référence à un mode de compatibilité qui a été introduit pour que les applications développées pour InterBase 5.x puissent fonctionner avec les versions ultérieures d’InterBase et de Firebird. C’était il ya près de dix ans et, autant que je sache, il n’est pas nécessaire aujourd’hui d’utiliser un élément inférieur au dialecte 3.
Autres conseils
Lors de la concaténation, vous devez tester les valeurs NULL. Voici un exemple pour deux champs et un séparateur entre eux:
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
Il est très facile de renvoyer plusieurs lignes à l'aide de procédures stockées Firebird.
Ne pas utiliser:
execute procedure proc_name(value);
Utilisez plutôt le:
select * from proc_name(value);