SQL norme 92 (SQL-2), contraintes d'intégrité

BoTTom |    Changer de couleur
 
 
 La dernière normalisation de SQL (on parle de SQL-2),
 
  définit entre autre les contraintes d'intégrité de la base de données.
 
 Une containte doit être nommée afin que le gestionnaire renvoi un nom
  de contrainte significatif dans le message lors d'une violation.
 
Cette nomination se fait par: <contrainte> CONSTRAINT nom.
 
 Contraintes de domaine: 
 
               NOT NULL   (variable obligatoire)
 
              create table article (CODART CHAR(6) NOT NULL , ...)
 
               DEFAUT valeur ou mot-réservé
 
              create table article (CODART CHAR(6) NOT NULL,
                                    DATCRT DATE    DEFAUT CURRENT-DATE )
 


|    Changer de couleur
               UNIQUE toute valeur doit être unique.
                      Pour les clés candidates, mais il semble qu'un
                       index fasse aussi bien l'affaire.
 
               CHECK(expression) expression devant être vraie
 
               CHECK(nom de zone op valeur)
                                 !
                                 !-> opérateur logique (<,>,=,...)
 
              create table article (CODART CHAR(6) NOT NULL,
                                    QTESTOCK DEC(11, 2),
                                    CHECK(qtestock >= 0)
                                         CONSTRAINT qtestock_negative)
 
               CHECK(nom-de-zone op nom-de-zone)
 
              create table command (NUMCDE DEC(6, 0) NOT NULL,
                                    QTECDE DEC(11, 2), QTELIV DEC(11, 2),
                                    CHECK(qteliv <= qtecde)
                                         CONSTRAINT qteliv_invalide)
 


|    Changer de couleur
               CHECK(nom-de-zone IN (liste de valeurs))
 
              create table personnel (MATRICUL DEC(6, 0),
                                      SITUATION CHAR(1) /* marié,veuf,...*/,
                                      CHECK(situation in ('M' 'V' 'C' 'D'))
                                       CONSTRAINT situation_invalide)
 
               CHECK(nom-de-zone BETWEEN(val1 AND val2))
 
               la clause CHECK admet des sous-sélections
                                             (approche référentielle)
 
                Soit la table commande contenant un prix à la commande qui
                 ne peut pas être remisé de plus de 20% par rapport au tarif
              create table command (NUMCDE DEC(6, 0) NOT NULL,
                                    ARTCDE CHAR(6) ,  QTECDE DEC(11, 2),
                                    PRICDE DEC(9, 2) NOT NULL,
                                    CHECK(pricde >= 0,8 * (SELECT pritarif
                                                    FROM article
                                                    WHERE codart = artcde))
                                    CONSTRAINT remise_invalide)
 


|    Changer de couleur
               la clause CHECK admet des conditions complexes
                  (reliées par OR ou bien AND)
 
                Soit la table commande contenant un prix à la commande qui
                 DOIT être remisé d'au moins 10% si la quantité est > à 100
 
               create table command .....
                                    CHECK(qteliv < 100 OR
                                          pricde <= 0,9 * (SELECT pritarif
                                                    FROM article
                                                    WHERE codart = artcde))
                                    CONSTRAINT remise_mini
 
 Contraintes d'entité: 
 
               désignation d'une clé primaire (identifiant univoque).
 
               Create table (zone1 PRIMARY KEY , ...)
         ou
               create table (zone1, zone2, zone3, ...
                                   PRIMARY KEY(zone1, zone3) )
 


|    Changer de couleur
            les clés primaires doivent être définies NOT NULL
 
            il était possible d'arriver au même résultat en SQL-89
            (c'est toujours possible) en créant un index UNIQUE avec cette
            clé.
 
            cela offre probablement plus de souplesse.
 
            Les puriste considérent que cette contrainte étant sortie de
             la table, l'intégrité est moins forte.
              (suppression de l'index par exemple)
 
 Contraintes d'intégrité référentielle: 
 
            Il s'agit de concrétiser le lien exitant entre deux tables.
 
               (ce qui était réalisé jusqu'ici par programme)
 
            soit par des déclarations de contraintes (plus performant)
            soit par des procédures associées à une action = trigger
                 (plus souple, plus "gourmand").
 


|    Changer de couleur
            Définitions
 
            clé candidate: attribut ou groupe d'attributs dans une table T1
             susceptible d'identifier un enregistrement.Une clé primaire
             est toujours une clé candidate.
 
            clé étrangère: attribut ou groupe d'attributs dans une table T1
             dont les valeurs doivent exister comme valeurs de la clé
             candidate dans T2. (T1 et T2 peuvent être la même table)
 
            table référencée: table T2 qui contient la clé candidate.
 
            table qui référence: table T1 qui contient la clé étrangère.
 
   Déclaration d'une contrainte d'intégrité référentielle:
 
                 (dans la table qui référence)
                 champs REFERENCES table-référencée(clé candidate)
 
                (clé candidate) est facultatif et inutile lors qu'il s'agit
                 de la clé primaire de la table référencée.
 


|    Changer de couleur
 DU point de vue de la table qui référence:
 
               create table command (NUMCDE DEC(6, 0) NOT NULL,
                                     ARTCDE CHAR(6) REFERENCES article,
                                     NUMCLI DEC(6, 0) REFERENCES clients)
 
               ici le code article doit exister dans la table article
                   le n° de client doit exister dans la table clients.
 
      ou bien  (si la référence porte sur plusieurs colonnes)
 
               FOREIGN KEY(zone1, zone2, ..) REFERENCES table
 
               create table livraison (NUMLIV DEC(6, 0) NOT NULL,
                                       NUMCDE DEC(6, 0) NOT NULL,
                                       NOLIGN DEC(3, 0) NOT NULL,
                                       FOREIGN KEY(numcde, nolign)
                                               REFERENCES lcommand)
 
               ici une livraison doit faire référence à une ligne de
                commande existante.
 


|    Changer de couleur
 DU point de vue de la table référencée:
 
    il s'agit maintenant de définir ce que doit faire le gestionnaire
     en cas de manipulation de la table référencée.
 
    Pour le lien commande<-->client.
 
            que faire si l'on supprime un client
                      si l'on change le code d'un client
                      ... etc ...
 
   tout cela ce déclare sur la table qui référence:  (ici command)
 
                NUMCLI DEC(6, 0) REFERENCES clients  ON évènement action
 
                évènement : une action réalisée sur la table référencée
                                                             (ici clients)
                            ON UPDATE = clé modifiée
 
                            ON DELETE = ligne supprimée
 
 


|    Changer de couleur
                action: que doit faire le SGBD sur la table qui référence
                                                            (ici command)
                        NO ACTION : ne rien faire, l'évènement est interdit.
 
                        CASCADE :  en cas de mise à jour,répercute la mise
                                    à jour sur la table qui référence.
                                   (en cas de modification d'une code client
                                    toutes ses commandes possèdent son
                                     nouveau code)
 
                                   en cas de suppression, suppression des
                                    lignes associées dans la table qui
                                    référence.
                                   (en cas de suppression d'un client,
                                     suppression de toutes ses commandes)
 
                        SET NULL : l'évènement est autorisé et la clé
                                   étrangère de la table qui référence est
                                   mise à NULL (NULL doit être autorisé)
 
                        SET DEFAULT : idem SET NULL avec la valeur/dft
 


|    Changer de couleur
Exemple avec notre table command:
 
                NUMCLI DEC(6, 0) REFERENCES clients
                                 ON UPDATE CASCADE
                                 ON DELETE NO ACTION
 
                répercussion des modifs,suppression non autorisée.
 
remarque NO ACTION équivaut à ne rien préciser (c'est le défaut)
 
         certains SGBD utilisent la clause RESTRICT à la place.
 
 Une contrainte d'intégrité peut être sortie de la notion de table
 (non rattachée à une table) avec la notion d'ASSERTION.
 
 CREATE ASSERTION nom-assertion
        CHECK(NOT EXIST (SELECT * from command
                         WHERE pricde >= 0,8 * (SELECT pritarif
                                                FROM article
                                                WHERE codart = artcde))
 
 Ce que nous avions déja définit, à la création de la table.


|    Changer de couleur
 
Et enfin toute contrainte d'intégrité est par défaut immédiate
 (c'est à dire vérifiée à chaque instruction SQL)
 
Elle peut être différée c'est à dire reportée à la fin de la transaction
 (ordre COMMIT)
 
Prenons l'exmple suivant:
 
1/ Un client ne peut exister que s'il possède au moins une commande.
 
2/ Une commande ne peut être enregistrée que pour un client connu.
 
   Ces deux règles peuvent être dans certains cas (nouveau client)
    contradictoires et peuvent empecher la création d'une commande
    pour un nouveau client.
 
   En déclarant ces deux contraintes différées, il suffit de demander
    l'ajout du client et de sa première commande dans la même transaction.
 
   En fin de transaction (COMMIT), les deux règles s'avéreront vraies.
 


|    Changer de couleur
 
Syntaxe: chaque contrainte peut être complétée par
 
         (NOT) DEFERRABLE
      -- INITIALLY DEFERRED / IMMEDIATE
      !
      !  une contrainte pouvant être déclarée différable
      !   lors de sa création (non différable par défaut).
      !
      -> il s'agit de la valeur initiale qui peut être modifiée en début
          de transaction pendant l'application par:
 
         SET CONSTRAINTS (<-liste de contraintes-> / ALL)
             DEFERRED / IMMEDIATE
 
 
 
 
 Mise en oeuvre de tout cela sur AS/400 via DB2/400 :
 
 
 


|    Changer de couleur
 
 Définition d'une clé primaire
 
              ADDPFCST    FILE(client)
                          TYPE(*PRIKEY)
                          CST(num_client)  <- nom de la contrainte
                          KEY(nocli)
 
 Intégrité référentielle
 
              ADDPFCST    FILE(command)
                          TYPE(*REFCST)
                          CST(clicommand)
                          KEY(numcli)      <- zone du fichier commande
                          PRNFILE(client)  <- fichier parent
                          PRNKEY(nocli)    <- clé candidate/fichier client
                          UPDRULE(*NOACTION)
                          DLTRULE(*CASCADE)
 
UPDRULE :  *NOACTION , *RESTRICT (= *NOACTION mais avant l'appel du trigger)
DLTRULE : les mêmes +  *CASCADE  , *SETNULL , *SETDFT
 


|    Changer de couleur
 
 Ces contraintes peuvents être définies via SQL :
 
   CREATE TABLE modifié (conforme à la norme, sur ce point)
 
   ou par ALTER TABLE (uniquement pour ajouter une contrainte)
 
 Une contrainte peut être momentanement "suspendue"
  ou peut s'avérer fausse (restauration par exemple)
 
 Il y a 4 états possibles:  - Etablie/active       <-- OK
 
                            - Etablie/desactivée   <-- suspendue
 
                            - Définie/activée      <-- pas de membre
 
                            - Définie/désactivée   <-- en erreur
 
 Deux commandes permettent de gérer l'état  : WRKPFCST
                                            et EDTPFCST appellé directement
                                                        à l'IPL en cas de
                                                        problème.


|    Changer de couleur
 
  Si une contrainte est fausse
 
  Pour une contrainte d'unicité :
 
       elle est réalisable immédiatement ou il y a echec.
 
  Pour une contrainte d'intégrité :
 
     - soit suite à une restauration
 
     - soit suite à une désactivation , puis modifs dans le fichier
 
  Elle est notées "Check Pending"
 
 
 
 
               Il faut utiliser la commande WRKPFCTS
 
 
 


|    Changer de couleur
 
   WRKPFCST
 
 ########################################################################## 
 #           Gestion des contraintes de fichier physique                  # 
 #                                                                        # 
 # 2=Modifier   4=Enlever  6=Afficher enreg en instance de vérif.         # 
 #                                                                        # 
 # Opt  Contrainte   Fichier   Biblio    Type    Etat    verif/instance   # 
 #      ARTICK1      ARTICP1   MABIB     *PRIKEY                          # 
 #      ARTICC1      ARTICP1   MABIB     *REFCST ETA/DES    Oui           # 
 #      ARTICC2      ARTICP1   MABIB     *REFCST ETA/ACT    Non           # 
 #       ....                                                             # 
 # ==>                                                                    # 
 #                                                                        # 
 ########################################################################## 
 
 2=CHGPFCST, 4=RMVPFCST
 
 "Verif : Oui" signifie que le système à détecté au moins un incohérence
  (visualisable par l'option 6)
 





©AF400