Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment utiliser une clé étrangère dans Oracle

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