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.

SyntaxeInsérer une collection d'objets depuis une table

Soient les tables tro et t définies par le schéma RO ci-après.

1
type col : collection de <string>
2
tro(a_obj:col)
3
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.

1
INSERT INTO tro (a_objet)
2
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éthodeApproche 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).

1
type col : collection de <string>
2
tro(#pk_id:string, a_obj:col)

Soit la table tr définie par le schéma relationnel ci-après.

1
tr(a:string, b:string)
Extrait de tr

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.

1
INSERT INTO tro (pk_id, a_obj)
2
SELECT 
3
  a,
4
  CAST(
5
    MULTISET(
6
      SELECT b 
7
      FROM tr tr1 
8
      WHERE tr1.a= tr2.a) 
9
    AS col)
10
FROM tr tr2;
Extrait de tro après exécution de la requête INSERT

a1

(b1, b2, b3)

a2

(b4, b5)