복붙노트

[SQL] 체크 ADD와 함께 제약 조건 CHECK 제약 대를 추가 CONSTRAINT 다음

SQL

체크 ADD와 함께 제약 조건 CHECK 제약 대를 추가 CONSTRAINT 다음

나는 SQL 서버 2008에서는 AdventureWorks 샘플 데이터베이스에서 찾고 있어요, 그리고 나는 그들이 다음을 사용하는 경향이 그들의 작성 스크립트에서 참조 :

ALTER TABLE [Production].[ProductCostHistory] WITH CHECK ADD 
CONSTRAINT [FK_ProductCostHistory_Product_ProductID] FOREIGN KEY([ProductID])
  REFERENCES [Production].[Product] ([ProductID])
GO

바로 다음 :

ALTER TABLE [Production].[ProductCostHistory] CHECK CONSTRAINT     
[FK_ProductCostHistory_Product_ProductID]
GO

나는 외래 키 (등 여기), 고유 제한 및 일반 CHECK 제약 조건이 참조; DEFAULT 제약 내가 같은 더 잘 알고 정규 형식을 사용합니다 :

ALTER TABLE [Production].[ProductCostHistory] ADD  CONSTRAINT  
[DF_ProductCostHistory_ModifiedDate]  DEFAULT (getdate()) FOR [ModifiedDate]
GO

그것을 두 번째 대 첫 번째 방법을 수행 차이가있는 경우, 무엇입니까?

해결법

  1. ==============================

    1.첫 번째 구문은 중복 - CHECK에 WITH 새로운 제약 조건의 기본이며, 제약도 기본적으로 설정되어 있습니다.

    첫 번째 구문은 중복 - CHECK에 WITH 새로운 제약 조건의 기본이며, 제약도 기본적으로 설정되어 있습니다.

    SQL 스크립트를 생성 할 때이 구문은 SQL 관리 스튜디오에 의해 생성 - 나는 그것이 가능성이 제약 조건이 테이블의 기본 제약 조건 동작이 변경되는 경우에도 사용할 수 있도록 여분의 중복의 일종입니다 있으리라 믿고있어.

  2. ==============================

    2.방법이 works--을 설명하기 위해

    방법이 works--을 설명하기 위해

    CREATE TABLE T1 (ID INT NOT NULL, SomeVal CHAR(1));
    ALTER TABLE T1 ADD CONSTRAINT [PK_ID] PRIMARY KEY CLUSTERED (ID);
    
    CREATE TABLE T2 (FKID INT, SomeOtherVal CHAR(2));
    
    INSERT T1 (ID, SomeVal) SELECT 1, 'A';
    INSERT T1 (ID, SomeVal) SELECT 2, 'B';
    
    INSERT T2 (FKID, SomeOtherVal) SELECT 1, 'A1';
    INSERT T2 (FKID, SomeOtherVal) SELECT 1, 'A2';
    INSERT T2 (FKID, SomeOtherVal) SELECT 2, 'B1';
    INSERT T2 (FKID, SomeOtherVal) SELECT 2, 'B2';
    INSERT T2 (FKID, SomeOtherVal) SELECT 3, 'C1';  --orphan
    INSERT T2 (FKID, SomeOtherVal) SELECT 3, 'C2';  --orphan
    
    --Add the FK CONSTRAINT will fail because of existing orphaned records
    ALTER TABLE T2 ADD CONSTRAINT FK_T2_T1 FOREIGN KEY (FKID) REFERENCES T1 (ID);   --fails
    
    --Same as ADD above, but explicitly states the intent to CHECK the FK values before creating the CONSTRAINT
    ALTER TABLE T2 WITH CHECK ADD CONSTRAINT FK_T2_T1 FOREIGN KEY (FKID) REFERENCES T1 (ID);    --fails
    
    --Add the CONSTRAINT without checking existing values
    ALTER TABLE T2 WITH NOCHECK ADD CONSTRAINT FK_T2_T1 FOREIGN KEY (FKID) REFERENCES T1 (ID);  --succeeds
    ALTER TABLE T2 CHECK CONSTRAINT FK_T2_T1;   --succeeds since the CONSTRAINT is attributed as NOCHECK
    
    --Attempt to enable CONSTRAINT fails due to orphans
    ALTER TABLE T2 WITH CHECK CHECK CONSTRAINT FK_T2_T1;    --fails
    
    --Remove orphans
    DELETE FROM T2 WHERE FKID NOT IN (SELECT ID FROM T1);
    
    --Enabling the CONSTRAINT succeeds
    ALTER TABLE T2 WITH CHECK CHECK CONSTRAINT FK_T2_T1;    --succeeds; orphans removed
    
    --Clean up
    DROP TABLE T2;
    DROP TABLE T1;
    
  3. ==============================

    3.또한 신뢰할 수있는 제약 조건에 대한 위의 우수한 의견 :

    또한 신뢰할 수있는 제약 조건에 대한 위의 우수한 의견 :

    select * from sys.foreign_keys where is_not_trusted = 1 ;
    select * from sys.check_constraints where is_not_trusted = 1 ;
    

    신뢰할 수없는 제약 조건은, 이름에서 알만큼 정확하게 지금 테이블의 데이터의 상태를 표현하기 위해 신뢰할 수 없습니다. 그러나, 그러나 향후에 추가 및 수정 된 데이터를 확인하기 위해 신뢰할 수 있습니다.

    또한, 신뢰할 수없는 제약 조건은 쿼리 최적화에 의해 무시된다.

    점검 제한 조건 및 외부 키 제한 조건을 사용하는 코드는 단어 "검사"의 세 가지 의미로, 매우 나쁘다.

    ALTER TABLE [Production].[ProductCostHistory] 
    WITH CHECK -- This means "Check the existing data in the table".
    CHECK CONSTRAINT -- This means "enable the check or foreign key constraint".
    [FK_ProductCostHistory_Product_ProductID] -- The name of the check or foreign key constraint, or "ALL".
    
  4. ==============================

    4.WITH NOCHECK 정의하고 당신이 당신이 구현하고있는 새로운 제약의 충돌하여 실행하지 않는 한 제약 조건을 준수하지 않는 테이블의 잘 하나가 기존 않은 데이터로 사용됩니다 ...

    WITH NOCHECK 정의하고 당신이 당신이 구현하고있는 새로운 제약의 충돌하여 실행하지 않는 한 제약 조건을 준수하지 않는 테이블의 잘 하나가 기존 않은 데이터로 사용됩니다 ...

  5. ==============================

    5.함께 점검은 당신의 코딩 내에 포함하는 것이 좋습니다 그러나 실제로 기본 동작입니다.

    함께 점검은 당신의 코딩 내에 포함하는 것이 좋습니다 그러나 실제로 기본 동작입니다.

    명시 적으로 의도를 정의하는 것이 좋은 그래서 대안 동작은, WITH NOCHECK를 사용하는 과정이다. 당신은 / 수정 / 전환 인라인 파티션을 재생하는 경우에 자주 사용된다.

  6. ==============================

    6.외래 키와 체크 제약 조건은 신뢰할 수 없거나 신뢰할 수없는뿐만 아니라 활성화 및 비활성화되는 존재의 개념이있다. 자세한 내용에 대한 ALTER 테이블에 대한 MSDN 페이지를 참조하십시오.

    외래 키와 체크 제약 조건은 신뢰할 수 없거나 신뢰할 수없는뿐만 아니라 활성화 및 비활성화되는 존재의 개념이있다. 자세한 내용에 대한 ALTER 테이블에 대한 MSDN 페이지를 참조하십시오.

    CHECK 새로운 외래 키와 체크 제약 조건을 추가하는 기본값으로, WITH NOCHECK 재 활성화 장애인 외래 키의 기본이며 제약 조건을 확인합니다. 이 차이를 인식하는 것이 중요합니다.

    그런 말을하는 데, 유틸리티에 의해 생성 된 분명히 중복 문은 안전 및 / 또는 코딩의 편의를 위해 단순히있다. 그들에 대해 걱정하지 마십시오.

  7. ==============================

    7.여기에 내가 데이터베이스에 우리가 식별하고 올바른 신뢰할 수없는 제약으로 쓴 일부 코드입니다. 그것은 각각의 문제를 해결하기 위해 코드를 생성합니다.

    여기에 내가 데이터베이스에 우리가 식별하고 올바른 신뢰할 수없는 제약으로 쓴 일부 코드입니다. 그것은 각각의 문제를 해결하기 위해 코드를 생성합니다.

        ;WITH Untrusted (ConstraintType, ConstraintName, ConstraintTable, ParentTable, IsDisabled, IsNotForReplication, IsNotTrusted, RowIndex) AS
    (
        SELECT 
            'Untrusted FOREIGN KEY' AS FKType
            , fk.name AS FKName
            , OBJECT_NAME( fk.parent_object_id) AS FKTableName
            , OBJECT_NAME( fk.referenced_object_id) AS PKTableName 
            , fk.is_disabled
            , fk.is_not_for_replication
            , fk.is_not_trusted
            , ROW_NUMBER() OVER (ORDER BY OBJECT_NAME( fk.parent_object_id), OBJECT_NAME( fk.referenced_object_id), fk.name) AS RowIndex
        FROM 
            sys.foreign_keys fk 
        WHERE 
            is_ms_shipped = 0 
            AND fk.is_not_trusted = 1       
    
        UNION ALL
    
        SELECT 
            'Untrusted CHECK' AS KType
            , cc.name AS CKName
            , OBJECT_NAME( cc.parent_object_id) AS CKTableName
            , NULL AS ParentTable
            , cc.is_disabled
            , cc.is_not_for_replication
            , cc.is_not_trusted
            , ROW_NUMBER() OVER (ORDER BY OBJECT_NAME( cc.parent_object_id), cc.name) AS RowIndex
        FROM 
            sys.check_constraints cc 
        WHERE 
            cc.is_ms_shipped = 0
            AND cc.is_not_trusted = 1
    
    )
    SELECT 
        u.ConstraintType
        , u.ConstraintName
        , u.ConstraintTable
        , u.ParentTable
        , u.IsDisabled
        , u.IsNotForReplication
        , u.IsNotTrusted
        , u.RowIndex
        , 'RAISERROR( ''Now CHECKing {%i of %i)--> %s ON TABLE %s'', 0, 1' 
            + ', ' + CAST( u.RowIndex AS VARCHAR(64))
            + ', ' + CAST( x.CommandCount AS VARCHAR(64))
            + ', ' + '''' + QUOTENAME( u.ConstraintName) + '''' 
            + ', ' + '''' + QUOTENAME( u.ConstraintTable) + '''' 
            + ') WITH NOWAIT;'
        + 'ALTER TABLE ' + QUOTENAME( u.ConstraintTable) + ' WITH CHECK CHECK CONSTRAINT ' + QUOTENAME( u.ConstraintName) + ';' AS FIX_SQL
    FROM Untrusted u
    CROSS APPLY (SELECT COUNT(*) AS CommandCount FROM Untrusted WHERE ConstraintType = u.ConstraintType) x
    ORDER BY ConstraintType, ConstraintTable, ParentTable;
    
  8. from https://stackoverflow.com/questions/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint by cc-by-sa and MIT license