Wat is een externe sleutel
Foreign key in Oracle is een manier om meerdere tabellen met elkaar in verband te brengen. Het is een verknoping tussen de tabellen.
- Een externe sleutel is een kolom of reeks kolommen die verwijst naar de primaire sleutel of unieke sleutel in dezelfde tabel of een andere tabel
- Foreign key-waarden zijn gebaseerd op gegevenswaarden en zijn puur logische constructies, geen fysieke verwijzingen
- De waarde van de buitenlandse sleutel moet overeenkomen met een primaire sleutelwaarde of een unieke sleutelwaarde, anders is deze null.
Foreign key-beperkingen worden referentiële integriteitsbeperkingen genoemd. De tabel waarnaar wordt verwezen, wordt de bovenliggende tabel genoemd, terwijl de tabel met de externe sleutel de onderliggende tabel wordt genoemd.
hoe een externe sleutel te gebruiken
Laten we eens kijken met het voorbeeld van EMP en 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
EMP-tabel bevat de kolom DEPT_NO. en DEPT-tabel bevat ook de kolom DEPT_NO en het is de primaire sleutel in de tabel.
Nu willen we geen items in de tabel EMP waar DEPT_NO niet overeenkomt met DEPT_NO in de kolom DEPT, omdat we geen emp kunnen hebben waarvan het dept-nummer niet bestaat. Laten we kijken of we dit kunnen doen met de huidige setup
SQL> insert into emp values( 7790, 'TOM', 'ANALYST', 7567, to_date('9-7-2017','dd-mm-yyyy'), 4000, null, 50); 1 row created.
Maar dit is gelukt en de structuur heeft een probleem met de gegevensintegriteit veroorzaakt
Om dit soort gegevensproblemen te voorkomen, kunnen we de Foreign key-beperkingen op de EMP-tabel afdwingen.
Laten we nog eens kijken
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 );
Laten we nu proberen dezelfde rij in te voeren
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
Dus het heeft de invoer van de slechte gegevens vermeden.
Hetzelfde is het scenario met Verwijderen uit de DEPT-tabel. We zouden de rijen van de afdeling waar emp enkele records heeft niet moeten verwijderen. Zonder externe sleutelbeperkingen zal dit gebeuren en slechte gegevens veroorzaken. Maar met Foreign key wordt dit vermeden
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
Buitenlandse sleutelclausules bij verwijderoptie
CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ENABLE ON DELETE [CASCADE |SET NULL]
Geval 1: Externe sleutel gedefinieerd zonder ON DELETE-optie
U kunt geen records uit de bovenliggende tabel verwijderen als er records worden gevonden in de onderliggende tabel
Zaak -2 Foreign key gedefinieerd met ON DELETE SET NULL optie
Eens kijken hoe het werkt
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
Dus bij het verwijderen van de rijen uit de bovenliggende tabel, wordt de kolom met de vreemde sleutel van de onderliggende rijen null gemaakt
Zaak -3 Foreign key gedefinieerd met ON DELETE CASCADE optie
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>
Dus bij het verwijderen van de rijen uit de bovenliggende tabel, worden ook onderliggende rijen verwijderd
Tabel externe sleutel wijzigen
We kunnen ook een externe sleutel in Oracle maken nadat de tabel is gemaakt
alter table emp add CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ;
Hoe de beperking van de externe sleutel te verwijderen
SQL> alter table emp drop constraint "FK_DEPTNO"; Table altered.
De beperking uitschakelen
SQL> alter table emp disable constraint "FK_DEPTNO"; Table altered.
De beperking inschakelen
SQL> alter table emp enable constraint "FK_DEPTNO"; Table altered. SQL>
Leest ook
Controlebeperking in Oracle
Niet Null-beperking in Oracle
Hoe u een primaire sleutel in Oracle kunt toevoegen:de primaire sleutel identificeert de rij in de tabel op unieke wijze. Hoe een primaire sleutel in Oracle toe te voegen, hoe de primaire sleutel te laten vallen, hoe een samengestelde sleutel te maken
drop externe sleutelbeperking Oracle
unieke sleutel in Oracle:Unieke sleutel dwingt uniek af in de kolom in de tabel en helpt ons identificeren de rij snel. Oracle maakt de unieke index voor de sleutel als er geen index beschikbaar is
query verwijderen in oracle
https://en.wikipedia.org/wiki/Foreign_key