sql >> Database teknologi >  >> RDS >> Oracle

Hvordan man bruger en fremmed nøgle i oracle

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


  1. Sådan opdaterer og sletter du listen. Se data i SQLite-database med kliklytter?

  2. Send array til MySQL-lagret rutine

  3. Redundante data i opdateringserklæringer

  4. Find de maksimale på hinanden følgende år for hvert ID'er i en tabel (Oracle SQL)