Bases de Données / Databases

Site Web de l'équipe BD du LIP6 / LIP6 DB Web Site

Outils pour utilisateurs

Outils du site


site:enseignement:licence:3i009:tme_triggers

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
site:enseignement:licence:3i009:tme_triggers [21/10/2015 18:36]
amann [TME TRIGGERS]
site:enseignement:licence:3i009:tme_triggers [11/12/2018 09:29] (Version actuelle)
hubert [Travail à faire]
Ligne 1: Ligne 1:
-====== TME Triggers ======+{{indexmenu_n>​11}} 
 + 
 +====== TME 11-a Triggers ======
 Sous Oracle, le bloc d’instructions d’un trigger est un bloc PL/​SQL. ​ Sous Oracle, le bloc d’instructions d’un trigger est un bloc PL/​SQL. ​
 Dans ce TME nous allons utiliser un sous-ensemble minimal de PL/SQL pour définir et modifier des variables ​ Dans ce TME nous allons utiliser un sous-ensemble minimal de PL/SQL pour définir et modifier des variables ​
Ligne 10: Ligne 12:
 La syntaxe d'un bloc PL/SQL est rappelée ​  ​ci-dessous. La syntaxe d'un bloc PL/SQL est rappelée ​  ​ci-dessous.
  
 +<​code>​
 [ DECLARE [ DECLARE
    -- déclaration de variables ​ ]    -- déclaration de variables ​ ]
Ligne 15: Ligne 18:
    -- instructions PL/​SQL ​    -- instructions PL/​SQL ​
 END; END;
 +</​code>​
  
 où les les crochets '​['​ et '​]'​ délimitent les éléments optionnels. où les les crochets '​['​ et '​]'​ délimitent les éléments optionnels.
Ligne 23: Ligne 27:
 Les variables utilisées dans un bloc PL/SQL doivent être déclarées dans la section DECLARE de ce bloc.  Les variables utilisées dans un bloc PL/SQL doivent être déclarées dans la section DECLARE de ce bloc. 
 Elles peuvent ​ prendre n’importe quel type du langage SQL.  Elles peuvent ​ prendre n’importe quel type du langage SQL. 
-L’attribut %TYPE permet de faire référence au type d’une colonne donnée.+L’attribut ​''​%TYPE'' ​permet de faire référence au type d’une colonne donnée.
  
 **Affectation de variables PL/SQL** **Affectation de variables PL/SQL**
  
-On utilise l’opérateur :​= pour affecter une valeur à une variable, lors de sa déclaration ou dans une instruction de la section BEGIN.On peut donc y introduire tous les éléments du langage PL/SQL, et notamment des variables, déclarées dans une section DECLARE, juste avant la section BEGIN…END.+On utilise l’opérateur ''​:='' ​pour affecter une valeur à une variable, lors de sa déclaration ou dans une instruction de la section BEGIN. On peut donc y introduire tous les éléments du langage PL/SQL, et notamment des variables, déclarées dans une section ​''​DECLARE''​, juste avant la section ​''​BEGIN…END''​. 
 Instructions PL/SQL : Instructions PL/SQL :
 +
 Une expression SQL est une instruction PL/SQL. Par exemple, on peut utiliser l'​ordre UPDATE pour modifier la base de données. On suppose que chaque requête SQL retourne au maximum un nuplet. La valeur de cet nuplet peut être copiée dans des variables déclarées dans la section DECLARE. Par exemple : Une expression SQL est une instruction PL/SQL. Par exemple, on peut utiliser l'​ordre UPDATE pour modifier la base de données. On suppose que chaque requête SQL retourne au maximum un nuplet. La valeur de cet nuplet peut être copiée dans des variables déclarées dans la section DECLARE. Par exemple :
  
-**select** Jour, Heure, Salle  +<code sql> 
- +select Jour, Heure, Salle  
-**into** JourI, HeureI, SalleI +into JourI, HeureI, SalleI 
- +from TD                                  
-**from** TD                                  +where  niveau=:​new.niveau and UE=:new.UE and NoTD=:​new.NoTD;​ 
-  +</​code>​
-**where** niveau=:​new.niveau and UE=:new.UE and NoTD=:​new.NoTD;​+
  
 On peut également appliquer des fonctions de conversion pour modifier les valeurs de variables ;​ Par exemple les fonctions UPPER et LOWER transforment leur arguments (des chaînes de caractères) respectivement en majuscule et  minuscule. ​ On peut également appliquer des fonctions de conversion pour modifier les valeurs de variables ;​ Par exemple les fonctions UPPER et LOWER transforment leur arguments (des chaînes de caractères) respectivement en majuscule et  minuscule. ​
-Il est possible d'​utiliser les structures de contrôle ​suivants : +Il est possible d'​utiliser les structures de contrôle ​suivantes :
  
-  * **if** (<​condition>​) ​**then** <​bloc_psql1> ​ +<code plsql> 
-**else** <​bloc_plsql2>​ ] **end if**+if (<​condition>​) then <​bloc_psql1>​ [ else <​bloc_plsql2>​ ] end if; 
-  * **loop** <​bloc_psql> ​**end loop**+loop <​bloc_psql>​ end loop; 
-  * **for** <var> in <​seq> ​**loop** <​bloc_psql> ​**end loop** ​+for <var> in <seq> loop <​bloc_psql>​ end loop 
-  * **while** <​condition> ​**loop** <​bloc_psql> ​**end loop** ​;+while <​condition>​ loop <​bloc_psql>​ end loop ; 
 +</​code>​
  
 Les commandes exit et exit when <​cond>​ permettent de sortir d'une boucle. Les commandes exit et exit when <​cond>​ permettent de sortir d'une boucle.
Ligne 53: Ligne 58:
 **Exceptions :​** **Exceptions :​**
  
-On ne peut pas annuler une transaction à l'​intérieur d'un trigger mais on put déclencher une exception en utilisant la fonction RAISE_APPLICATION_ERROR (qui peut ensuite être traitée par la procédure qui a déclenchée ​le trigger) :+On ne peut pas annuler une transaction à l'​intérieur d'un trigger mais on peut déclencher une exception en utilisant la fonction RAISE_APPLICATION_ERROR (qui peut ensuite être traitée par la procédure qui a déclenché ​le trigger) : 
 + 
 +<code plsql>
 RAISE_APPLICATION_ERROR(code,'​message'​) ; RAISE_APPLICATION_ERROR(code,'​message'​) ;
 +</​code>​
 +
 +
 +** Limitations : **
 +Un trigger AFTER déchenché après un update (ou un insert) de la table T n'est pas autorisé à modifier la table T (ne pas écrire d'​instruction ''​update T''​ dans le corps du trigger). Pour palier cette limitation, utiliser un trigger BEFORE.
 +
  
  
Ligne 62: Ligne 75:
 On s'​intéresse plus particulièrement au schéma suivant ​ On s'​intéresse plus particulièrement au schéma suivant ​
  
-**TD**(noTD, codeUE, ​ niveau, salle, jour, heure, noEns) +<code sql> 
-**INSCRIPTION**(noEtud, noTD, codeUE) +DROP TABLE TD; 
- +CREATE TABLE TD ( 
-Désarchiver le fichier /​Infos/​bd/​public/tme-triggers.tgz + noTD smallint not null 
-puis exécuter depuis votre fichier tme7_triggers.sql + codeUE ​varchar(10), 
-en tapant @schema_tme7. + niveau ​varchar(10) 
 + salle varchar(10) 
 + jour varchar(8) not null  
 + heure varchar(5) not null 
 + noEns smallint,  
 + PRIMARY KEY ( NoTD, codeUE ​), 
 + UNIQUE (salle,​jour,​heure)) ;  
 +  
 +DROP TABLE INSCRIPTION;​ 
 +CREATE TABLE  ​INSCRIPTION (   
 + noEtud ​smallint 
 +  noTD smallint 
 +  codeUE ​varchar(10), 
 + PRIMARY KEY (noEtud, codeUE)) ; 
 +</code>
  
-La clé primaire ​de relation TD est (noTD, codeUEet celle de  +Exécutez les instructions ​de création de tables ci-dessus dans le client Oracle ​(sqlplus). 
-la ralation INSCRIPTION est (noEtud, codeUE).+({{:​site:​enseignement:​licence:​3i009:​tme_7_schema.sql|}})
  
-Chaque n-uplet de la relation TD renseigne sur un TD d’une UE donnée, ​ +La clé primaire de relation TD est (noTD, codeUE) et celle de la relation INSCRIPTION est (noEtud, codeUE). 
-pour un niveau donné. (ex. le TD 2 de l'UE BD2 du niveau L3). +Chaque n-uplet de la relation TD renseigne sur un TD d’une UE donnée, pour un niveau donné. (ex. le TD 2 de l'UE BD2 du niveau L3). Les TD ont lieu au rythme d’une fois par semaine, pendant toute l’année universitaire.
-Les TD ont lieu au rythme d’une fois par semaine, ​ +
-pendant toute l’année universitaire.+
 Les attributs SALLE, JOUR  et HEURE donnent le lieu, le jour et l’horaire de début du TD. Les attributs SALLE, JOUR  et HEURE donnent le lieu, le jour et l’horaire de début du TD.
 On suppose que tous les TDs de toutes les UEs sont synchronisés au niveau des horaires et de la durée ​ On suppose que tous les TDs de toutes les UEs sont synchronisés au niveau des horaires et de la durée ​
 (il n'y a pas de conflit possible entre deux TDs qui ne commencent pas à la même heure et n'ont pas lieu dans la même salle). ​ (il n'y a pas de conflit possible entre deux TDs qui ne commencent pas à la même heure et n'ont pas lieu dans la même salle). ​
-L’enseignant qui assure le TD est identifié par NOENS. +L’enseignant qui assure le TD est identifié par NOENS. Les étudiants s’inscrivent à chaque UE, séparément,​ et choisissent un seul TD pour cette UE. 
- +
-Les étudiants s’inscrivent à chaque UE, séparément,​ et choisissent un seul TD pour cette UE. +
 L'​étudiant est identifié par NOETUD. L'​étudiant est identifié par NOETUD.
  
Ligne 90: Ligne 112:
 dans la table concernée. dans la table concernée.
  
-1. Créer un trigger qui assure que les valeurs des attributs NIVEAU et CODEUE, entrées dans la table TD, soient en majuscules, quelle que soit la casse utilisée ​ +  - Créer un trigger qui assure que les valeurs des attributs NIVEAU et CODEUE, entrées dans la table TD, soient en majuscules, quelle que soit la casse utilisée lors des instructions d’insertion ou de mise à jour (utilisez la fonction UPPER).  
-lors des instructions d’insertion ou de mise à jour (utilisez la fonction UPPER).  +  ​- ​Créez un trigger qui empêche qu'un étudiant s'​inscrive dans plus que 6 UEs.  
- +  - Créez un trigger qui empêche que le nombre de groupes par UE dépasse 4. 
-2. Créez un trigger qui empêche qu'un étudiant s'​inscrive dans plus que 6 UEs.  +  - Créez un trigger qui empêche le nombre d'​étudiants dans chaque groupe de dépasser ​ 32. 
- +  - Pour empêcher un étudiant de s’inscrire à des TD incompatibles (i.e. ayant lieu en même temps), ​ on introduit une nouvelle contrainte d’intégrité dans la base : un étudiant ne peut pas avoir deux inscriptions qui lui imposent d’être, au même moment, à deux endroits différents.
-3. Pour empêcher un étudiant de s’inscrire à des TD incompatibles (i.e. ayant lieu en même temps), ​ +
-on introduit une nouvelle contrainte d’intégrité dans la base : ​ +
-un étudiant ne peut pas avoir deux inscriptions qui lui imposent d’être, au même moment, ​ +
-à deux endroits différents.+
  
 Ecrire un trigger qui assure cette contrainte, de la façon suivante : Ecrire un trigger qui assure cette contrainte, de la façon suivante :
-  * en préambule à chaque inscription,​ le trigger inscrit le numéro de l’étudiant,​ avec le jour, l’heure et la salle du TD qu’il a choisi, dans une table supplémentaire LOCETUD ​ et une contrainte d’intégrité qui assure l’unicité du triplet (NoETUDIANT,​ JOUR, HEURE) : +  * en préambule à chaque inscription,​ le trigger inscrit le numéro de l’étudiant,​ avec le jour, l’heure et la salle du TD qu’il a choisi, dans une table supplémentaire LOCETUD ​ et une contrainte d’intégrité qui assure l’unicité du triplet (NoETUDIANT,​ JOUR, HEURE): 
-  * si l’étudiant a déjà pris une inscription correspondant au même jour et à la même heure, la contrainte de table précédente provoque le rejet du nouveau quadruplet ​ (NoETUDIANT,​ JOUR, HEURE, SALLE), le trigger est arrêté sur erreur, et l’instruction d’insertion d’un nouvel élément dans la table INSCRIPTION est, par suite, arrêtée sur erreur.+<code sql> 
 +CREATE TABLE LOCETUD (  
 + NoEtud smallint, 
 +    Jour varchar(8),​ 
 +   ​ Heure varchar(5),​ 
 +   ​ Salle varchar(10),​ 
 +   ​ PRIMARY KEY ( NoEtud, Jour, Heure )); 
 +</​code>  ​ 
 +  * si l’étudiant a déjà pris une inscription correspondant au même jour et à la même heure, la contrainte de table précédente provoque le rejet du nouveau quadruplet ​ (NoETUDIANT,​ JOUR, HEURE, SALLE), le trigger est arrêté sur erreur, et l’instruction d’insertion d’un nouvel élément dans la table INSCRIPTION est, par suite, arrêtée sur erreur. ​
  
-Le schéma de Locetud est  
- ​(NoEtud,​ Jour, Heure, Salle) ayant pour clé primaire le triplet ( NoEtud, Jour, Heure ). 
        
  
site/enseignement/licence/3i009/tme_triggers.1445445414.txt.gz · Dernière modification: 21/10/2015 18:36 par amann