Qu'est-ce qu'une clé étrangère
La clé étrangère dans Oracle est un moyen de relier plusieurs tables. C'est un cross-linking entre les tables.
- Une clé étrangère est une colonne ou un ensemble de colonnes qui fait référence à la clé primaire ou à la clé unique de la même table ou d'une autre table
- Les valeurs de clé étrangère sont basées sur des valeurs de données et sont une construction purement logique et non des pointeurs physiques
- La valeur de la clé étrangère doit correspondre à une valeur de clé primaire ou à une valeur de clé unique, sinon elle est nulle.
Les contraintes de clé étrangère sont appelées contraintes d'intégrité référentielle. La table référencée est appelée table parent tandis que la table avec la clé étrangère est appelée table enfant.
comment utiliser une clé étrangère
Vérifions avec l'exemple de EMP et DEPT.
SQL>CREATE TABLE "DEPT" ( "DEPTNO" NUMBER(2,0), "DNAME" VARCHAR2(14), "LOC" VARCHAR2(13), CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO") ) SQL>CREATE TABLE "EMP" ( "EMPNO" NUMBER(4,0), "ENAME" VARCHAR2(10), "JOB" VARCHAR2(9), "MGR" NUMBER(4,0), "HIREDATE" DATE, "SAL" NUMBER(7,2), "COMM" NUMBER(7,2), "DEPTNO" NUMBER(2,0), CONSTRAINT "PK_EMP" PRIMARY KEY ("EMPNO") ); SQL> desc emp Name Null? Type EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER(2) SQL> SQL> desc dept Name Null? Type DEPTNO NOT NULL NUMBER(2) DNAME VARCHAR2(14) LOC VARCHAR2(13) SQL> insert into DEPT values(10, 'ACCOUNTING', 'NEW YORK'); insert into dept values(20, 'RESEARCH', 'DALLAS'); insert into dept values(30, 'RESEARCH', 'DELHI'); insert into dept values(40, 'RESEARCH', 'MUMBAI'); insert into emp values( 7698, 'Blake', 'MANAGER', 7839, to_date('1-5-2007','dd-mm-yyyy'), 2850, null, 10 ); insert into emp values( 7782, 'Clark', 'MANAGER', 7839, to_date('9-6-2008','dd-mm-yyyy'), 2450, null, 10 ); insert into emp values( 7788, 'Scott', 'ANALYST', 7566, to_date('9-6-2012','dd-mm-yyyy'), 3000, null, 20 ); insert into emp values( 7789, 'TPM', 'ANALYST', 7566, to_date('9-6-2017','dd-mm-yyyy'), 3000, null, null ); insert into emp values( 7560, 'T1OM', 'ANALYST', 7567, to_date('9-7-2017','dd-mm-yyyy'), 4000, null, 20 ); insert into emp values( 7790, 'TOM', 'ANALYST', 7567, to_date('9-7-2017','dd-mm-yyyy'), 4000, null, null ); SQL> select from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO 7698 BLAKE MANAGER 7839 01-MAY-07 2850 10 7782 CLARK MANAGER 7839 09-JUN-08 2450 10 7788 SCOTT ANALYST 7566 09-JUN-12 3000 20 7789 TPM ANALYST 7566 09-JUN-17 3000 7790 TOM ANALYST 7567 09-JUL-17 4000 7560 T1OM ANALYST 7567 09-JUL-17 4000 20
La table EMP contient la colonne DEPT_NO. et la table DEPT contient également la colonne DEPT_NO et il s'agit de la clé primaire de la table.
Maintenant, nous ne voulons aucune entrée dans la table EMP où DEPT_NO ne correspond pas à DEPT_NO dans la colonne DEPT car nous ne pouvons pas avoir un emp dont le numéro de dept n'existe pas. Voyons si nous pouvons le faire avec la configuration actuelle
SQL> insert into emp values( 7790, 'TOM', 'ANALYST', 7567, to_date('9-7-2017','dd-mm-yyyy'), 4000, null, 50); 1 row created.
Mais cela a réussi et la structure a causé un problème d'intégrité des données
Pour éviter ces types de problèmes de données, nous pouvons appliquer les contraintes de clé étrangère sur la table EMP.
Revoyons à nouveau
drop table emp; drop table dept; SQL>CREATE TABLE "DEPT" ( "DEPTNO" NUMBER(2,0), "DNAME" VARCHAR2(14), "LOC" VARCHAR2(13), CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO") ) SQL>CREATE TABLE "EMP" ( "EMPNO" NUMBER(4,0), "ENAME" VARCHAR2(10), "JOB" VARCHAR2(9), "MGR" NUMBER(4,0), "HIREDATE" DATE, "SAL" NUMBER(7,2), "COMM" NUMBER(7,2), "DEPTNO" NUMBER(2,0), CONSTRAINT "PK_EMP" PRIMARY KEY ("EMPNO"), CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ENABLE ); SQL> desc emp Name Null? Type EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER(2) SQL> SQL> desc dept Name Null? Type DEPTNO NOT NULL NUMBER(2) DNAME VARCHAR2(14) LOC VARCHAR2(13) SQL> insert into DEPT values(10, 'ACCOUNTING', 'NEW YORK'); insert into dept values(20, 'RESEARCH', 'DALLAS'); insert into dept values(30, 'RESEARCH', 'DELHI'); insert into dept values(40, 'RESEARCH', 'MUMBAI'); insert into emp values( 7698, 'Blake', 'MANAGER', 7839, to_date('1-5-2007','dd-mm-yyyy'), 2850, null, 10 ); insert into emp values( 7782, 'Clark', 'MANAGER', 7839, to_date('9-6-2008','dd-mm-yyyy'), 2450, null, 10 ); insert into emp values( 7788, 'Scott', 'ANALYST', 7566, to_date('9-6-2012','dd-mm-yyyy'), 3000, null, 20 ); insert into emp values( 7789, 'TPM', 'ANALYST', 7566, to_date('9-6-2017','dd-mm-yyyy'), 3000, null, null ); insert into emp values( 7560, 'T1OM', 'ANALYST', 7567, to_date('9-7-2017','dd-mm-yyyy'), 4000, null, 20 ); insert into emp values( 7790, 'TOM', 'ANALYST', 7567, to_date('9-7-2017','dd-mm-yyyy'), 4000, null, null );
Essayons maintenant de saisir la même ligne
SQL> insert into emp values( 7790, 'TOM', 'ANALYST', 7567, to_date('9-7-2017','dd-mm-yyyy'), 4000, null, 50); insert into emp values( 7790, 'TOM', 'ANALYST', 7567, to_date('9-7-2017','dd-mm-yyyy'), 4000, null, 50) * ERROR at line 1: ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated - parent key not found
Ainsi, il a évité les entrées des mauvaises données.
Il en va de même pour le scénario avec Supprimer de la table DEPT. Nous ne devrions pas supprimer les lignes du département où emp a des enregistrements. Sans contraintes de clé étrangère, cela se produira et entraînera de mauvaises données. Mais avec la clé étrangère, cela sera évité
SQL> delete from dept where deptno=10; delete from dept where deptno=10 * ERROR at line 1: ORA-02292: integrity constraint (SCOTT.FK_DEPTNO) violated - child record found
Clauses de clé étrangère sur l'option de suppression
CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ENABLE ON DELETE [CASCADE |SET NULL]
Cas 1 : Clé étrangère définie sans l'option ON DELETE
Vous ne pourrez pas supprimer d'enregistrements de la table parent si des enregistrements sont trouvés dans la table enfant
Cas -2 Clé étrangère définie avec l'option ON DELETE SET NULL
Voyons comment cela fonctionne
SQL> alter table emp add CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ON DELETE SET NULL; Table altered. SQL> select * from emp where empno=7698; EMPNO DEPTNO ------- ---- 7698 10 SQL> delete from dept where deptno=10; 1 row deleted. SQL> commit; Commit complete. SQL> select * from emp where empno=7698; EMPNO DEPTNO ------- ---- 7698
Ainsi, lors de la suppression des lignes de la table parent, la colonne de clé étrangère des lignes enfants est rendue nulle
Cas -3 Clé étrangère définie avec l'option ON DELETE CASCADE
SQL> alter table emp add CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ON DELETE cascade; Table altered. SQL> delete from dept where deptno=10; 1 row deleted. SQL> commit; Commit complete. SQL> select * from emp where deptno=10; ; no rows selected SQL>
Ainsi, lors de la suppression des lignes de la table parent, les lignes enfants sont également supprimées
Modifier la clé étrangère de la table
Nous pouvons également créer une clé étrangère dans Oracle après la création de la table
alter table emp add CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ;
Comment supprimer la contrainte de clé étrangère
SQL> alter table emp drop constraint "FK_DEPTNO"; Table altered.
Comment désactiver la contrainte
SQL> alter table emp disable constraint "FK_DEPTNO"; Table altered.
Comment activer la contrainte
SQL> alter table emp enable constraint "FK_DEPTNO"; Table altered. SQL>
Lit également
Contrainte de vérification dans Oracle
Contrainte non nulle dans Oracle
Comment ajouter une clé primaire dans Oracle :la clé primaire identifie de manière unique la ligne dans la table. Comment ajouter une clé primaire dans oracle, comment supprimer une clé primaire, comment créer une clé composite
supprimer une contrainte de clé étrangère oracle
clé unique dans oracle :la clé unique applique une clé unique dans la colonne de la table et aide nous identifions le rang rapidement. Oracle crée l'index unique pour la clé si aucun index n'est disponible
supprimer la requête dans oracle
https://en.wikipedia.org/wiki/Foreign_key