Recherche sur le blog

mardi 11 octobre 2011

[SQL] Séquences sur DB2 400

Pour vous, impossible de créer une clé avec un incrément automatique ? Vous pouvez alors utiliser un objet qu'on appelle couramment "séquence". Celui-ci correspond en fait à une suite d'entiers que l'on peut manipuler et même "configurer" de sorte à ce qu'elle s'incrémente de telle ou telle manière. C'est une très bonne solution pour faire face aux problèmes de concurrence.

Sur l'AS/400, lorsque l'on crée une séquence, on dispose d'un objet de type *DTAARA, auquel on peut également attribuer des droits d'accès.

   
Créer la séquence

La base de données DB2 UDB permet l'exécution de requêtes écrites en langage SQL. Comme sur Oracle, on peut utiliser la syntaxe suivante :
CREATE SEQUENCE ma_sequence
De cette manière, la séquence "ma_sequence" va être créée dans la bibliothèque QGPL. Il est bien sûr possible de changer ça en spécifiant dans quelle bibliothèque on souhaite la créer. La syntaxe est, de ce fait, légèrement différente :
CREATE SEQUENCE ma_lib/ma_sequence
La séquence sera donc créée dans "ma_lib". Dans l'exemple ci-dessous (image), la bibliothèque utilisée est "TSTTRI", une bibliothèque de test. Une même séquence peut donc se retrouver à deux endroits différents, et l'accès à l'une d'entre elles se fera grâce à la "Library List" (pour ceux qui ne connaissent pas, c'est une sorte de "path" dans lequel le système recherche lorsque l'on veut accéder à un programme, un objet, etc).

Des options pour la création 
CREATE SEQUENCE ma_lib/ma_sequence
 START WITH 500
 INCREMENT BY 1
MAXVALUE 1000   
  • L'option "start with" permet d'indiquer quelle est la valeur initiale de la séquence. Elle commencera donc ici à 500.
  • L'option "Increment by" permet d'indiquer de combien la valeur doit être augmentée à chaque appel de "next value".
  • L'option "Maxvalue" permet de fixer une limite qui, si elle est atteinte, réinitialise la valeur de la séquence à sa valeur d'origine (dans notre cas, 500).
  • Le cache peut être désactivé : cela dépendra du contexte d'utilisation. Pour ne pas se servir des valeurs mises en cache, on ajoutera la clause NO CACHE lors de la création.
Accéder à la valeur suivante 
SELECT NEXTVAL FOR ma_sequence FROM SYSIBM/SYSDUMMY1
La table "SYSDUMMY1" est un peu équivalente à la table "DUAL" dans Oracle : elle ne contient qu'une seule ligne. Attention : une restriction est imposée ici : impossible de spécifier le nom de la bibliothèque devant le nom de la séquence, ce qui implique que, lors de l'exécution de cette requête, la séquence doit se trouver dans l'une des bibliothèques de votre "library list". 

Accéder à la valeur courante (session en cours) 
SELECT PREVIOUS VALUE FOR TESTSEQ FROM SYSIBM/SYSDUMMY1
La valeur précédente ne peut être récupérée que si la séquence a déjà été incrémentée durant la session. De plus, il est toujours impossible de spécifier le nom de la bibliothèque dans la requête, ce qui implique que celle-ci soit dans la "library list". C'est dommage mais en soi ce n'est pas tellement contraignant si on utilise peu de librairies (par exemple, une pour la production et une pour le test). 

Récupérer la prochaine valeur pour une insertion 

Supposons que vous voulez utiliser "ma_sequence" pour insérer un numéro de manière automatique dans une table de commandes (MESCOM) où l'on a deux colonnes : NUMCO et NUMCLI. Les deux insertions seront effectuées avec la même requête, le client ayant fait deux commandes. Voici ce qu'il faut alors exécuter :
INSERT INTO MESCOM (NUMCO, NUMCLI)
VALUES (NEXT VALUE FOR TEST.ORDER_SEQ, 12)
La séquence sera initialisée à 500 lors de la première insertion. Sa valeur sera incrémentée lors de la deuxième : on se retrouvera avec deux lignes dans la table, la première ligne sera la commande 500 pour le client 12, quant à la seconde, il s'agira de la commande 501 pour le même client. 

Modifier la séquence 
ALTER SEQUENCE ma_sequence ... 
Supprimer la séquence 

Comme dans toute base de données, il faut utiliser la commande bien connue, "DROP SEQUENCE", de la manière suivante : 
DROP SEQUENCE ma_sequence
Nous voilà rassurés : nous pensions qu'il était impossible d'utiliser des séquences dans cette version de la base de données, mais finalement non, c'est plutôt une bonne nouvelle. En cherchant bien, on finit par trouver. D'ailleurs, la documentation IBM nous renseigne bien à ce niveau !
   

Aucun commentaire: