Insertion de collections à partir de requêtes SELECT
Les constructeurs[1] d'objets sont utilisables dans les instructions de type INSERT ... VALUES
, mais ne peuvent être utilisés dans les instructions de type INSERT ... SELECT
. Pour ces dernières une autre méthode de construction est nécessaire.
Syntaxe : Insérer une collection d'objets depuis une table
Soient les tables tro
et t
définies par le schéma RO ci-après.
type col : collection de <string>
tro(a_obj:col)
t(a:string)
L'instruction suivante permet d'insérer le contenu de l'attribut a
pour tous les enregistrements de t
dans un seul attribut a_obj
d'un seul enregistrement de tro
sous la forme d'une collection.
INSERT INTO tro (a_objet)
VALUES (CAST(MULTISET(SELECT a FROM t ) AS col));
L'instruction
CAST (...) AS <type>
permet de renvoyer un type donné à partir d'une expression.L'instruction
MULTISET (...)
permet de renvoyer une collection à partir d'une liste de valeurs.
Méthode : Approche générale
Soit la table tro
définie par le schéma RO ci-après. Elle contient un attribut clé (pk_id
) et un attribut qui est une collection (a_obj
).
type col : collection de <string>
tro(#pk_id:string, a_obj:col)
Soit la table tr
définie par le schéma relationnel ci-après.
tr(a:string, b:string)
a1 | b1 |
a1 | b2 |
a1 | b3 |
a2 | b4 |
a2 | b5 |
Si l'on souhaite insérer le contenu de tr
dans tro
de telle façon que les valeurs de a
correspondent à pk_id
et celles de b
à obj_a
, en insérant une ligne pour chaque valeur ax
et que tous les bx
correspondant soient stockés dans la même collection, il faut exécuter une requête INSERT ... SELECT
qui fait appel aux instructions CAST
et MULTISET
.
INSERT INTO tro (pk_id, a_obj)
SELECT
a,
CAST(
MULTISET(
SELECT b
FROM tr tr1
WHERE tr1.a= tr2.a)
AS col)
FROM tr tr2;
a1 | (b1, b2, b3) |
a2 | (b4, b5) |