WITH CHECK CHECK CONSTRAINT 란 무엇입니까?


18

자동 생성 된 T-SQL이 있는데 아마도 유효하지만 실제로는 이해하지 못합니다.

ALTER TABLE [dbo].[MyTable]
WITH CHECK
CHECK CONSTRAINT [My_FORIEGN_KEY];

외래 키 제약 조건이 무엇인지 알고 있지만 무엇 CHECK CHECK입니까?

답변:


27

MSDN 문서화 페이지에 대한 ALTER TABLE설명은 다음과 같습니다.

  • ALTER TABLE: 테이블 구조를 수정하십시오
    (및 가능한 조치 / 수정 중 일부는 다음과 같습니다).
    • CHECK CONSTRAINT ..: 제약 조건을 활성화합니다
    • NOCHECK CONSTRAINT ..: 제약 조건 비활성화 제약 조건
      을 생성 / 활성화 / 비활성화하는 동안 수행 할 수있는 추가 옵션 단계도 있습니다.
      • WITH CHECK: 제약 조건도 확인하십시오.
      • WITH NOCHECK: 제약 조건을 확인하지 마십시오

그들의 말로 :

| [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT   
    { ALL | constraint_name [ ,...n ] }

...

WITH CHECK | WITH NOCHECK테이블의 데이터 가 새로 추가되거나 다시 활성화 FOREIGN KEY되거나 CHECK제한 되는지 대해 유효성이 검사 되는지 여부를 지정합니다 . 지정되지 않은 경우 WITH CHECK새 제한 조건 WITH NOCHECK으로 가정되고 다시 사용 가능한 제한 조건으로 가정됩니다.

당신은 새로운 확인하지 않으려는 경우 CHECK또는 FOREIGN KEY기존 데이터 사용에 제약을 WITH NOCHECK. 드문 경우를 제외하고는이 작업을 수행하지 않는 것이 좋습니다. 새로운 구속 조건은 이후의 모든 데이터 업데이트에서 평가됩니다. 제한 WITH NOCHECK조건이 추가 될 때 억제되는 제한 조건 위반 은 제한 조건을 준수하지 않는 데이터로 행을 업데이트하는 경우 향후 갱신에 실패 할 수 있습니다.

쿼리 최적화 프로그램은 정의 된 제약 조건을 고려하지 않습니다 WITH NOCHECK. 이러한 제한은 ALTER TABLEtable 을 사용하여 다시 활성화 될 때까지 무시됩니다 WITH CHECK CHECK CONSTRAINT ALL.

...

{ CHECK | NOCHECK } CONSTRAINT
constraint_name이 활성화 또는 비활성화되도록 지정합니다. 이 옵션은 FOREIGN KEYCHECK제약 조건 과 함께 만 사용할 수 있습니다 . 때 NOCHECK지정된 제약 조건이 비활성화되고 열 미래 삽입 또는 업데이트가 제약 조건에 대해 검증되지 않습니다. DEFAULT, PRIMARY KEYUNIQUE제약 조건을 비활성화 할 수 없습니다.

dbfiddle 에서 테스트 :

CREATE TABLE a (aid INT PRIMARY KEY);

가다

INSERT INTO a (aid)
VALUES (1), (2), (3) ;

가다

영향을받는 3 개의 행
CREATE TABLE b 
( aid INT,
  bid INT PRIMARY KEY,
  CONSTRAINT [My_FORIEGN_KEY]
    FOREIGN KEY (aid) REFERENCES a (aid)
) ;

가다

INSERT INTO b (aid, bid)
VALUES
  (1, 11),
  (1, 12),
  (2, 21), 
  (3, 31) ;

가다

4 행 영향을 받음
INSERT INTO b (aid, bid)
VALUES
  (6, 61),
  (6, 62) ;

가다

메시지 547 수준 16 상태 0 줄 1
INSERT 문이 FOREIGN KEY 제한 조건 "My_FORIEGN_KEY"과 충돌했습니다. 데이터베이스 "fiddle_792fce5de09f42908c3a0f91421f3522", 테이블 "dbo.a", 열 'aid'에서 충돌이 발생했습니다.
메시지 3621 수준 0 상태 0 줄 1
그 진술서는 만료되었습니다.
SELECT * FROM b ;

가다

원조 | 매기다
-: | -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
ALTER TABLE b NOCHECK CONSTRAINT [My_FORIEGN_KEY];   --disable

가다

INSERT INTO b (aid, bid)
VALUES
  (4, 41),
  (4, 42) ;

가다

영향을받는 2 개의 행
SELECT * FROM b ;

가다

원조 | 매기다
-: | -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
  4 | 41
  4 | 42
ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY];  
-- enable constraint without checking existing data

가다

SELECT * FROM b ;

가다

원조 | 매기다
-: | -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
  4 | 41
  4 | 42
INSERT INTO b (aid, bid)
VALUES
  (6, 61),
  (6, 62) ;

가다

메시지 547 수준 16 상태 0 줄 1
INSERT 문이 FOREIGN KEY 제한 조건 "My_FORIEGN_KEY"과 충돌했습니다. 데이터베이스 "fiddle_792fce5de09f42908c3a0f91421f3522", 테이블 "dbo.a", 열 'aid'에서 충돌이 발생했습니다.
메시지 3621 수준 0 상태 0 줄 1
그 진술서는 만료되었습니다.
SELECT * FROM b ;

가다

원조 | 매기다
-: | -:
  1 | 11
  1 | 12
  2 | 21
  3 | 31
  4 | 41
  4 | 42
ALTER TABLE b WITH CHECK CHECK CONSTRAINT [My_FORIEGN_KEY];  
-- check existing data and enable constraint 

가다

메시지 547 수준 16 상태 0 줄 1
ALTER TABLE 문이 FOREIGN KEY 제한 조건 "My_FORIEGN_KEY"과 충돌했습니다. 데이터베이스 "fiddle_792fce5de09f42908c3a0f91421f3522", 테이블 "dbo.a", 열 'aid'에서 충돌이 발생했습니다.

1
감사. Wrt ALTER TABLE b WITH NOCHECK CHECK CONSTRAINT [My_FORIEGN_KEY]; -- enable constraint without checking, 이것은 제약 조건이 기존 데이터를 검사하지 않고 새로운 수신 데이터 만 검사한다는 것을 의미합니까?
BanksySan

1
바로 그거죠. 다음 인서트 (aid = 6)가 허용되지 않지만 기존 행 (aid = 4)이 여전히 어떻게 존재하는지 확인하십시오.
ypercubeᵀᴹ

그것은 그것을 완벽하게 보여줍니다.
BanksySan

1

https://msdn.microsoft.com/en-us/library/ms190273.aspx 에서 기사를 읽으십시오.

'쿼리 옵티마이 저는 WITH NOCHECK로 정의 된 제약 조건을 고려하지 않습니다. 이러한 제한 조건은 ALTER TABLE 테이블 WITH CHECK CHECK CONSTRAINT ALL '을 사용하여 다시 사용 가능할 때까지 무시됩니다.

또한 StackOverflow의 스레드를 고려 하십시오 : https : //.com/questions/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.