Hvad er fremmednøgle
Fremmednøgle i Oracle er en måde at relatere flere tabeller. Det er en krydskobling mellem tabellerne.
- En fremmednøgle er en kolonne eller et sæt kolonner, der refererer til primærnøglen eller den unikke nøgle i den samme tabel eller en anden tabel
- Fremmednøgleværdier er baseret på dataværdier, og de er udelukkende logiske konstruktioner og ikke fysiske pointere
- Fremmednøgleværdi skal matche en primær nøgleværdi eller unik nøgleværdi, eller den er null.
Udenlandske nøglebegrænsninger kaldes referenceintegritetsbegrænsninger. Den refererede tabel kaldes den overordnede tabel, mens tabellen med den fremmede nøgle kaldes den underordnede tabel.
hvordan bruges fremmednøgle
Lad os se med eksemplet EMP og 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-tabellen indeholder DEPT_NO-kolonnen. og DEPT-tabellen indeholder også DEPT_NO-kolonnen, og den er den primære nøgle i tabellen.
Nu vil vi ikke have nogen indgange i tabellen EMP, hvor DEPT_NO ikke stemmer overens med DEPT_NO i DEPT-kolonnen, da vi ikke kan have en emp, hvis afdelingsnummer ikke eksisterer. Lad os se, om vi kan gøre dette med den nuværende opsætning
SQL> insert into emp values( 7790, 'TOM', 'ANALYST', 7567, to_date('9-7-2017','dd-mm-yyyy'), 4000, null, 50); 1 row created.
Men dette lykkedes, og strukturen har forårsaget et dataintegritetsproblem
For at undgå disse typer dataproblemer kan vi håndhæve begrænsningerne for udenlandsk nøgle på EMP-tabellen.
Lad os se igen
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 );
Lad os nu prøve at indtaste den samme række
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
Så det har undgået indtastning af de dårlige data.
Det samme er scenariet med Slet fra DEPT-tabellen. Vi bør ikke slette rækkerne i afdelingen, hvor emp har nogle rekorder. Uden fremmednøgle-begrænsninger vil det ske og vil forårsage dårlige data. Men med fremmednøgle vil dette blive undgået
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
Fremmednøgleklausuler om sletningsmulighed
CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ENABLE ON DELETE [CASCADE |SET NULL]
Case 1: Fremmednøgle defineret uden ON DELETE mulighed
Du vil ikke være i stand til at slette poster fra den overordnede tabel, hvis der findes poster i den underordnede tabel
Case -2 Fremmednøgle defineret med TIL SLET INDSTIL NULL mulighed
Lad se, hvordan det virker
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
Så ved sletning af rækkerne fra den overordnede tabel, bliver underordnede rækkers fremmednøglekolonne gjort nul
Case -3 Fremmednøgle defineret med ON DELETE CASCADE mulighed
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>
Så ved sletning af rækkerne fra den overordnede tabel, slettes underordnede rækker også
Alter Table Fremmednøgle
Vi kan også oprette en fremmednøgle i Oracle efter tabeloprettelsen
alter table emp add CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ;
Sådan droppes fremmednøglebegrænsningen
SQL> alter table emp drop constraint "FK_DEPTNO"; Table altered.
Sådan deaktiverer du begrænsningen
SQL> alter table emp disable constraint "FK_DEPTNO"; Table altered.
Sådan aktiverer du begrænsningen
SQL> alter table emp enable constraint "FK_DEPTNO"; Table altered. SQL>
Læser også
Tjek begrænsning i Oracle
Ikke null begrænsning i Oracle
Sådan tilføjes primærnøgle i Oracle:primærnøgle identificerer entydigt rækken i tabellen. Sådan tilføjer du primærnøgle i oracle, sådan slipper du primærnøgle, hvordan opretter du en sammensat nøgle
slip fremmednøglebegrænsning oracle
unik nøgle i oracle :Unik nøgle håndhæver unik i kolonnen i tabellen og hjælper vi identificerer rækken hurtigt. Oracle opretter det unikke indeks for nøglen, hvis intet indeks er tilgængeligt
slet forespørgsel i oracle
https://en.wikipedia.org/wiki/Foreign_key