Oracle
 sql >> база данни >  >> RDS >> Oracle

Как да използвам външен ключ в oracle

Какво е външния ключ

Външният ключ в Oracle е начин за свързване на множество таблици. Това е кръстосана връзка между таблиците.

  • Външният ключ е колона или набор от колони, които се отнасят до първичния ключ или уникален ключ в същата таблица или друга таблица
  • Стойностите на външния ключ се базират на стойности на данни и са чисто логическа конструкция, а не физически указатели
  • Стойността на външния ключ трябва да съвпада със стойност на първичен ключ или уникален ключ или е нула.

Ограниченията на външния ключ се наричат ​​ограничения за референтна цялост. Реферираната таблица се нарича родителска таблица, докато таблицата с външния ключ се нарича дъщерна таблица.

как да използвам външен ключ

Нека проверим с примера на EMP и 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 таблицата съдържа колоната DEPT_NO. и таблицата DEPT съдържа също колоната DEPT_NO и това е първичният ключ в таблицата.

Сега не искаме никакви записи в таблицата EMP, където DEPT_NO не съвпада с DEPT_NO в колоната DEPT, тъй като не можем да имаме emp, чийто dept Number не съществува. Нека видим дали можем да направим това с текущата настройка

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

Но това успя и структурата доведе до проблем с целостта на данните

За да избегнем тези типове проблеми с данните, можем да наложим ограниченията на външния ключ върху таблицата EMP.
Нека да видим отново

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 );

Сега нека се опитаме да въведете същия ред

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

Така че е избегнало вписванията на лошите данни.

Същият е сценарият и с Изтриване от таблицата DEPT. Не трябва да изтриваме редовете на отдела, където emp има някои записи. Без ограничения на външния ключ това ще се случи и ще доведе до лоши данни. Но с външния ключ това ще бъде избегнато

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

Клаузи за чужд ключ при опция за изтриване

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

Случай 1: Външен ключ, дефиниран без опция ON DELETE
Няма да можете да изтривате записи от родителската таблица, ако записи са открити в дъщерната таблица

Случай -2 Външен ключ, дефиниран с опция ON DELETE SET NULL
Да видим как работи

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 

Така че при изтриване на редовете от родителската таблица, колоната с външния ключ на дъщерните редове се прави нула

Случай -3 Външен ключ, дефиниран с опция 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>

Така че при изтриване на редовете от родителската таблица, дъщерните редове също се изтриват

Промяна на външния ключ на таблицата

Можем да създадем и външен ключ в Oracle след създаването на таблицата

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

Как да премахнете ограничението за външния ключ

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

Как да деактивирам ограничението

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

Как да активирам ограничението

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

Също чете
Проверете ограничението в Oracle
Ограничението не е нула в Oracle
Как да добавите първичен ключ в oracle:първичният ключ уникално идентифицира реда в таблицата. Как да добавите първичен ключ в oracle, как да махнете първичния ключ, как да създадете съставен ключ
изпуснете ограничението на външния ключ oracle
уникален ключ в oracle :Уникалният ключ налага уникален ключ в колоната в таблицата и помага бързо идентифицираме реда. Oracle създава уникалния индекс за ключа, ако няма наличен индекс
изтриване на заявка в oracle
https://en.wikipedia.org/wiki/Foreign_key


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Първи стъпки с Oracle SQL Developer на MacOSX

  2. Възможно ли е да се създават типове обекти на Oracle Database вътре в PL/SQL?

  3. OdbcConnection връща китайски символи като ?

  4. Различни стойности се отчитат в една и съща колона

  5. Oracle:DDL и връщане на транзакциите