0. 들어가기에 앞서...


각 제약조건의 의미와 테이블 생성시 제약조건을 설정하는 방법들에 대해선 "제약 조건 #1" 문서를 참고하자.

위 문서에서 SSMS를 이용하여, 제약조건을 설정하는 방법은 테이블을 만들고 나서도 자유롭게 추가/삭제가 가능하다.
하지만, 위 문서의 T-SQL을 이용한 방법은 테이블을 생성할 때의 내용뿐이었다.

이제 T-SQL을 이용하여 이미 존재하는 테이블, 그것도 대량의 데이터가 들어있는 테이블에 대해
새로이 제약조건을 추가하거나, 기존의 제약조건을 변경, 또는 삭제하는 방법을 알아보도록 하자.

기존의 테이블을 변경하는 기본 구문은 ALTER TABLE이며, 이에 대해선 이 챕터에서 자세히 설명하진 않는다.


1. 제약 조건의 추가

제약조건을 추가하는 기본 구문은 ADD CONTRAINT constraint_name이며,
이는 아래 예제들에서도 반복적으로 나오므로 자연스레 눈에 익을 것이라 생각한다.

ADD CONSTRAINT constraint_name과 각 제약조건의 종류에 따른 키워드들로 제약 조건 추가 구문이 조합된다.


1. PK 제약 조건

기본 키가 지정되어 있지 않던 테이블에 기본키를 추가하는 방법은 아래와 같다.

  1. ALTER TABLE UserTable
  2.     ADD CONSTRAINT PK_UserTable_ID
  3.     PRIMARY KEY(UserID)

    기존 테이블에 PK를 추가하려 할 때, 해당(UserID) 컬럼은 NOT NULL로 설정이 되어 있어야 한다.


    2. FK 제약 조건

    기존 테이블에 FK(외래 키)를 설정하는 방법은 아래와 같다.

    1. ALTER TABLE BuyTable
    2.     ADD CONSTRAINT FK_UserTable_ID
    3.     FOREIGN KEY (ID)                  -- 이 테이블에서 FK를 걸 컬럼명
    4.     REFERENCES UserTable(UserID)      -- 기준 테이블의 참조 컬럼명

    이미 데이터들이 꽤나 많이 차 있는 두 개의 테이블에 FK 의존 관계 설정시 애 먹는 경우가 있다.

    애초 의존 관계를 고려하지 않았기에, 기준 테이블에 존재하지 않는 데이터가 외래 키 테이블에 존재할 수 있기 때문이다.
    헌데, 이미 서비스 중이고, 대량의 데이터가 차 있기에, 모든 데이터의 의존 관계를 완벽하게 조정할 수도 없는 상태이다.

    이런 경우 ALTER TABLE 구문을 WITH NOCHECK 옵션과 함께 사용하면,
    이미 입력되어 있는 데이터의 무결성(의존 관계)를 무시하고 외래 키 관계가 설정된다.

    참고로, 아무 것도 써 주지 않을 경우 기본적으로 WITH CHECK 상태이다.

    1. ALTER TABLE BuyTable WITH NOCHECK
    2.     ADD CONSTRAINT FK_UserTable_ID
    3.     FOREIGN KEY (ID)                  -- 이 테이블에서 FK를 걸 컬럼명
    4.     REFERENCES UserTable(UserID)      -- 기준 테이블의 참조 컬럼명

    WITH NOCHECK 옵션은 FK와 CHECK 제약 조건에서만 설정이 가능하다.

    그리고 WITH CHECK / WITH NOCHECK 옵션은 
    제약 조건을 생성할 때 기존의 데이터를 검사하는 것을 무시하는 것일뿐설정한 후에는 당연히 제약 조건이 작동됨을 혼동하지 말자.


    3. UNIQUE 제약 조건

    기존 테이블에 UNIQUE 제약 조건을 추가하는 방법은 아래와 같다.

    1. ALTER TABLE UserTable
    2.     ADD CONSTRAINT UK_Regdate
    3.     UNIQUE RegDate


    4. CHECK 제약 조건

    기존 테이블에 CHECK 제약 조건을 추가 설정하는 방법은 아래와 같다.

    1. -- 출생년도가 1900년 이후 그리고 현재의 연도 이전
    2. ALTER TABLE UserTable
    3.     ADD CONSTRAINT CK_BirthYear
    4.     CHECK (BirthYear >= 1900 AND BirthYear <= YEAR(GETDATE()))
    5.  
    6. -- 전화번호 국번 체크 (아래 번호들 중에서만 가능)
    7. ALTER TABLE UserTable
    8.     ADD CONSTRAINT CK_Mobile1
    9.     CHECK (Mobile1 IN ('010''011''016''017''018''019'))
    10.  
    11. -- 키는 0 보다 커야 함
    12. ALTER TABLE UserTable
    13.     ADD CONSTRAINT CK_Height
    14.     CHECK (Height > 0)


    5. DEFAULT 정의


    기존에 없던 DEFALUT 정의를 추가하려면 아래와 같이 FOR 문을 함께 사용해 주어야 한다.

    1. ALTER TABLE UserTable
    2.     ADD CONSTRAINT CD_BirthYear
    3.     DEFAULT YEAR(GETDATE()) FOR BirthYear
    4.  
    5. ALTER TABLE UserTable
    6.     ADD CONSTRAINT CD_Addr
    7.     DEFAULT N'서울' FOR Addr
    8.  
    9. ALTER TABLE UserTable
    10.     ADD CONSTRAINT CD_Height
    11.     DEFAULT 172 FOR Height



    2. 제약 조건의 삭제

    기존의 제약 조건을 삭제하는 것은 추가하는 것에 비해 무척이나 간단하다.
    제약 조건의 종류에 관계없이 공통된 구문 하나로 모두 적용이 가능하다.

    1. ALTER TABLE tableName
    2.     DROP CONSTRAINT constraint_name

    만약, 제약 조건만 삭제하는 경우가 아니라, 해당 컬럼을 삭제하려 하고 그 컬럼에 제약 조건이 걸린 경우라면,
    1. 제약 조건을 먼저 삭제하고,
    2. 해당 컬럼을 삭제해야 한다.

    즉, UserTable의 BirthYear에 CHECK 제약 조건이 걸려 있는데, BirthYear 컬럼을 삭제하고 싶으면,
    아래 예제와 같이 CHECK 제약 조건을 먼저 삭제한 후에 컬럼을 삭제해야 하는 것이다.

    1. -- 먼제 BirthYear에 걸려있는 제약 조건을 삭제하고
    2. ALTER TABLE UserTable
    3.     DROP CK_BirthYear
    4.  
    5. -- BirthYear 컬럼을 삭제해야 한다.
    6. -- DROP COLUMN column_name 형식에 주의하라
    7. ALTER TABLE UserTABLE
    8.     DROP COLUMN BirthYear


    3. 제약 조건 활성/비활성화

    위에서 WITH CHECK / WITH NOCHECK 옵션은 
    제약 조건을 생성하는 그 순간에서만 제약 조건 체크를 스킵할 지 여부를 결정하는 것이라 하였다.

    그럼, 이미 만들어진 제약 조건을 잠깐 비활성화하고 싶을 때는 어떻게 해야 하는가?

    CHECK CONSTRAINT / NOCHECK CONSTRAINT 옵션을 사용하면 된다.
    • CHECK CONSTRAINT constraint_name : 특정 제약 조건을 활성화
    • NOCHECK CONSTRAINT constraint_name : 특정 제약 조건을 비활성화
    • NOCHECK CONSTRAINT ALL : 모든 제약 조건을 비활성화

    1. -- FK 일시적으로 비활성화
    2. ALTER TABLE BuyTable
    3.     NOCHECK CONSTRAINT FK_UserTable_ID
    4. GO
    5.  
    6. -- FK 제약 조건에 위배되는 데이터 삽입
    7. INSERT INTO BuyTable VALUES (...)
    8. INSERT INTO BuyTable VALUES (...)
    9. INSERT INTO BuyTable VALUES (...)
    10. GO
    11.  
    12. -- FK 다시 정상적으로 활성화
    13. ALTER TABLE BuyTable
    14.     CHECK CONSTRAINT FK_UserTable_ID
    15. GO

    간혹, 써 먹어야 될 때가 있을 것이다.


    'SQL > MS-SQL' 카테고리의 다른 글

    Datetime Fomat  (0) 2017.10.11
    PIVOT/ UNPIVOT  (0) 2017.09.21
    제약 조건(Constraint) #1 (의미와 설정)  (0) 2017.09.20
    테이블변수  (0) 2017.09.20
    테이블 컬럼변경  (0) 2017.09.20

    + Recent posts