Oracle/Oracle_SQL

[8장] 제약조건

산소썬 2014. 10. 29. 01:39

 

 

 

- 제약조건(Constraint) : 컬럼마다 정하는 규칙

                                     테이블에 올바른 데이터만 입력받고 잘못된 데이터는 들어오지 못하도록 함

 

 

 

1. 제약조건의 종류

 

조건 이름

의    미 

 NOT NULL

 NULL값이 입력되지 못함

 UNIQUE

 중복된 값이 입력되지 못함

 PRIMARY KEY

 NOT NULL + UNIQUE의 의미를 가짐

 테이블 내에서 데이터들끼리의 유일성을 보장하는 컬럼에 설정할 수 있으며

 테이블 당 1개만 설정할 수 있음

 FOREIGN KEY

 다른 테이블의 칼럼을 참조해서 무결성 검사를 하게 됨

 CHECK

 이 조건으로 설정된 값만 입력을 허용하고 나머지는 거부

 

 - 위의 제약 조건은 컬럼별로 설정

 - Primary Key를 제외한 나머지 제약조건들은 하나의 제약 조건이 여러 컬럼에 중복으로 설정 할 수 있고

    하나의 컬럼에 여러 개의 제약조건들이 중복으로 설정 할 수 있음

 

 -  어떤 컬럼에 UNIQUE 제약조건이나 Primary Key 제약조건을 설정하게 되면 해당 컬럼에 데이터는

    서로 중복이 되지 않는 다는 뜻

 

- Foreign Key를 제외한 나머지 4개는 한 개의 테이블에 설정되지만 Foreign Key는 두 개의 테이블에 동시에 설정 됨

 

 

 

 

 - 사원테이블에 입력이 될 때 부서 번호를 부서 테이블의 부서 번호 컬럼을 확인 한 후 존재하면 입력을 허용하고,

    존재하지 않는다면 에러를 발생하고 입력을 거부하게 설정

 

 - 정보를 제공해 주는 쪽 : 부서테이블(부모 테이블, Parent Table)

 - 정보를 받는 쪽 : 사원테이블(자식테이블, Child Table)

 

 - 부모 테이블쪽에 참조되는 컬럼에 설정되는 제약조건을 Reference Key(참조키)

 - 자식 테이블쪽에 참조되는 컬럼에 설정되는 제약조건을 Foreign Key(외래키)라고 부름

 

 - 참조키 제약조건은 자식 테이블에 데이터가 입력되기 위해서 부모 테이블의 특정 컬럼을 조사한 후

    해당 데이터가 있을 경우 입력 허가.

 - 부모 테이블의 데이터를 변경하려면 해당 부모 데이터를 참조하는 자식 테이블의 데이터가 없어야 함

 

 - 참조키 제약조건을 설정할 때는 자식 테이블과 부모 테이블의 해당 컬럼에 반드시 적절한 인덱스를 생성하길 권장함

 

 

 

2. 각 제약 조건의 설정 방법

 

1) 테이블 생성시에 동시에 설정하기

 

 SCOTT> CREATE TABLE emp3
           ( no NUMBER(4)
                  CONSTRAINT emp3_no_pk PRIMARY KEY ,
     4         name VARCHAR2(10)
     5              CONSTRAINT emp3_name_nn NOT NULL,
             jumin VARCHAR2(13)
     7              CONSTRAINT emp3_jumin_nn NOT NULL    ← 컬럼에 2개 이상의 제약 조건 설정
     8              CONSTRAINT emp3_jumin_uk UNIQUE ,
             area NUMBER(1)
    10             CONSTRAINT emp3_area_ck CHECK ( area < 5 ),
    11         deptno VARCHAR2(6)
    12             CONSTRAINT emp3_deptno_fk REFERENCES dept2(dcode)    ← 참조키 설정
    13         ) ;

 

 SCOTT> CREATE TABLE emp4
           ( no NUMBER(4) PRIMARY KEY ,
             name VARCHAR2(10) NOT NULL,
             jumin VARCHAR2(13) NOT NULL UNIQUE ,
             area NUMBER(1) CHECK ( area < 5 ),
             deptno VARCHAR2(6) REFERENCES dept2(dcode)
             ) ;

 

 

- 두가지 방법은 동일한 효과를 냄, 차이점은 각 제약 조건의 이름을 직접 지정하느냐 안 하느냐의 차이

- 뒤에서 제약조건을 비활성화 / 활성화 / 삭제하는 등의 관리 작업을 하려면 해당 제약조건의 이름을 알고 있어야 한다.
   그래서 제약 조건을 생성 할 때 위의 방법처럼 제약 조건의 이름을 직접 지정하는 것을 권장

   아래처럼 제약조건의 종류만 적고 이름을 적지 않게 되면 오라클이 자동으로 이름을 결정하게 되는데

   찾기가 불편한 부분이 많음

   이렇게 설정된 제약조건들은 딕셔너리에 저장되어 있으며 데이터가 입력되기 전에 참조

 

 

 

2) 테이블 생성 후 추가하기

 

- 위에서 생성한 emp4 테이블의 name 컬럼에 UNIQUE 제약 조건 추가

SCOTT> ALTER TABLE emp4
           ADD CONSTRAINT emp4_name_uk UNIQUE(name) ;

 

- emp4 테이블의 Area 컬럼에 NOT NULL 제약 조건 추가

SCOTT> ALTER TABLE emp4
     2       ADD CONSTRAINT emp4_area_nn NOT NULL(area) ;
ADD CONSTRAINT emp4_area_nn NOT NULL(area)
                                             *
ERROR at line 2:
ORA-00904: : invalid identifier


SCOTT> ALTER TABLE emp4
     2       MODIFY (area constraint emp4_area_nn NOT NULL) ;
Table altered.

 

 - 위 예에서 보듯이 NULL ↔ NOT NULL 로 변경하는 것은

    ADD CONSTRAINT 명령어로 하는 것이 아니라 기본값으로 허용되어 있는 NULL을 NOT NULL로 변경하는 것이기

    때문에 MODIFY 키워드를 사용해서 변경

 

 

- emp4테이블의 no컬럼이 emp2테이블의 empno컬럼의 값을 참조하도록 참조키 제약 조건 설정

   (emp4 테이블이 자식테이블입니다)

SCOTT> ALTER TABLE emp4
     2      ADD CONSTRAINT emp4_no_fk FOREIGN KEY(no)
     3      REFERENCES emp2(empno) ;

 

- 이렇게 참조키 제약조건을 설정하실 때 주의 사항
   : 부모 테이블 쪽에 설정되는 컬럼이 Primary Key 이거나 Unique Key가 설정되어 있어야 한다

 

SCOTT> ALTER TABLE emp4
     2       ADD CONSTRAINT emp4_name_fk FOREIGN KEY(name)
     3       REFERENCES emp2(name) ;
REFERENCES emp2(name)
                      *
ERROR at line 3:
ORA-02270: no matching unique or primary key for this column-list


SCOTT> ALTER TABLE emp2
     2       ADD CONSTRAINT emp2_name_uk UNIQUE(name);
Table altered.


SCOTT> ALTER TABLE emp4
     2       ADD CONSTRAINT emp4_name_fk FOREIGN KEY(name)
     3       REFERENCES emp2(name) ;
Table altered.


 

- FOREIGN KEY를 설정 후 부모 테이블 의 데이터를 지우고 싶은데 만약 자식테이블에서 부모테이블의 해당 데이터를

   참조하고 있을 경우 지울 수가 없음

- 이럴 경우를 대비해서 FOREIGN KEY를 생성할 때 ON DELETE CASCADE 옵션을 줄 수 있음

   이 옵션을 주면 부모테이블의 데이터가 지워지면 자식 테이블의 데이터도 함께 지우라는 의미가 됨
- ON DELETE SET NULL이란 옵션도 줄 수 있는 데 이 옵션은 부모테이블의 데이터가 지워질 경우 자식테이블의 값을

   NULL로 설정

 

 

Step 1. 연습용 테이블을 생성합니다.

SCOTT> create table c_test1 (
     2       no number ,
     3       name varchar2(6) ,
     4       deptno number);
Table created.


SCOTT> create table c_test2 (
     2       no number ,
     3       name varchar2(10));
Table created.


Step 2. 두 개의 테이블에 제약조건을 설정하고 데이터를 입력합니다.

SCOTT> alter table c_test1
     2       add constraint ctest1_deptno_fk foreign key(deptno)
     3       references c_test2(no);
references c_test2(no)
                                 *
ERROR at line 3:
ORA-02270: no matching unique or primary key for this column-list


SCOTT> alter table c_test2
     2       add constraint ctest2_no_uk unique(no);
Table altered.

 

SCOTT> alter table c_test1
     2       add constraint ctest1_deptno_fk foreign key(deptno)
     3       references c_test2(no)
     4       on delete cascade ; <------ 이렇게 설정합니다.
Table altered.

​SCOTT> insert into c_test2 values (10,'AAAA');
1 row created.


SCOTT> insert into c_test2 values (20,'BBBB');
1 row created.


SCOTT> insert into c_test2 values (30,'CCCC');
1 row created.


SCOTT> commit;
Commit complete.


SCOTT> select * from c_test2 ;
   NO     NAME
---- -------
   10      AAAA
   20      BBBB
   30      CCCC


SCOTT> insert into c_test1 values (1,'apple',10);
1 row created.


SCOTT> insert into c_test1 values (2,'banana',20);
1 row created.

 

SCOTT>insert into c_test1 values (3,'cherry',30);
1 row created.

 

Step 3. on delete cascade 테스트를 수행합니다.

SCOTT> insert into c_test1 values (4,'peach',40);
insert into c_test1 values (4,'peach',40)
*
ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.CTEST1_DEPTNO_FK) violated

 - parent key not found


SCOTT> select * from c_test1;
   NO    NAME     DEPTNO
----  ------ --------

    1     apple         10
    2     banana      20
    3     cherry       30


SCOTT> delete from c_test2 where no=10 ;
1 row deleted.

 


SCOTT>select * from c_test1;
   NO    NAME     DEPTNO
----  ------ --------

    2     banana      20
    3     cherry       30

 


위 결과에서 1 번 항목이 지워진 것이 확인됩니다.

 

 

Step 4. on delete set null 테스트를 수행합니다.

SCOTT> alter table c_test1 drop constraint ctest1_deptno_fk;
Table altered.


SCOTT> alter table c_test1
2 add constraint ctest1_deptno_fk foreign key(deptno)
3 references c_test2(no)
4 on delete set null;
Table altered.


SCOTT> select * from c_test1;
   NO    NAME     DEPTNO
----  ------ --------

    2     banana      20
    3     cherry       30


SCOTT> select * from c_test2;
   NO    NAME    
----  ------

   20     banana  

   30     cherry 


SCOTT> delete from c_test2 where no=20 ;
1 row deleted.


SCOTT> select * from c_test1;
   NO    NAME     DEPTNO
----  ------ --------

    2     banana                       ← 이 부분이 Null로 변경

    3     cherry       30


자식테이블의 deptno 가 null 로 변경되는 것이 확인 됨

 

 

 

 

 

자식 테이블의 deptno 컬럼에 not Null 속성이 설정되어 있는 상태에서 Foreign Key가 on delete set null 로 생성되면?!

 

 Step 1. 자식테이블의 deptno 에 not null 속성을 설정합니다.

SCOTT> alter table c_test1
     2      modify (deptno constraint ctest1_deptno_nn not null);
modify (deptno constraint ctest1_deptno_nn not null)
                                        *
ERROR at line 2:
ORA-02296: cannot enable (SCOTT.CTEST1_DEPTNO_NN) - null values found

(기존에 null 값이 있어서 변경할 수 없다는 뜻)


SCOTT> select * from c_test1;
   NO    NAME     DEPTNO
----  ------ --------

    2     banana      
    3     cherry       30


SCOTT> update c_test1 set deptno=30
     2      where no = 2;
1 row updated.


SCOTT> commit;
Commit complete.


SCOTT> select * from c_test1;
   NO    NAME     DEPTNO
----  ------ --------

    2     banana      30
    3     cherry       30


SCOTT> alter table c_test1
     2      modify (deptno constraint ctest1_deptno_nn not null);
Table altered.

(정상적으로 자식 테이블의 deptno 컬럼에 not null이 설정됨)

SCOTT> select * from c_test2;
   NO     NAME
---- -------
   30      CCCC


SCOTT> delete from c_test2;
delete from c_test2
                   *
ERROR at line 1:
ORA-01407: cannot update ("SCOTT"."C_TEST1"."DEPTNO") to NULL

( 부모 테이블을 지우려고 시도했더니 자식 테이블(c_test1) 을 null 로 update 할 수 없다고

   에러가 나고 작업이 수행되지 않음이 확인 됨)


SCOTT> select * from c_test2;
   NO     NAME
---- -------
   30      CCCC 

 

 

 

 

 

3. 제약조건 관리하기

 

 - 테이블의 컬럼에 설정되는 각 제약조건들은 어떤 필요에 의해서 일시적으로 DISABLE / ENABLE할 수 있음

    ex) 예를 들어 이미 검증된 대량의 데이터를 테이블에 입력 할 경우는 데이터를 입력할 때 제약조건을 다시 검사 할 필요가

          없다. 이럴 경우 제약조건을 임시로 DISABLE 해 둔 후 빠르게 데이터를 입력하고 입력이 완료되면

          다시 ENABLE 하는 등의 작업을 많이 함

 

1) 제약 조건 DISABLE하기

  : DISABLE 옵션은 NOVALIDATE와 VALIDATE 두 가지가 있음

  

 - NOVALIDATE 옵션은 해당 제약조건이 없어서 데이터가 전부 들어온다는 뜻

 

 

(1) DISABLE NOVALIDATE 사용하기

 

SCOTT> INSERT INTO test_novalidate VALUES(1,'DDD');
INSERT INTO test_novalidate VALUES(1,'DDD')
*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.SYS_C0014418) violated

(Primary Key 가 설정되어 있는 컬럼이므로 중복된 데이터 입력 안됨) 

SCOTT> ALTER TABLE test_novalidate
     2      DISABLE NOVALIDATE CONSTRAINT SYS_C0014418 ;
Table altered.


SCOTT> INSERT INTO test_novalidate VALUES(1,'DDD');
1 row created.     ← 정상적으로 입력

 

 

- DISABLE NOVALIDATE로 제약조건을 DISABLE하게 되면 CONSTRAINT가 없는 것과 동일하게 작동

 

 

(3) DISABLE VALIDATE 옵션 설정 후 다른 컬럼 내용 변경하기

​      Test_validate 테이블에 name 컬럼에 설정되어 있던 NOT NULL 제약조건이

      DISABLE VALIDATE 되어 있는 상태에서 다른 컬럼에 데이터를 입력

SCOTT> INSERT INTO test_validate VALUES(4,'DDD');
INSERT INTO test_validate VALUES(4,'DDD')
*
ERROR at line 1:
ORA-25128: No insert/update/delete on table with constraint (SCOTT.TV_NAME_NN)
disabled and validated


-- NULL 값 입력 하기
SCOTT> INSERT INTO test_validate VALUES(4,NULL);
INSERT INTO test_validate VALUES(4,NULL)
*
ERROR at line 1:
ORA-25128: No insert/update/delete on table with constraint (SCOTT.TV_NAME_NN)
disabled and validated


-- 다른 컬럼에만 데이터 입력하기
SCOTT> INSERT INTO test_validate(no)
     2      VALUES(4) ;
INSERT INTO test_validate(no)
*
ERROR at line 1:
ORA-25128: No insert/update/delete on table with constraint (SCOTT.TV_NAME_NN)
disabled and validated

 

 

 - 위 테스트 결과 DISABLE VALIDATE 옵션은 결과적으로 테이블의 내용을 변경 할 수 없도록 함

 - 위 테스트는 INSERT만 했지만 UPDATE나 DELETE 또한 동일한 결과를 볼 수 있음

 

 - DISABLE 의 기본 옵션 :  NOVALIDATE

 - PRIMARY KEY나 UNIQUE 제약조건을 DISABLE 할 경우 생성되어 있던 UNIQUE INDEX 가 자동으로 삭제됨

 

 

 

 

2) 제약 조건 ENABLE하기

 

 - DISABLE되어 있던 제약조건을 ENABLE하는 방법도 NOVALIDATE / VALIDATE 두 가지가 있음

 - ENABLE NOVALIDATE는 제약조건을 ENABLE하는 시점까지 테이블에 들어 있는 데이터는 검사하지 않고

    ENABLE 한 시점 이후부터 입력되는 데이터만 제약조건을 적용하여 검사하는 옵션

 

 - ENABLE VALIDATE는 제약조건을 ENABLE하는 시점까지 테이블에 입력되어 있던 모든 데이터를 전부 검사하며

    신규로 입력되는 데이터도 전부 검사하는 옵션

 - 해당 제약조건을 ENABLE VALIDATE하게 되면 오라클이 해당 테이블에 데이터가 변경되지 못하도록(기존 데이터를

    검사해야 하므로) LOCK을 설정

 - 만약 검사도중에 제약조건을 위반하는 값이 발견되면 에러를 발생하면서 제약조건 ENABLE 작업을 취소

    그렇게 되면 DBA나 사용자가 그 위반되는 데이터를 찾아서 적절하게 조치 후 다시 ENABLE 작업을 반복해서 시도해야 함

    문제는 그 위반되는 데이터를 일일이 찾아서 조치를 해줘야 한다는 것

    데이터가 많은 테이블은 데이터 이전 후 검증하는 데 시간이 아주 오래 걸릴 수 있습니다. 기본값이 ENABLE VALIDATE 

 

 - 이런 문제를 조금이라도 해결하기 위해 ENABLE VALIDATE 일 경우 사용할 수 있는 EXCEPTIONS라는 테이블이 존재

    이 테이블에 위반 사항을 저장하게 설정하면 한결 쉽게 ENABLE 작업을 하실 수 있음!!

 


테스트용 테이블 test_enable 에 데이터를 입력

 

SCOTT> INSERT INTO test_enable VALUES(1,'AAA');
1 row created.


SCOTT> INSERT INTO test_enable VALUES(2,'BBB');
1 row created.


SCOTT> INSERT INTO test_enable VALUES(3,NULL);  
INSERT INTO test_enable VALUES(3,NULL)    데이터가 NOT NULL제약조건에 걸려 입력 안됨 
                                                          *
ERROR at line 1:
ORA-01400: cannot insert NULL into ("SCOTT"."TEST_ENABLE"."NAME")

 

 

  해당 제약조건을 DISABLE로 변경 후 다시 입력해 보겠습니다

 

SCOTT> ALTER TABLE test_enable
     2      DISABLE CONSTRAINT te_name_nn ;
Table altered.


SCOTT> INSERT INTO test_enable VALUES(3,NULL);
1 row created.       ← 잘 입력 됨

 

 

위 테스트 결과로 지금 test_enable 의 테이블에는 잘못된 데이터가 들어가 있다.
이 상태에서 제약 조건을 ENABLE

 

(1) ENABLE NOVALIDATE로 name 컬럼 제약조건 ENABLE하기

SCOTT> ALTER TABLE test_enable
     2      ENABLE NOVALIDATE CONSTRAINT te_name_nn ;
Table altered.


SCOTT> SELECT * FROM test_enable ;
   NO     NAME
---- -------
    1      AAA
    2      BBB
    3                     ← 이 행이 잘못된 데이터


SCOTT> INSERT INTO test_enable VALUES(4,NULL);
INSERT INTO test_enable VALUES(4,NULL)
                                                     *
ERROR at line 1:
ORA-01400: cannot insert NULL into ("SCOTT"."TEST_ENABLE"."NAME")

 

 

 - 위 테스트 결과를 보면 test_enable 테이블의 name 컬럼에 NOT NULL 제약 조건이 설정되어 있음에도 불구하고

    3행의 NULL 값의 데이터가 입력되어 있음이 확인됨

    즉, ENABLE NOVALIDATE 옵션은 ENABLE 시점에 테이블에 입력되어 있던 기존 데이터는 검사를 하지 않기 때문에

    이런 현상이 생김 그러나 ENABLE 후 입력하는 값은 에러가 나고 입력이 안됨을 볼 수 있다

 

- 앞에서 살펴본 바와 같이 ENABLE NOVALIDATE는 신규로 입력되는 데이터만 검사함

 

 

(2) ENABLE VALIDATE로 name 컬럼 제약조건 ENABLE하기

SCOTT> ALTER TABLE test_enable
     2      DISABLE CONSTRAINT te_name_nn ;
Table altered.


SCOTT> ALTER TABLE test_enable
     2      ENABLE VALIDATE CONSTRAINT te_name_nn ;
ENABLE VALIDATE CONSTRAINT te_name_nn
                                             *
ERROR at line 2:
ORA-02293: cannot validate (SCOTT.TE_NAME_NN) - CHECK constraint violated

 

 

 - 위 결과처럼 테이블에 잘못된 데이터가 들어가 있기 때문에 ENABLE VALIDATE를 할 수 없음

   이럴 때 문제가 되는 행을 찾아서 수정해야 하는데 데이터가 많을 경우 일일이 그 행을 찾기가 힘들 때가 많음

   이렇게 ENABLE VALIDATE 할 때 문제가 되는 행을 별도의 테이블에 저장해서 문제 행을 쉽게 찾을 수 있도록

   해 주는 기능이 EXCEPTIONS 테이블!!(이 기능은 사용자가 별도로 생성하고 설정해야 함)

 

 

 

 

3) EXCEPTIONS 테이블을 사용하여 ENABLE VALIDATE 하기

 

Step 1. SYS계정으로 exceptions table 을 생성

SYS> @?/rdbms/admin/utlexcpt.sql        ?는 $ORACLE_HOME 디렉토리를 의미합니다.
Table created.


Step 2. 테스트용 테이블 (scott.tt550) 을 not null 제약조건을 가지도록 생성

SYS> CREATE TABLE scott.tt550
   2    ( no NUMBER CONSTRAINT tt550_nn NOT NULL);
Table created.


Step 3. 테스트용 테이블의 NOT NULL 속성을 사용 안 함 모드로 변경

SYS> ALTER TABLE scott.tt550 DISABLE CONSTRAINT tt550_nn;
Table altered.


Step 4. 테스트용 데이터를 입력하는데 null 값도 함께 입력

SYS> INSERT INTO scott.tt550 VALUES (1);
1 row created.


SYS> INSERT INTO scott.tt550 VALUES (null);       null 값 입력함. 이상 없이 들어감
1 row created.


SYS> INSERT INTO scott.tt550 VALUES (2);
1 row created.


SYS> COMMIT ;
Commit complete.


SYS> SELECT * FROM scott.tt550;
   NO
-----
     1
                    ← 문제가 될 null 부분입니다
     2


 Step 5. not null 제약조건을 사용함으로 변경하면서 exceptions table을 사용하게 설정.

 

SYS> ALTER TABLE scott.tt550 ENABLE VALIDATE CONSTRAINT tt550_nn
2 EXCEPTIONS INTO sys.exceptions;
alter table scott.tt550 enable validate constraint tt550_nn
*
ERROR at line 1:
ORA-02293: cannot validate (SCOTT.TT550_NN) - CHECK constraint violated <- 예상했던 에러발생

 


Step 6. exceptions table 을 조회하여 에러 내역을 확인

SYS> SELECT rowid, no
   2    FROM scott.tt550
   3    WHERE rowid in (SELECT row_id FROM exceptions) ;
  ROWID                                   NO
---------------------  -------
 AAANExAAEAAAAVMAAB                       ← no 의 값이 null


Step 7. 테스트용 테이블 scott.tt550 에서 문제가 되는 부분을 정상적인 값으로 업데이트

SYS> UPDATE scott.tt550
   2    SET no=3
   3    WHERE rowid ='AAANExAAEAAAAVMAAB';
1 row updated.


SYS> COMMIT ;
Commit complete.


SYS> TRUNCATE TABLE sys.exceptions;
Table truncated.                        수정 완료한 에러내역을 삭제하기 위해 TRUNCATE 

SYS> ALTER TABLE scott.tt550 ENABLE VALIDATE CONSTRAINT tt550_nn
   2    EXCEPTIONS INTO sys.exceptions;
Table altered.


SYS> SELECT * FROM scott.tt550;
   NO
-----
     1
     3               ← null이었던 값이 정상적인 데이터로 변경
     2

 

​Step 8. not null 이 사용함인 상태에서 일부러 null 값을 입력하여 not null 이 작동함을 확인

SYS> INSERT INTO scott.tt550 VALUES (null);
insert into scott.tt550 values (null)
                                                *
ERROR at line 1:
ORA-01400: cannot insert NULL into ("SCOTT"."TT550"."NO")

↑ null 데이터가 입력되지 않음

 

 

 

 

 

4) 제약조건 조회하기

 

 - 테이블에 제약조건을 설정하면 그 내용이 딕셔너리에 저장이 되어 있음
 - 사용하는 딕셔너리는 USER_CONSTRAINTS와 USER_CONS_COLUMNS이며

    데이터베이스 전체의 제약조건을 조회하려면 DBA_CONSTRAINTS와 DBA_CONS_COLUMNS를 사용

 

 

 

사용 예 1: emp4 테이블에 설정되어 있는 제약조건 조회하기

SCOTT> SELECT owner, constraint_name, constraint_type, status
     2      FROM user_constraints
     3      WHERE table_name='EMP4';

 

 - constraint_type 의 타입 값 중 P: Primary Key , U :Unique , C: CHECK , R:외래키를 의미

 

  

사용 예 2: FOREIGN KEY 조회하기

SCOTT> COL child_table FOR a15
SCOTT> COL child_column FOR a15
SCOTT> COL child_cons_name FOR a15
SCOTT> COL parent_table FOR a15
SCOTT> COL parent_cons_name FOR a15
SCOTT> COL parent_column FOR a15

​SCOTT> SELECT a.table_name "Child_Table",
     2                   c.column_name "Child_Column",
     3                   a.constraint_name "Child_Cons_name",
     4                   b.table_name "Parent_Table" ,
     5                   a.r_constraint_name "Parent_Cons_name" ,
     6                   d.column_name "Parent_Column"
     7      FROM user_constraints a , user_constraints b , user_cons_columns c,
     8                (SELECT constraint_name, column_name, table_name
     9                 FROM user_cons_columns) d
    10      WHERE a.r_constraint_name=b.constraint_name
    11      AND     a.constraint_name=c.constraint_name
    12      AND     a.r_constraint_name=d.constraint_name
    13      AND     a.constraint_type='R' ;
 Child_Table    Child_Column   Child_Cons_name    Parent_Table   Parent_Cons_nam   Parent_Column
---------- ----------- -------------- ----------- --------------- -------------
 EMP               DEPTNO            FK_DEPTNO               DEPT             PK_DEPT                 DEPTNO
 EMP4             DEPTNO            SYS_C0014411           DEPT2           SYS_C0014275        DCODE
 EMP3             DEPTNO            EMP3_DEPTNO_FK      DEPT2           SYS_C0014275        DCODE
 EMP4             NO                    EMP4_NO_FK              EMP2             SYS_C0014273        EMPNO
 EMP8             NO                    EMP8_NO_FK              EMP2             SYS_C0014273        EMPNO
 EMP4             NAME                EMP4_NAME_FK          EMP2             EMP2_NAME_UK       NAME
6 rows selected.

 

 

 

5) 제약조건 삭제하기

 

SCOTT> ALTER TABLE emp4
     2      DROP CONSTRAINT emp4_name_fk ;

 

 

 

 

 

서진수,『오라클 SQL과 PL/SQL』, 생능출판사, 2012, pp.282-299