2010-12-03 3 views
7

아래의 SQL 문은 중첩 된 세부 정보로 예외를 throw하는 일부 SQL의 좋은 예입니다. 내가 외부 예외 세부 사항 Could not create constraint. See previous errors만을 얻을 수 있다는 진술의 캐치 부분에있는 것 같습니다 (별로 유용하지는 않습니다!). 사이클 또는 여러 개의 계단식 경로를 일으킬 수 FOREIGN KEY 제약 'FK_TWO'테이블 'TABLE2'에 소개SQL Server try-catch 내부 예외 메시지 수수께끼

: 내가 얻고 싶은 것은 내부 예외 메시지입니다. ON DELETE NO ACTION 또는 ON UPDATE NO ACTION을 지정하거나 다른 FOREIGN KEY 제약 조건을 수정하십시오 (try-catch없이 코드를 실행하여 이 메시지를받을 수 있음).

Catch 블록에서 T-SQL을 어떻게 구현할 수 있습니까?

BEGIN TRY 
     BEGIN TRAN; 

     CREATE TABLE TABLE1 (USER_ID INTEGER NOT NULL PRIMARY KEY, USER_NAME 
      CHAR(50) NOT NULL); 

     CREATE TABLE TABLE2 (AUTHOR_ID INTEGER NOT NULL PRIMARY KEY, AUTHOR_NAME 
      CHAR(50) NOT NULL, LASTMODIFIEDBY INTEGER NOT NULL, ADDEDBY INTEGER NOT 
      NULL); 

     ALTER TABLE TABLE2 ADD CONSTRAINT FK_ONE FOREIGN KEY (LASTMODIFIEDBY) 
      REFERENCES TABLE1 (USER_ID) ON DELETE CASCADE ON UPDATE CASCADE; 

     ALTER TABLE TABLE2 ADD CONSTRAINT FK_TWO FOREIGN KEY (ADDEDBY) 
      REFERENCES TABLE1(USER_ID) ON DELETE NO ACTION ON UPDATE CASCADE; 

     COMMIT TRAN; 
END TRY 
BEGIN CATCH 

     DECLARE @ERROR_MSG NVARCHAR(MAX), @SEVERITY INT, @STATE INT 
     SELECT @SEVERITY = ERROR_SEVERITY(), @STATE = ERROR_STATE() 
      , @ERROR_MSG = ERROR_MESSAGE() + ' err src line: ' + CAST(ERROR_LINE() AS NVARCHAR(20)) + ' ' + ISNULL(ERROR_PROCEDURE(), ''); 

     ROLLBACK; 
     -- RE-THROW EXCEPTION FOR DIAGNOSTIC VISIBILITY 
     RAISERROR (@ERROR_MSG ,@SEVERITY, @STATE); 
END CATCH; 

[편집]

그래서 그 후 많은이 문제에 대한 해결책이 없다는 것을 검색하는 것 같다. 잘만되면 그들은 미래 버전에서 이것을 고칠 것이다.

+1

나는 이것을 할 방법이 없다고 생각합니다. 관련 질문 : [단일 명령문에서 여러 오류 메시지 캡처] (http://stackoverflow.com/questions/3697492/capturing-multiple-error-messages-from-a-single-statement) –

답변

0

지금이 문제에 대한 해결책은 없습니다. this에 따르면 SQL Server의 다음 버전의 솔루션은 두 가지 오류를 모두 다시 제기하는 새 throw 키워드를 사용합니다.

+0

[있을 수 있음 만약 당신이 출력 버퍼를 구문 분석하는 방법에 대해 혼란스러워한다면 솔루션입니다!] (http://stackoverflow.com/questions/3697492/capturing-multiple-error-messages-from-a-single-statement/5773071) # 5773071) –

9

원본 오류는 다시 throw 할 수 없습니다. 캡처 된 오류 메시지가 포함 된 오류 번호가 50000 이상인 새 오류 오류를 던져야합니다. 예제 Exception handling and nested transactions를 참조하십시오 : 나는 연결

begin catch 
    declare @error int, @message varchar(4000), @xstate int; 
    select @error = ERROR_NUMBER() 
     , @message = ERROR_MESSAGE(); 
raiserror ('Caught exception: %d: %s', 16, 1, @error, @message) ; 
return; 
end catch 

이 기사는보다 철저한 예를 들어,도 필수 XACT_STATE() 검사를 덮고 트랜잭션 의미와 시도/catch 블록을 혼합 있습니다.

throw; (임의의 인수 없음)을 발행 할 수 있으므로 다음 버전 ("Denali")에서는 다른 try/catch 언어와 마찬가지로 원래 예외가 발생합니다. TRY CATCH THROW: Error handling changes in T-SQL

가 D' 오, 나는 종류의 대각선의 게시물을 읽을

업데이트를 참조하십시오. 더 많은 예외가 발생하면 하나만 잡을 수 있습니다. 데날리 역시 그렇습니다. 하지만 대부분의 예외는 심각도 0 (예외가 아니라 실제로 인쇄됨을 의미)이며 클라이언트는 여전히 정보 메시지 (SqlConnection.InfoMessage 이벤트)로 클라이언트에 전달합니다.