2

내가 가지고 bit 열 그 플래그가 설정되었을 때 추적하는 해당 datetime2 열이있는 테이블에 다음과 같이체크 제약 조건 위반

CREATE TABLE MyTable 
(
    Id int primary key identity, 
    Processed bit not null, 
    DateTimeProcessed datetime2 
) 

내가 점검 제한 조건을 추가 한을 :

:
ALTER TABLE MyTable 
    ADD CHECK ((Processed = 0 AND DateTimeProcessed IS NULL) 
      OR (Processed = 1 AND DateTimeProcessed IS NOT NULL)) 

는 I은 AFTER UPDATE 트리거를 사용 DateTimeProcessed 열의 설정을 제어하려고

AFTER UPDATE 트리거가 실행되기 전에 검사 제한 조건이 적용되므로 Processed 열이 업데이트되면 제약 조건이 위반됩니다.

여기서 내가하려고하는 것을 달성하는 가장 좋은 방법은 무엇입니까?

답변

2

이제 CREATE TABLE에 대한 MSDN 페이지에 따라 : 테이블이 FOREIGN KEY가 있거나 CONSTRAINTS 및 트리거를 확인

경우 트리거가 실행되기 전에, 제약 조건이 평가됩니다.

이렇게하면 "INSTEAD OF"트리거를 사용할 가능성이 배제됩니다.

  • 이미 날짜 필드가에 설정되고 있음을 확인하고 있습니다 : 트리거 이후 자체가 규칙의 동일한 적용을 제공 할 수 있기 때문에

    당신은 궁극적으로 필요하지 않습니다으로 점검 제한 조건을 제거해야합니다 BIT 필드가 1로 설정되어 있습니다.

  • CASE 문은 이미 날짜 필드를 NULL로 설정하여 BIT 필드를 0으로 처리하고 있습니다.
  • IF UPDATE(DateTimeProcessed)을 확인하고 DELETED 테이블의 내용으로 되돌 리거나 오류를 던질 수 있습니다.

    • 원래 값으로 다시 업데이트하는 경우 재귀 호출을 테스트하고 재귀 호출 인 경우 종료해야 할 수 있습니다.
    • 당신이 오류가 발생 단지의 라인을 따라 뭔가 사용하려는 경우 : UPDATE() 기능은 필드가 UPDATE 문에 나타냅니다 것을 명심

      IF(UPDATE(DateTimeProcessed)) 
      BEGIN 
          RAISERROR('Update of [DateTimeProcessed] field is not allowed.', 16, 1); 
          ROLLBACK; -- cancel the UPDATE statement 
          RETURN; 
      END; 
      

      을; 이 아니며 값이 변경되었다는 표시가이 아닙니다. 따라서 SET DateTimeProcessed = DateTimeProcessed의 업데이트를 수행하면 분명히 값이 변경되지 않지만 UPDATE(DateTimeProcessed)은 "true"를 반환합니다.

    • 또한 열 수준 DENY 사용하여 트리거의 "규칙"외부의이 부분을 처리 할 수 ​​

      :

      DENY UPDATE ON MyTable (DateTimeProcessed) TO {User and/or Role};

+1

"주석 제안"전을 "트리거는 SQL Server가"BEFORE "트리거가 없기 때문에 아마도 삭제되었습니다. ... 예, 아마도 그 이유가 될 것입니다. :) – grin0048

+0

해답을 보내 주셔서 감사합니다. 'DateTimeProcessed'가 직접 업데이트되면 에러를 던지는 것은 여기에 추가 할 마지막 부분처럼 보입니다. – grin0048

+0

@ grin0048 : 예, 나는 그 시나리오에서 오류를 던지라고 제안 했습니까, 그것이 당신이 말하는 내용입니까, 아니면 내 업데이트를 보지 못했습니까? 그럼에도 불구하고 글 머리 기호의 순서를 다시 정렬하고 오류 및 취소를 처리하는 코드 및 코드와 관련이없는 새로운 (알려진 적은) 옵션과 같은 세부 정보를 추가했습니다. –

관련 문제