Intégrité des données
Ce chapitre explique comment les contraintes d'intégrité appliquent les règles métier associées à une base de données et empêchent la saisie d'informations non valides dans les tables.
-
Introduction à l'intégrité des données Il est important que les données maintiennent l'intégrité des données, qui est conforme aux règles métier déterminées par l'administrateur de base de données ou le développeur d'applications.
-
Types de contraintes d'intégrité Oracle AI Database vous permet d'appliquer des contraintes au niveau de la table et de la colonne, ainsi que des assertions impliquant plusieurs tables.
-
Etats des contraintes et assertions d'intégrité Dans le cadre de la définition de contrainte ou d'assertion, vous pouvez indiquer comment et quand Oracle AI Database doit appliquer la contrainte ou l'assertion, déterminant ainsi l'état de la contrainte ou de l'assertion. Voir aussi : Présentation des tables pour l'arrière-plan sur les colonnes et la nécessité de contraintes d'intégrité.
Introduction à l'intégrité des données
Il est important que les données maintiennent l'intégrité des données, qui est conforme aux règles métier déterminées par l'administrateur de base de données ou le développeur d'applications.
Les règles indiquent des conditions et des relations qui doivent toujours être vraies ou fausses. Par exemple, chaque société définit ses propres politiques sur les salaires, les numéros d'employé, le suivi des stocks, etc.
-
Techniques de garantie de l'intégrité des données Lors de la conception d'une application de base de données, les développeurs disposent de plusieurs options pour garantir l'intégrité des données stockées dans la base.
-
Avantages des contraintes d'intégrité Une contrainte d'intégrité est un objet de schéma qui est créé et supprimé à l'aide de SQL. Pour garantir l'intégrité des données, utilisez autant que possible des contraintes ou des assertions d'intégrité.
Techniques de garantie de l'intégrité des données
Lors de la conception d'une application de base de données, les développeurs disposent de plusieurs options pour garantir l'intégrité des données stockées dans la base.
Les options disponibles sont les suivantes :
-
Appliquer des règles avec des procédures de base de données stockée déclenchées
-
Utiliser des procédures stockées pour contrôler complètement l'accès aux données
-
Appliquer des règles dans le code d'une application de base de données
-
Utilisation des contraintes d'intégrité d'Oracle AI Database, qui sont des règles définies au niveau de la colonne ou de l'objet qui restreignent les valeurs dans la base de données
-
Utilisation d'assertions, qui sont des expressions booléennes impliquant des sous-interrogations sur les tables de base de données d'une application
Voir aussi :
-
La section Présentation des déclencheurs explique l'objectif et les types de déclencheur.
-
"Introduction à la programmation côté serveur" explique l'objectif et les caractéristiques des procédures stockées
Avantages des contraintes d'intégrité
Une contrainte d'intégrité est un objet de schéma créé et supprimé à l'aide de SQL. Pour garantir l'intégrité des données, utilisez autant que possible des contraintes ou des assertions d'intégrité.
Voici quelques avantages des assertions et contraintes d'intégrité par rapport aux alternatives permettant d'assurer l'intégrité des données :
-
Facilité de déclaration
Etant donné que vous définissez des contraintes d'intégrité et des assertions à l'aide d'instructions SQL, aucune programmation supplémentaire n'est requise lorsque vous définissez ou modifiez une table. Les instructions SQL sont faciles à écrire et éliminent les erreurs de programmation.
-
Règles centralisées
Les contraintes et assertions d'intégrité sont définies pour les tables et sont stockées dans le dictionnaire de données. Ainsi, les données saisies par toutes les applications doivent respecter les mêmes contraintes et assertions d'intégrité. Si les règles changent au niveau de la table, les applications n'ont pas besoin d'être modifiées. En outre, les applications peuvent utiliser les métadonnées du dictionnaire de données pour informer immédiatement les utilisateurs des violations, avant même que la base de données ne vérifie l'instruction SQL.
-
Flexibilité lors du chargement des données
Vous pouvez désactiver temporairement les assertions et les contraintes d'intégrité afin d'éviter toute surcharge de performances lors du chargement de grandes quantités de données. Une fois le chargement des données terminé, vous pouvez réactiver les contraintes et les assertions d'intégrité.
Voir aussi :
-
Oracle AI Database - Introduction à Oracle AI Database Development et Oracle AI Database Development Guide pour apprendre à maintenir l'intégrité des données
-
Guide de l'administrateur Oracle AI Database pour apprendre à gérer les contraintes d'intégrité
Types de contrainte d'intégrité
Oracle AI Database vous permet d'appliquer des contraintes au niveau de la table et de la colonne, ainsi que des assertions impliquant plusieurs tables.
Une contrainte spécifiée dans la définition d'une colonne ou d'un attribut est une spécification intégrée. Une contrainte spécifiée dans la définition de la table est une spécification hors ligne.
Une clé est la colonne ou l'ensemble de colonnes inclus dans la définition de certains types de contraintes d'intégrité. Les clés décrivent les relations entre les tables et les colonnes d'une base de donnée relationnelle. Les valeurs individuelles d'une clé sont appelées valeurs de clé.
Le tableau suivant décrit les types de contrainte. Chacun peut être spécifié en ligne ou hors ligne, à l'exception de NOT NULL, qui doit être en ligne.
Tableau 1 Types de contrainte d'intégrité
| Type de contrainte | Description | Voir aussi |
|---|---|---|
NOT NULL |
Autorise ou interdit l'insertion ou la mise à jour de lignes contenant une valeur null dans une colonne spécifiée. | "Contraintes d'intégrité NOT NULL" |
| Clé unique | Empêche plusieurs lignes d'avoir la même valeur dans la même colonne ou une combinaison de colonnes mais autorise la Présence de valeurs NULL. | "Contraintes uniques" |
| Clé primaire | Combine une contrainte NOT NULL et une contrainte unique. Elle interdit à plusieurs lignes d'avoir la même valeur dans la même colonne ou la même combinaison de colonnes et empêche les valeurs d'être NULL. |
"Contraintes de clé primaire" |
| Clé étrangère | Désigne une colonne en tant que clé étrangère et établit une relation entre la clé étrangère et une clé primaire ou unique, appelée clé référencée. | Contraintes de clé étrangère |
| Chèque | Nécessite une valeur de base de données pour obéir à une condition spécifiée. | "Contraintes de vérification" |
REF |
Indique les types de manipulation de données autorisés sur les valeurs d'une colonne REF et la façon dont ces actions affectent les valeurs dépendantes. Dans une base de données relationnelle objet, un type de données intégré appelé REF encapsule une référence à un objet de ligne d'un type d'objet spécifié. Les contraintes d'intégrité référentielle sur les colonnes REF garantissent l'existence d'un objet de ligne pour REF. |
Guide du développeur Oracle AI Database Object-Relational pour en savoir plus sur les contraintes REF |
Assertions |
Les assertions sont des expressions booléennes qui impliquent des sous-interrogations dans les tables de base de données d'une application. Les assertions ont la sémantique d'une contrainte, c'est-à-dire que la base de données est chargée de garantir la vérité de ces expressions booléennes pendant que les transactions modifient les données et valident ces modifications. | Assertions SQL pour en savoir plus sur les assertions |
-
Contraintes d'intégrité NOT NULL Une contrainte
NOT NULLexige qu'une colonne d'une table ne contienne aucune valeur NULL. Un null est l'absence de valeur. Par défaut, toutes les colonnes d'une table autorisent les valeurs NULL. -
Contraintes uniques Une contrainte de clé unique requiert que chaque valeur d'une colonne ou d'un ensemble de colonnes soit unique. Aucune ligne d'une table ne peut contenir de valeurs en double dans une seule colonne (clé unique) ou dans un ensemble de colonnes (clé unique composite) avec une contrainte de clé unique.
-
Contraintes de clé primaire Dans une contrainte de clé primaire, les valeurs du groupe d'une ou plusieurs colonnes soumises à la contrainte identifient de manière unique la ligne. Chaque table peut avoir une clé primaire, qui en fait nomme la ligne et garantit l'absence de lignes en double.
-
Contraintes de clé étrangère Chaque fois que deux tables contiennent une ou plusieurs colonnes communes, Oracle AI Database peut appliquer la relation entre les deux tables via une contrainte de clé étrangère, également appelée contrainte d'intégrité référentielle.
-
Vérifier les contraintes Une contrainte de vérification sur une colonne ou un ensemble de colonnes exige qu'une condition spécifiée soit vraie ou inconnue pour chaque ligne.
-
Contraintes CHECK prévérifiables Une contrainte CHECK marquée comme
PRECHECKpeut être vérifiée en dehors de la base de données. -
Les assertions Assertions sont des expressions booléennes qui impliquent des sous-interrogations sur les tables de base de données d'une application.
Voir aussi :
-
Référence du langage SQL d'Oracle AI Database pour en savoir plus sur les types de contrainte
Contraintes d'intégrité NOT NULL
Une contrainte NOT NULL exige qu'une colonne d'une table ne contienne aucune valeur NULL. Un null est l'absence de valeur. Par défaut, toutes les colonnes d'une table autorisent les valeurs NULL.
Les contraintes NOT NULL sont destinées aux colonnes qui ne doivent pas manquer de valeurs. Par exemple, la table hr.employees requiert une valeur dans la colonne email. Une tentative d'insertion d'une ligne de salarié sans adresse e-mail génère une erreur :
SQL> INSERT INTO hr.employees (employee_id, last_name) values (999, 'Smith');
.
.
.
ERROR at line 1:
ORA-01400: cannot insert NULL into ("HR"."EMPLOYEES"."EMAIL")
Vous pouvez uniquement ajouter une colonne avec une contrainte NOT NULL si la table ne contient aucune ligne ou si vous indiquez une valeur par défaut.
Voir aussi :
-
Oracle AI Database - Introduction à Oracle AI Database Development pour obtenir des exemples d'ajout de contraintes
NOT NULLà une table -
Référence de langage SQL Oracle AI Database pour connaître les restrictions d'utilisation des contraintes
NOT NULL -
Guide de développement Oracle AI Database pour savoir quand utiliser la contrainte
NOT NULL
Contraintes uniques
Une contrainte de clé unique requiert que chaque valeur d'une colonne ou d'un ensemble de colonnes soit unique. Aucune ligne d'une table ne peut contenir de valeurs en double dans une seule colonne (clé unique) ou dans un ensemble de colonnes (clé unique composite) avec une contrainte de clé unique.
Remarque : le terme clé fait uniquement référence aux colonnes définies dans la contrainte d'intégrité. Etant donné que la base de données applique une contrainte unique en créant ou en réutilisant implicitement un index sur les colonnes de clé, le terme clé unique est parfois utilisé de manière incorrecte comme synonyme de contrainte de clé unique ou d'index unique.
Les contraintes de clé unique sont appropriées pour toute colonne dans laquelle les valeurs en double ne sont pas autorisées. Les contraintes uniques diffèrent des contraintes de clé primaire, dont le but est d'identifier chaque ligne de la table de manière unique, et contiennent généralement des valeurs qui n'ont pas d'autre importance que d'être uniques. Exemples de clés uniques :
-
Numéro de téléphone du client, où la clé primaire est le numéro du client
-
Un nom de service, où la clé primaire est le numéro de service.
Comme indiqué dans l'exemple 4-1, une contrainte de clé unique existe sur la colonne email de la table hr.employees. La partie pertinente de la déclaration est la suivante :
CREATE TABLE employees ( ...
, email VARCHAR2(25)
CONSTRAINT emp_email_nn NOT NULL ...
, CONSTRAINT emp_email_uk UNIQUE (email) ... );
La contrainte emp_email_uk garantit qu'aucun employé n'a la même adresse électronique, comme indiqué dans l'exemple suivant :
SQL> SELECT employee_id, last_name, email FROM employees WHERE email = 'PFAY';
EMPLOYEE_ID LAST_NAME EMAIL
----------- ------------------------- -------------------------
202 Fay PFAY
SQL> INSERT INTO employees (employee_id, last_name, email, hire_date, job_id)
1 VALUES (999,'Fay','PFAY',SYSDATE,'ST_CLERK');
.
.
.
ERROR at line 1:
ORA-00001: unique constraint (HR.EMP_EMAIL_UK) violated
Sauf si une contrainte NOT NULL est également définie, une valeur NULL satisfait toujours une contrainte de clé unique. Par conséquent, les colonnes avec des contraintes de clé uniques et des contraintes NOT NULL sont typiques. Cette combinaison force l'utilisateur à saisir des valeurs dans la clé unique et élimine la possibilité que de nouvelles données de ligne entrent en conflit avec des données de ligne existantes.
Remarque : en raison du mécanisme d'interrogation des contraintes de clé unique sur plusieurs colonnes, vous ne pouvez pas avoir de valeurs identiques dans les colonnes non NULL d'une contrainte d'une clé unique composite partiellement NULL.
Exemple 7-1 Contrainte unique
SQL> SELECT employee_id, last_name, email FROM employees WHERE email = 'PFAY';
EMPLOYEE_ID LAST_NAME EMAIL
----------- ------------------------- -------------------------
202 Fay PFAY
SQL> INSERT INTO employees (employee_id, last_name, email, hire_date, job_id)
1 VALUES (999,'Fay','PFAY',SYSDATE,'ST_CLERK');
.
.
.
ERROR at line 1:
ORA-00001: unique constraint (HR.EMP_EMAIL_UK) violated
Voir aussi :
Contraintes de clé primaire
Dans une contrainte de clé primaire, les valeurs du groupe d'une ou de plusieurs colonnes soumises à la contrainte identifient de manière unique la ligne. Chaque table peut avoir une clé primaire, qui en fait nomme la ligne et garantit l'absence de lignes en double.
Une clé primaire peut être naturelle ou de substitution. Une clé naturelle est un identificateur significatif constitué d'attributs existants dans une table. Par exemple, une clé naturelle peut être un code postal dans une table de consultation.
En revanche, une clé de substitution est un identificateur d'incrémentation généré par le système qui garantit l'unicité au sein d'une table. En général, une séquence ou un UUID génère des clés de substitution.
L'implémentation de la contrainte de clé primaire par Oracle AI Database garantit que les affirmations suivantes sont vraies :
-
Deux lignes n'ont pas de valeurs en double dans la colonne ou l'ensemble de colonnes indiqué.
-
Les colonnes de clé primaire n'autorisent pas les valeurs NULL.
Une situation typique appelant à une clé primaire est l'identifiant numérique d'un employé. Chaque employé doit avoir un ID unique. Un employé doit être décrit par une seule ligne dans la table employees.
L'exemple de la section Contraintes uniques indique qu'un employé existant a l'ID 202, où l'ID d'employé est la clé primaire. L'exemple suivant illustre une tentative d'ajout d'un salarié avec le même matricule et d'un salarié sans matricule :
SQL> INSERT INTO employees (employee_id, last_name, email, hire_date, job_id)
1 VALUES (202,'Chan','JCHAN',SYSDATE,'ST_CLERK');
.
.
.
ERROR at line 1:
ORA-00001: unique constraint (HR.EMP_EMP_ID_PK) violated
SQL> INSERT INTO employees (last_name) VALUES ('Chan');
.
.
.
ERROR at line 1:
ORA-01400: cannot insert NULL into ("HR"."EMPLOYEES"."EMPLOYEE_ID")
La base de données applique les contraintes de clé primaire avec un index. En général, une contrainte de clé primaire créée pour une colonne crée implicitement un index unique et une contrainte NOT NULL. Notez les exceptions suivantes à cette règle :
-
Dans certains cas, comme lorsque vous créez une clé primaire avec une contrainte pouvant être différée, l'index généré n'est pas unique.
Remarque : vous pouvez créer explicitement un index unique à l'aide de l'instruction
CREATE UNIQUE INDEX. -
Si un index utilisable existe lors de la création d'une contrainte de clé primaire, celle-ci réutilise cet index et n'en crée pas implicitement.
Par défaut, le nom de l'index créé implicitement est celui de la contrainte à clé primaire. Vous pouvez également indiquer un nom défini par l'utilisateur pour un index. Vous pouvez indiquer des options de stockage pour l'index en incluant la clause ENABLE dans l'instruction CREATE TABLE ou ALTER TABLE utilisée pour créer la contrainte.
Voir aussi : Oracle AI Database Get Started with Oracle AI Database Development et Oracle AI Database Development Guide pour découvrir comment ajouter des contraintes de clé primaire à une table
Contraintes de clé étrangère
Chaque fois que deux tables contiennent une ou plusieurs colonnes communes, Oracle AI Database peut appliquer la relation entre les deux tables via une contrainte de clé étrangère, également appelée contrainte d'intégrité référentielle.
Une contrainte de clé étrangère exige que pour chaque valeur de la colonne sur laquelle la contrainte est définie, la valeur de l'autre table et colonne spécifiées corresponde. Un salarié ne peut travailler que pour un service existant, par exemple, une règle d'intégrité référentielle.
Le tableau suivant répertorie les termes associés aux contraintes d'intégrité référentielle.
Tableau 2 Termes de contrainte d'intégrité référentielle
| Terme | Définition |
|---|---|
| Clé étrangère | Colonne ou ensemble de colonnes inclus dans la définition de la contrainte qui référence une clé référencée. Par exemple, la colonne Les clés étrangères peuvent être définies en tant que colonnes multiples. Cependant, une clé étrangère composite doit référencer une clé primaire composite ou une clé unique avec le même nombre de colonnes et les mêmes types de données. La valeur des clés étrangères peut correspondre à la valeur de clé primaire ou unique référencée, ou être NULL. Si une colonne d'une clé étrangère composite est NULL, les parties non NULL de la clé ne doivent pas nécessairement correspondre à la partie correspondante d'une clé parent. |
| Clé référencée | Clé unique ou clé primaire de la table référencée par une clé étrangère. Par exemple, la colonne department_id dans departments est la clé référencée pour la colonne department_id dans employees. |
| Table dépendante ou enfant | Table qui inclut la clé étrangère. Cette table dépend des valeurs présentes dans la clé unique ou primaire référencée. Par exemple, la table employees est un enfant de departments. |
| Table référencée ou parent | Table référencée par la clé étrangère de la table enfant. C'est la clé référencée de cette table qui détermine si des insertions ou des mises à jour spécifiques sont autorisées dans la table enfant. Par exemple, la table departments est un parent de employees. |
La figure 7-1 présente une clé étrangère sur la colonne employees.department_id. Elle garantit que chaque valeur de cette colonne doit correspondre à une valeur de la colonne departments.department_id. Par conséquent, la colonne employees.department_id ne contient aucun numéro de département erroné.
Figure 1 : Contraintes d'intégrité référentielle

Description de l'image cncpt056.gif
-
Contraintes d'intégrité auto-référentielle Une contrainte d'intégrité auto-référentielle est une clé étrangère qui référence une clé parent dans la même table.
-
Nuls et clés étrangères Le modèle relationnel permet aux clés étrangères de correspondre à la valeur de clé primaire ou unique référencée, ou d'être NULL. Par exemple, une ligne dans
hr.employeespeut ne pas indiquer d'ID de département. -
Modifications de clé parent et clés étrangères La relation entre la clé étrangère et la clé parent a des implications pour la suppression des clés parent. Par exemple, si un utilisateur tente de supprimer l'enregistrement de ce service, que deviennent les enregistrements des employés de ce service ?
-
Index et clés étrangères En règle générale, les clés étrangères doivent être indexées. La seule exception est lorsque la clé unique ou primaire correspondante n'est jamais mise à jour ou supprimée. Voir aussi : Oracle AI Database Get Started with Oracle AI Database Development et Oracle AI Database Development Guide pour découvrir comment ajouter des contraintes de clé étrangère à une table
Contraintes d'intégrité auto-référentielle
Une contrainte d'intégrité auto-référentielle est une clé étrangère qui référence une clé parent dans la même table.
Dans la figure suivante, une contrainte auto-référentielle garantit que chaque valeur de la colonne employees.manager_id correspond à une valeur existante dans la colonne employees.employee_id. Par exemple, le responsable de l'employé 102 doit exister dans la table employees. Cette contrainte élimine le risque de numéros d'employé erronés dans la colonne manager_id.
Figure 2 : Contraintes référentielles à table unique

Description de l'image cncpt057.gif
Valeurs NULL et clés étrangères
Le modèle relationnel permet à la valeur des clés étrangères de correspondre à la valeur de clé primaire ou unique référencée, ou d'être NULL. Par exemple, une ligne dans hr.employees peut ne pas indiquer d'ID de département.
Si une colonne d'une clé étrangère composite est NULL, les parties non NULL de la clé ne doivent pas nécessairement correspondre à la partie correspondante d'une clé parent. Par exemple, une table reservations peut contenir une clé étrangère composite sur les colonnes table_id et date, mais table_id est NULL.
Modifications de clé parent et clés étrangères
La relation entre la clé étrangère et la clé parent a des implications pour la suppression des clés parent. Par exemple, si un utilisateur tente de supprimer l'enregistrement de ce service, que deviennent les enregistrements des employés de ce service ?
Lorsqu'une clé parent est modifiée, les contraintes d'intégrité référentielle peuvent spécifier les actions suivantes à effectuer sur les lignes dépendantes d'une table enfant :
-
Aucune action de suppression ou de mise à jour
Dans le cas normal, les utilisateurs ne peuvent pas modifier les valeurs de clé référencées si les résultats enfreignent l'intégrité référentielle. Par exemple, si
employees.department_idest une clé étrangère dedepartmentset que les employés appartiennent à un service particulier, la tentative de suppression de la ligne de ce service viole la contrainte. -
Suppressions en cascade
Une suppression en cascade (
DELETE CASCADE) lorsque des lignes contenant des valeurs de clé référencées sont supprimées, ce qui entraîne la suppression de toutes les lignes des tables enfant avec des valeurs de clé étrangère dépendantes. Par exemple, la suppression d'une ligne dansdepartmentsentraîne la suppression de lignes pour tous les employés de ce département. -
Suppressions ayant la valeur NULL
Une suppression définit la valeur NULL (
DELETE SET NULL) lorsque des lignes contenant des valeurs de clé référencées sont supprimées, ce qui entraîne la définition de la valeur NULL pour toutes les lignes des tables enfant avec des valeurs de clé étrangère dépendantes. Par exemple, la suppression d'une ligne de service définit la valeur de la colonnedepartment_idsur NULL pour les employés de ce service.
Le tableau 7-3 décrit les instructions LMD autorisées par les différentes actions référentielles sur les valeurs de clé dans la table parent et les valeurs de clé étrangère dans la table enfant.
Tableau 3 Instructions LMD autorisées par la mise à jour et la suppression sans action
| Instruction DML | Emis sur table parent | Table Emis pour enfant |
|---|---|---|
INSERT |
Toujours OK si la valeur de clé parent est unique | OK uniquement si la valeur de clé étrangère existe dans la clé parent ou est partiellement ou entièrement NULL |
UPDATE NO ACTION |
Autorisé si l'instruction ne laisse aucune ligne dans la table enfant sans valeur de clé parent référencée | Autorisé si la nouvelle valeur de clé étrangère référence toujours une valeur de clé référencée |
DELETE NO ACTION |
Autorisé si aucune ligne de la table enfant ne référence la valeur de clé parent | Toujours OK |
DELETE CASCADE |
Toujours OK | Toujours OK |
DELETE SET NULL |
Toujours OK | Toujours OK |
Remarque : d'autres actions référentielles non prises en charge par les contraintes d'intégrité FOREIGN KEY d'Oracle Database peuvent être appliquées à l'aide de déclencheurs de base de données. Reportez-vous à Présentation des déclencheurs.
Voir aussi : Référence du langage SQL Oracle AI Database pour en savoir plus sur la clause ON DELETE
Index et clés étrangères
En règle générale, les clés étrangères doivent être indexées. La seule exception est lorsque la clé unique ou primaire correspondante n'est jamais mise à jour ou supprimée.
L'indexation des clés étrangères dans les tables enfant présente les avantages suivants :
-
Empêche un verrouillage complet de la table enfant. A la place, la base de données acquiert un verrouillage de ligne sur l'index.
-
Supprime la nécessité d'un balayage complet de table de la table enfant. Par exemple, supposons qu'un utilisateur supprime l'enregistrement du département 10 de la table
departments. Siemployees.department_idn'est pas indexé, la base de données doit analyseremployeespour voir si des employés existent dans le département 10.
Voir aussi :
-
"Verrous et clés étrangères" explique le comportement de verrouillage des colonnes de clé étrangère indexées et non indexées
-
"Introduction aux index" explique l'objectif et les caractéristiques des index
Contraintes de vérification
Une contrainte de vérification sur une colonne ou un ensemble de colonnes requiert qu'une condition spécifiée soit vraie ou inconnue pour chaque ligne.
Si le code DML entraîne l'évaluation de la condition de la contrainte sur False, l'instruction SQL est annulée (rollback). Le principal avantage des contraintes de vérification est la capacité à appliquer des règles d'intégrité très spécifiques. Par exemple, vous pouvez utiliser des contraintes de vérification pour appliquer les règles suivantes dans la table hr.employees :
-
La colonne
salaryne doit pas avoir une valeur supérieure à 10000. -
La colonne
commissiondoit avoir une valeur qui ne soit pas supérieure au salaire.
L'exemple suivant crée une contrainte de salaire maximum sur employees et montre ce qui se passe lorsqu'une instruction tente d'insérer une ligne contenant un salaire supérieur au maximum :
SQL> ALTER TABLE employees ADD CONSTRAINT max_emp_sal CHECK (salary < 10001);
SQL> INSERT INTO employees (employee_id,last_name,email,hire_date,job_id,salary)
1 VALUES (999,'Green','BGREEN',SYSDATE,'ST_CLERK',20000);
.
.
.
ERROR at line 1:
ORA-02290: check constraint (HR.MAX_EMP_SAL) violated
La définition d'une colonne peut comporter plusieurs contraintes Check qui référencent la colonne. Par exemple, la colonne salary peut avoir une contrainte qui empêche les valeurs supérieures à 10000 et une contrainte distincte qui empêche les valeurs inférieures à 500.
S'il existe plusieurs contraintes de vérification pour une colonne, elles doivent être conçues de manière à ce que leurs objectifs ne soient pas contradictoires. Aucun ordre d'évaluation des conditions ne peut être supposé. La base de données ne vérifie pas que les conditions de vérification ne s'excluent pas mutuellement.
Voir aussi : Référence du langage SQL Oracle AI Database pour en savoir plus sur les restrictions relatives aux contraintes de vérification
Contraintes CHECK contrôlables
Une contrainte de vérification marquée comme PRECHECK peut être vérifiée en dehors de la base de données.
La définition d'une contrainte CHECK sur l'état PRECHECK est effectuée lors de la création ou de la modification de la table. L'état PRECHECK complète les états ENABLE et VALIDATE d'une contrainte et une contrainte dont les trois états peuvent être actifs en même temps.
Si vous utilisez JSON pour exprimer la contrainte de vérification, Oracle AI Database vous permet d'exporter un schéma JSON et de valider les données JSON par rapport à un valideur de schéma JSON dans le client d'application. Lorsqu'une contrainte est définie sur l'état PRECHECK, elle indique qu'elle dispose d'un schéma JSON équivalent qui conserve la sémantique de la contrainte. Les développeurs d'application client peuvent pré-valider la contrainte au sein de l'application client. La base de données vérifie la contrainte et une erreur est générée si elle ne peut pas être exprimée dans le schéma JSON.
Rubriques connexes
Assertions
Les assertions sont des expressions booléennes qui impliquent des sous-interrogations dans les tables de base de données d'une application.
Les assertions ont la sémantique d'une contrainte, c'est-à-dire que la base de données est chargée de garantir la vérité de ces expressions booléennes pendant que les transactions modifient les données et valident ces modifications.
L'instruction SQL suivante crée une assertion, nommée NO_TRAINERS_IN_BOSTON, pour exiger qu'aucun formateur ne soit employé dans les services basés à Boston. Le niveau supérieur NOT EXISTS représente une expression booléenne qui exige que l'ensemble de résultats de la jointure entre les tables EMP et DEPT reste vide.
CREATE ASSERTION no_trainers_in_boston CHECK
(NOT EXISTS
(SELECT 'trainer in Boston'
FROM emp e, dept d
WHERE e.deptno = d.deptno
AND e.job = 'TRAINER'
AND d.loc = 'BOSTON'));
Les assertions sont des objets de niveau schéma. Cela implique que si des tables d'autres schémas sont référencées par l'expression booléenne, le privilège objet ASSERTION REFERENCES est requis pour accéder à ces tables. Il ne s'agit pas d'une clé étrangère qui s'étend sur deux schémas, c'est-à-dire qu'un privilège objet REFERENCES doit être en place pour créer une clé étrangère qui pointe vers une clé primaire d'une table dans un schéma différent.
Les assertions sont des contraintes génériques d'intégrité des données. Ils pourraient être utilisés pour remplacer les contraintes CHECK, PRIMARY KEY, UNIQUE et FOREIGN KEY.
Par exemple, supposons les contraintes suivantes sur la table EMP :
-
CHECK (COMM <= SAL) -
PRIMARY KEY (EMPNO) -
UNIQUE (ENAME, DEPTNO) -
FOREIGN KEY (DEPTNO) REFERENCES DEPT(DEPTNO)
Ces contraintes peuvent être implémentées avec les affirmations suivantes :
CREATE ASSERTION commission_not_greater_than_salary CHECK
(NOT EXISTS
(SELECT ''
FROM emp e
WHERE e.comm > e.sal));
CREATE ASSERTION emp_empno_pk CHECK
(NOT EXISTS
(SELECT ''
FROM emp e1, emp e2
WHERE e1.empno = e2.empno
AND e1.rowid != e2.rowid));
CREATE ASSERTION emp_ename_deptno_uk CHECK
(NOT EXISTS
(SELECT ''
FROM emp e1, emp e2
WHERE e1.ename = e2.ename
AND e1.deptno = e2.deptno
AND e1.rowid != e2.rowid));
CREATE ASSERTION emp_fk_dept CHECK
(NOT EXISTS
(SELECT ''
FROM emp e
WHERE NOT EXISTS
(SELECT ''
FROM dept d
WHERE d.deptno = e.deptno)));
Cependant, nous vous conseillons fortement de toujours utiliser des contraintes chaque fois que cela est possible, et d'utiliser uniquement des assertions lorsque vous ne pouvez pas utiliser une contrainte.
Rubriques connexes
Etats des contraintes et assertions d'intégrité
Dans le cadre de la définition de contrainte ou d'assertion, vous pouvez indiquer comment et quand Oracle AI Database doit appliquer la contrainte ou l'assertion, déterminant ainsi l'état de la contrainte ou de l'assertion.
-
Vérifie les données modifiées et existantes La base de données vous permet d'indiquer si une contrainte ou une assertion s'applique aux données existantes ou futures. Si une contrainte ou une assertion est activée, la base de données vérifie les nouvelles données au fur et à mesure qu'elles sont entrées ou mises à jour. Les données non conformes à la contrainte ou à l'assertion ne peuvent pas entrer dans la base de données.
-
Lorsque la base de données vérifie la validité des contraintes et des assertions, chaque contrainte et assertion est dans un état non pouvant être différé (par défaut) ou différé. Cet état détermine quand Oracle AI Database vérifie la validité de la contrainte ou de l'assertion.
-
Exemples de vérification de contrainte et d'assertion Les exemples suivants illustrent le moment où Oracle AI Database effectue la vérification des contraintes et des assertions.
Recherche les données modifiées et existantes
La base de données vous permet d'indiquer si une contrainte ou une assertion s'applique à des données existantes ou futures. Si une contrainte ou une assertion est activée, la base de données vérifie les nouvelles données au fur et à mesure qu'elles sont entrées ou mises à jour. Les données non conformes à la contrainte ou à l'assertion ne peuvent pas entrer dans la base de données.
Par exemple, l'activation d'une contrainte NOT NULL sur employees.department_id garantit que chaque ligne future possède un ID de service. Si une contrainte est désactivée, la table peut contenir des lignes qui violent la contrainte.
Vous pouvez définir des contraintes et des assertions sur l'un des modes de validation suivants :
-
VALIDATELes données existantes doivent être conformes à la contrainte ou à l'assertion. Par exemple, l'activation d'une contrainte
NOT NULLsuremployees.department_idet sa définition surVALIDATEvérifie que chaque ligne existante a un ID de département. -
NOVALIDATELes données existantes ne doivent pas nécessairement être conformes à la contrainte ou à l'assertion. En fait, c'est un mode "Faites-moi confiance". Par exemple, si vous êtes certain que chaque vente que vous avez chargée dans une table a une date, vous pouvez créer une contrainte
NOT NULLsur la colonne de date et définir la contrainte surNOVALIDATE. Les contraintes non imposées se révèlent utiles uniquement pour les vues matérialisées et les réécritures des requêtes.Pour une contrainte en mode
NOVALIDATE, le paramètreRELYindique que l'optimiseur peut utiliser la contrainte pour déterminer les informations de jointure. Même si la contrainte n'est pas utilisée pour valider les données, elle permet des réécritures de requête plus sophistiquées pour les vues matérialisées et permet aux outils d'entreposage de données d'extraire les informations de contrainte du dictionnaire de données. La valeur par défaut estNORELY, ce qui signifie que l'optimiseur n'est pas au courant de la contrainte.
Le comportement de VALIDATE et NOVALIDATE dépend toujours de l'activation ou de la désactivation de la contrainte ou de l'assertion. Le tableau suivant récapitule les relations.
Tableau 4 Vérifications des données modifiées et existantes
| Données modifiées | Données existantes | Synthèse |
|---|---|---|
ENABLE |
VALIDATE |
Les données existantes et futures doivent obéir à la contrainte ou à l'affirmation. Une tentative d'application d'une nouvelle contrainte ou assertion à une table alimentée génère une erreur si des lignes existantes violent la contrainte ou l'assertion. |
ENABLE |
NOVALIDATE |
La base de données vérifie la contrainte ou l'assertion, mais elle n'est pas nécessairement vraie pour toutes les lignes. Par conséquent, les lignes existantes peuvent violer la contrainte ou l'assertion, mais les lignes nouvelles ou modifiées doivent être conformes aux règles. Ce mode est souvent utilisé dans les data warehouses qui contiennent des données existantes dont l'intégrité a déjà été vérifiée. |
DISABLE |
VALIDATE |
La base de données désactive la contrainte, supprime son index et empêche la modification des colonnes contraintes. Une assertion ne peut pas être dans cet état. |
DISABLE |
NOVALIDATE |
La contrainte ou l'assertion n'est pas vérifiée et n'est pas nécessairement vraie. |
Voir aussi : Référence du langage SQL d'Oracle AI Database pour en savoir plus sur les états de contrainte
Vérification de la validité des contraintes et assertions par la base de données
Chaque contrainte et assertion est soit dans un état non différable (par défaut), soit dans un état différable. Cet état détermine quand Oracle AI Database vérifie la validité de la contrainte ou de l'assertion.
Le graphique suivant présente les options pour les contraintes et les assertions pouvant être différées.
Figure 3 : Options pour les contraintes et assertions pouvant être différées

Description de l'image cncpt313.gif
-
Contraintes et assertions non transférables Dans une contrainte non transférable, Oracle AI Database ne reporte jamais la vérification de validité de la contrainte ou de l'assertion jusqu'à la fin de la transaction. Au lieu de cela, la base de données vérifie la contrainte ou l'assertion à la fin de chaque instruction. Si la contrainte ou l'assertion est violée, l'instruction est annulée.
-
Contraintes et assertions pouvant être différées Une contrainte ou assertion pouvant être différée permet à une transaction d'utiliser la clause
SET CONSTRAINTpour différer la vérification de cette contrainte ou assertion jusqu'à ce qu'une instructionCOMMITsoit émise. Si vous apportez des modifications à la base de données susceptibles de violer la contrainte ou l'assertion, ce paramètre vous permet de désactiver la contrainte ou l'assertion jusqu'à ce que toutes les modifications soient terminées.
Contraintes et assertions non transférables
Dans une contrainte non transférable, Oracle AI Database ne reporte jamais la vérification de validité de la contrainte ou de l'assertion jusqu'à la fin de la transaction. Au lieu de cela, la base de données vérifie la contrainte ou l'assertion à la fin de chaque instruction. Si la contrainte ou l'assertion est violée, l'instruction est annulée.
Par exemple, une contrainte NOT NULL non applicable existe pour la colonne employees.last_name. Si une session tente d'insérer une ligne sans nom, la base de données annule immédiatement l'instruction car la contrainte NOT NULL est violée. Aucune ligne n'est insérée.
Contraintes et assertions pouvant être différées
Une contrainte ou assertion pouvant être différée permet à une transaction d'utiliser la clause SET CONSTRAINT pour différer la vérification de cette contrainte ou assertion jusqu'à ce qu'une instruction COMMIT soit émise. Si vous apportez des modifications à la base de données susceptibles de violer la contrainte ou l'assertion, ce paramètre vous permet de désactiver la contrainte ou l'assertion jusqu'à ce que toutes les modifications soient terminées.
Vous pouvez définir le comportement par défaut lorsque la base de données vérifie la contrainte ou l'assertion pouvant être différée. Vous pouvez spécifier l'un des attributs suivants :
-
INITIALLY IMMEDIATELa base de données vérifie la contrainte ou l'assertion immédiatement après l'exécution de chaque instruction. Si la contrainte ou l'assertion est violée, la base de données annule l'instruction.
-
INITIALLY DEFERREDLa base de données vérifie la contrainte ou l'assertion lorsqu'une instruction
COMMITest émise. Si la contrainte ou l'assertion est violée, la base de données annule la transaction.
Supposons qu'une contrainte NOT NULL pouvant être différée sur employees.last_name soit définie sur INITIALLY DEFERRED. Un utilisateur crée une transaction avec 100 instructions INSERT, dont certaines ont des valeurs NULL pour last_name. Lorsque l'utilisateur tente de valider, la base de données annule les 100 instructions. Toutefois, si cette contrainte était définie sur INITIALLY IMMEDIATE, la base de données n'annulerait pas la transaction.
Si une contrainte provoque une action, la base de données considère cette action comme faisant partie de l'instruction qui l'a provoquée, que la contrainte soit différée ou immédiate. Par exemple, la suppression d'une ligne dans departments entraîne la suppression de toutes les lignes dans employees qui référencent la ligne de département supprimée. Dans ce cas, la suppression de employees est considérée comme faisant partie de l'instruction DELETE exécutée sur departments.
Voir aussi : Référence du langage SQL d'Oracle AI Database pour plus d'informations sur les attributs de contrainte et leurs valeurs par défaut
Exemples de vérification de contrainte et d'assertion
Les exemples suivants illustrent le moment où Oracle AI Database effectue la vérification des contraintes et des assertions.
Supposons les éléments suivants :
-
La table
employeesprésente la structure illustrée dans la section "Contraintes d'intégrité auto-référentielle". -
La contrainte auto-référentielle rend les entrées de la colonne
manager_iddépendantes des valeurs de la colonneemployee_id. -
Exemple : insertion d'une valeur dans une colonne de clé étrangère lorsqu'aucune valeur de clé parent n'existe Cet exemple concerne l'insertion de la première ligne dans la table
employees. Aucune ligne n'existe actuellement. Comment saisir une ligne si la valeur de la colonnemanager_idne peut pas référencer une valeur existante dans la colonneemployee_id? -
Exemple : mise à jour de toutes les valeurs de clé étrangère et de clé parent Dans cet exemple, une contrainte auto-référentielle rend les entrées de la colonne
manager_iddeemployeesdépendantes des valeurs de la colonneemployee_id. -
Exemple : chaque responsable doit avoir un commis dans le même service Cet exemple crée une assertion pour s'assurer que chaque responsable a un commis dans le même service.
Exemple : insertion d'une valeur dans une colonne de clé étrangère lorsqu'aucune valeur de clé parent n'existe
Cet exemple concerne l'insertion de la première ligne dans la table employees. Aucune ligne n'existe actuellement. Comment saisir une ligne si la valeur de la colonne manager_id ne peut pas référencer une valeur existante dans la colonne employee_id ?
Les possibilités sont les suivantes :
-
Si aucune contrainte
NOT NULLn'est définie sur la colonnemanager_id, vous pouvez entrer une valeur NULL pour la colonnemanager_idde la première ligne.Etant donné que les valeurs NULL sont autorisées dans les clés étrangères, Oracle AI Database insère cette ligne dans la table.
-
Vous pouvez entrer la même valeur dans les colonnes
employee_idetmanager_id, en indiquant que l'employé est son propre responsable.Ce cas révèle qu'Oracle AI Database effectue sa vérification des contraintes après l'exécution de l'instruction. Pour autoriser la saisie d'une ligne avec les mêmes valeurs dans la clé parent et la clé étrangère, la base de données doit d'abord insérer la nouvelle ligne, puis déterminer si une ligne de la table a une valeur
employee_idqui correspond à la valeurmanager_idde la nouvelle ligne. -
Une instruction
INSERTà plusieurs lignes, telle qu'une instructionINSERTavec des instructionsSELECTimbriquées, peut insérer des lignes qui se référencent.Par exemple, la première ligne peut avoir 200 pour le matricule salarié et 300 pour le matricule responsable, tandis que la deuxième ligne a 300 pour le matricule salarié et 200 pour le responsable. La vérification des contraintes est différée jusqu'à l'exécution complète de l'instruction
INSERT. La base de données insère toutes les lignes, puis recherche les violations de contrainte dans toutes les lignes.
Les valeurs par défaut sont incluses dans une instruction INSERT avant l'analyse de l'instruction. Par conséquent, les valeurs de colonne par défaut sont soumises à toute vérification des contraintes d'intégrité.
Exemple : mise à jour de toutes les valeurs de clé étrangère et de clé parent
Dans cet exemple, une contrainte auto-référentielle rend les entrées de la colonne manager_id de employees dépendantes des valeurs de la colonne employee_id.
La société a été vendue. En raison de cette vente, tous les numéros d'employé doivent être mis à jour pour correspondre à la valeur actuelle plus 5000 afin de se coordonner avec les numéros d'employé de la nouvelle société. Comme le montre le graphique suivant, certains employés sont également des responsables :
Figure 4 : Tableau des employés avant les mises à jour

Description de l'image cncpt058.gif
Les matricules de responsable étant également des matricules de salarié, ils doivent également augmenter de 5000. Vous pouvez exécuter l'instruction SQL suivante pour mettre à jour les valeurs :
UPDATE employees SET employee_id = employee_id + 5000,
manager_id = manager_id + 5000;
Bien qu'une contrainte soit définie pour vérifier que chaque valeur manager_id correspond à une valeur employee_id, l'instruction précédente est valide car la base de données vérifie effectivement les contraintes une fois l'instruction terminée. La figure 7-5 montre que la base de données effectue les actions de l'ensemble de l'instruction SQL avant de vérifier les contraintes.
Figure 5 : Vérification des contraintes

Description de l'image cncpt059.gif
Les exemples de cette section illustrent le mécanisme de vérification des contraintes lors des instructions INSERT et UPDATE, mais la base de données utilise le même mécanisme pour tous les types d'instruction LMD. La base de données utilise le même mécanisme pour tous les types de contrainte, pas seulement les contraintes auto-référentielles. Remarque : les opérations sur une vue ou un synonyme sont soumises aux contraintes d'intégrité définies dans les tables de base.
Exemple : chaque manager doit avoir un commis dans le même service
Cet exemple crée une assertion pour s'assurer que chaque manager a un employé dans le même département.
Dans cet exemple, vous devez d'abord insérer le commis, puis le responsable. Lors de l'exécution de plusieurs insertions de ligne, comme pour les contraintes, les assertions sont validées après l'exécution de chaque instruction INSERT. Vous pouvez définir cette assertion sur DEFERRABLE afin de vous permettre d'insérer d'abord le gestionnaire, puis le greffier. La validation aurait lieu à l'emplacement COMMIT au lieu de chaque instruction INSERT.
CREATE ASSERTION manager_has_clerk check
(NOT EXISTS
(SELECT 'manager without clerk'
FROM employees m
WHERE m.job_id = 'ST_MAN'
AND NOT EXISTS
(SELECT 'a clerk in same department'
FROM employees c
WHERE c.job_id = 'ST_CLERK'
AND c.department_id = m.department_id)));