Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Jak używać klucza obcego w Oracle

Co to jest klucz obcy

Klucz obcy w Oracle to sposób na powiązanie wielu tabel. Jest to połączenie między tabelami.

  • Klucz obcy to kolumna lub zestaw kolumn, który odnosi się do klucza podstawowego lub klucza unikalnego w tej samej lub innej tabeli
  • Wartości klucza obcego są oparte na wartościach danych i są konstrukcją czysto logiczną, a nie fizycznymi wskaźnikami
  • Wartość klucza obcego musi być zgodna z wartością klucza podstawowego lub unikalną wartością klucza lub ma wartość NULL.

Ograniczenia klucza obcego są nazywane ograniczeniami integralności referencyjnej. Tabela, do której się odwołuje, nazywana jest tabelą nadrzędną, podczas gdy tabela z kluczem obcym nazywana jest tabelą podrzędną.

jak używać klucza obcego

Sprawdźmy na przykładzie EMP i 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

Tabela EMP zawiera kolumnę DEPT_NO. Tabela DEPT zawiera również kolumnę DEPT_NO i jest to klucz podstawowy w tabeli.

Teraz nie chcemy żadnych wpisów w tabeli EMP, gdzie DEPT_NO nie pasuje do DEPT_NO w kolumnie DEPT, ponieważ nie możemy mieć emp, którego numer dept nie istnieje. Zobaczmy, czy możemy to zrobić z bieżącą konfiguracją

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

Ale to się udało i struktura spowodowała problem z integralnością danych

Aby uniknąć tego typu problemów z danymi, możemy wymusić ograniczenia klucza obcego w tabeli EMP.
Zobaczmy jeszcze raz

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

Teraz spróbujmy wpisać ten sam wiersz

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

Dzięki temu uniknięto wpisów złych danych.

To samo dotyczy scenariusza z Usuń z tabeli DEPT. Nie powinniśmy usuwać wierszy działu, w którym emp ma jakieś rekordy. Bez ograniczeń klucza obcego to się wydarzy i spowoduje złe dane. Ale w przypadku klucza obcego można tego uniknąć

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

Klauzule kluczy obcych w opcji usuwania

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

Przypadek 1: Klucz obcy zdefiniowany bez opcji ON DELETE
Nie będzie można usunąć rekordów z tabeli nadrzędnej, jeśli rekordy zostaną znalezione w tabeli podrzędnej

Sprawa -2 Klucz obcy zdefiniowany opcją ON DELETE SET NULL
Zobaczmy, jak to działa

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 

Tak więc po usunięciu wierszy z tabeli nadrzędnej kolumna klucza obcego wierszy podrzędnych jest pusta

Przypadek -3 Klucz obcy zdefiniowany opcją 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>

Tak więc po usunięciu wierszy z tabeli nadrzędnej usuwane są również wiersze podrzędne

Zmień klucz obcy tabeli

Możemy również utworzyć klucz obcy w Oracle po utworzeniu tabeli

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

Jak usunąć ograniczenie klucza obcego

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

Jak wyłączyć ograniczenie

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

Jak włączyć ograniczenie

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

Też czyta
Sprawdź ograniczenie w Oracle
Ograniczenie Not Null w Oracle
Jak dodać klucz podstawowy w Oracle :klucz podstawowy jednoznacznie identyfikuje wiersz w tabeli. Jak dodać klucz podstawowy w oracle, jak usunąć klucz podstawowy, jak utworzyć klucz złożony
upuść ograniczenie klucza obcego oracle
unikalny klucz w oracle :Unikalny klucz wymusza unikalność w kolumnie w tabeli i pomaga szybko identyfikujemy wiersz. Oracle tworzy unikalny indeks dla klucza, jeśli żaden indeks nie jest dostępny
usuń zapytanie w 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. Dlaczego nie mogę zrobić a z x jako (...) z ADODB i Oracle?

  2. ORA-01008:nie wszystkie zmienne są powiązane. Są związani

  3. Jak połączyć się w java jako SYS z Oracle?

  4. PL/SQL — przykład podniesienia błędu aplikacji

  5. Jak przekonwertować 1985-02-07T00:00:00.000Z (ISO8601) na wartość daty w Oracle?