sql >> Databasteknik >  >> RDS >> Oracle

Hur man använder främmande nyckel i oracle

Vad är främmande nyckel

Främmande nyckel i Oracle är ett sätt att relatera flera tabeller. Det är en tvärbindning mellan tabellerna.

  • En främmande nyckel är en kolumn eller uppsättning kolumner som refererar till primärnyckeln eller unik nyckel i samma tabell eller en annan tabell
  • Främmande nyckelvärden är baserade på datavärden och de är rent logiska konstruktioner inte fysiska pekare
  • Värdet på en främmande nyckel måste matcha ett primärnyckelvärde eller unikt nyckelvärde eller så är det null.

Främmande nyckelbegränsningar kallas referensintegritetsbegränsningar. Den refererade tabellen kallas den överordnade tabellen medan tabellen med den främmande nyckeln kallas den underordnade tabellen.

hur man använder främmande nyckel

Låt oss kolla med exemplet EMP och 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 innehåller kolumnen DEPT_NO. och DEPT-tabellen innehåller också kolumnen DEPT_NO och den är den primära nyckeln i tabellen.

Nu vill vi inte ha några poster i tabellen EMP där DEPT_NO inte matchar DEPT_NO i DEPT-kolumnen eftersom vi inte kan ha en emp vars avdelningsnummer inte finns. Låt oss se om vi kan göra detta med den nuvarande installationen

SQL> insert into emp values( 7790, 'TOM', 'ANALYST', 7567, to_date('9-7-2017','dd-mm-yyyy'), 4000, null, 50);
 1 row created.

Men detta lyckades och strukturen har orsakat ett dataintegritetsproblem

För att undvika dessa typer av dataproblem kan vi genomdriva begränsningarna för främmande nyckel på EMP-tabellen.
Låt oss 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 );

Låt oss nu försöka gå in i samma rad

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å den har undvikit inmatning av dålig data.

Detsamma är scenariot med Ta bort från DEPT-tabellen. Vi borde inte ta bort raderna i avdelningen där emp har några rekord. Utan begränsningar för främmande nyckel kommer det att hända och kommer att orsaka dålig data. Men med främmande nyckel kommer detta att undvikas

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

Klausuler för främmande nyckel vid raderingsalternativ

CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO")
 REFERENCES "DEPT" ("DEPTNO") ENABLE
 ON DELETE [CASCADE |SET NULL]

Fall 1: Främmande nyckel definierad utan ON DELETE-alternativet
Du kommer inte att kunna ta bort poster från den överordnade tabellen om poster finns i den underordnade tabellen

Fall -2 Främmande nyckel definierad med ON DELETE SET NULL-alternativet
Låt se hur det fungerar

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å när raderna tas bort från den överordnade tabellen, blir underordnade raders främmande nyckelkolumn null

Fall -3 Främmande nyckel definierad med alternativet 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>

Så när raderna tas bort från den överordnade tabellen raderas även underordnade rader

Ändra tabell främmande nyckel

Vi kan också skapa en främmande nyckel i Oracle efter att tabellen skapats

 alter table emp add CONSTRAINT "FK_DEPTNO" FOREIGN KEY ("DEPTNO") REFERENCES "DEPT" ("DEPTNO") ; 

Hur man släpper begränsningen för främmande nyckel

SQL> alter table emp drop constraint "FK_DEPTNO";
 Table altered.

Hur man inaktiverar begränsningen

SQL> alter table emp  disable   constraint "FK_DEPTNO";
 Table altered.

Hur man aktiverar begränsningen

SQL>  alter table emp   enable  constraint "FK_DEPTNO";
 Table altered.
 SQL>

Läser också
Kontrollera begränsning i Oracle
Inte noll-begränsning i Oracle
Hur man lägger till primärnyckel i Oracle :primärnyckel identifierar unikt raden i tabellen. Hur man lägger till primärnyckel i Oracle, hur man släpper primärnyckel, hur man skapar en sammansatt nyckel
släpp främmande nyckel-begränsning oracle
unik nyckel i Oracle :Unik nyckel upprätthåller unik i kolumnen i tabellen och hjälper till vi identifierar raden snabbt. Oracle skapar det unika indexet för nyckeln om inget index är tillgängligt
ta bort fråga i oracle
https://en.wikipedia.org/wiki/Foreign_key


  1. SQL-utvecklare 4

  2. Lär dig hur du skapar PK från Sequence Trigger i SQL Developer

  3. Beräkna skillnaden mellan två datumtider i MySQL

  4. Hur man distribuerar ett produktionsfärdigt MySQL- eller MariaDB Galera-kluster med ClusterControl