2013-02-26 3 views
2

오류를 올바르게 기록하지 않는 것으로 보이는 저장 프로 시저가 있습니다.TSQL 시도 및 캐치 catch하지 않음

코드에 오류가 있지만 catch 블록이 적용되지 않는 것 같습니다.

try 블록은 상당히 길지만 오류 섹션은 간단하고 끝까지 올 수 있습니다. 그래서 나는 그것을 precis'd했습니다. proc 디렉토리가 실패

BEGIN TRY 
insert into tbl_X 
select * from #temp_tbl_Y 

RETURN 1 
END TRY 

BEGIN CATCH 
    Insert Into ExtractsErrorLog 
    SELECT 
    getdate() as ErrorDate 
    ,object_name(@@procid) as ProcedureName 
    ,ERROR_NUMBER() as ErrorNumber 
    ,ERROR_LINE() as ErrorLine 
    ,ERROR_MESSAGE() as ErrorMessage 
    ; 
DECLARE @errormessage as varchar(max); 
DECLARE @errorseverity as int; 
DECLARE @errorstate as int; 

set @errormessage = ERROR_MESSAGE(); 
set @errorseverity = ERROR_SEVERITY(); 
set @errorstate = ERROR_STATE(); 

RAISERROR (@errormessage, 
      @errorseverity, 
      @errorstate 
       ); 


END CATCH; 

오류는 우리의 오랜 친구 이다 "열 이름이나 테이블 정의와 일치하지 않습니다 제공 값의 수." 나는 그 오류를 수정했다. - 그것은 어리석은 실수였다. 그러나 내 오류 로깅 프로세스가 작동하지 않는 것 같은데 왜 당황하고 있는가? No ExtractsErrorLog 테이블에 행이 삽입되지 않았다.

+2

그것은 컴파일시 에러입니다,이 참조 : http://stackoverflow.com/questions/7286667/sql-try-catch-statement-not-handling-error- sql-server-2008 –

+0

'ExtractsErrorLog' 테이블 정의를 게시 할 수 있습니까? – Lamak

+0

감사합니다 이반 - 그건 많은 의미가 있습니다 - 그리고 그 스레드는 해결 방법을 제공합니다. 그것을 놓쳐서 미안 하 고 재 게시. 그 catch가 컴파일을 잡지 못한다는 것을 읽었을 것입니다 - 그러나 이것은 컴파일 에러가 될 것이라고 꼬집지 않았습니다. 컴파일/재 컴파일 할 때 어떤 오류가 발생했는지 이해하기위한 안내서가 온라인에 있는지 알고있는 사람이 있습니까? 나는 이것이 왜 지금 하나가 될지를 알 수있다. 나는 테이블도 놓친다 고 생각한다. 그러나 나는 확신하고 싶다. 그리고 이것에 대한 세부 사항을 많이 찾지는 않았다. – DanBennett

답변

6

TSQL의 TRY...CATCH은이 오류를 catch하지 않습니다. 이 오류는 CATCH 블록에 의해 처리되지 않는 "컴파일/재 컴파일"유형 오류로 "동일한 수준의 실행"으로 분류됩니다. MSDN 가입일

:

  • 컴파일 그들이 TRY ... CATCH 구조체로서 실행 동일한 수준에서 발생할 때 다음 유형의 오류가 CATCH 블록에 의해 처리되지 않는

    실행중인 일괄 처리를 방지하는 구문 오류와 같은 오류. 컴파일 이후에 발생하는 같은 개체 이름 확인 오류와 같은 문 수준의 재 컴파일 동안 발생하는

  • 오류로 인해 지연된 이름 확인

의 ...

당신을 TRY ... CATCH를 사용하여 컴파일 중에 발생하는 오류를 처리 할 수 ​​있습니다. 또는 오류 발생을 실행하여 문 수준 재 컴파일코드는 TRY 블록 내의 별도 배치에 있습니다. 예를 들어, 저장 프로 시저에 코드를 삽입하거나 sp_executesql을 사용하여 동적 Transact-SQL 문을 실행하여 을 수행합니다. 이렇게하면 TRY ... CATCH가 오류 발생보다 높은 실행 수준에서 오류를 포착 할 수 있습니다. 예를 들어, 다음 코드는 객체 이름 확인 오류를 생성하는 프로 시저를 보여줍니다. TRY ... CATCH 구문을 포함하는 일괄 처리는 저장 프로 시저보다 높은 수준 에서 실행 중입니다. 수준이 낮은 에서 발생하는 오류가 발견되었습니다.

나는 스크립트가 실패 할 경우 트랜잭션을 ROLLBACKTRY...CATCH 내부 트랜잭션을 만드는 비슷한 문제로 달렸다. CATCH이 입력되지 않았기 때문에 트랜잭션 내부의 명령문에서 동일한 오류가 발생하여 트랜잭션이 절대로 닫히지 않았습니다.

MSDN 문서에서 언급했듯이 하나의 대안은 INSERT 문에서 저장 프로 시저를 만든 다음 try/catch 내부에서 호출하는 것입니다. sproc이 잘못되면 컴파일을 시도하는 동안 컴파일 오류가 발생합니다. 나중에 테이블 정의가 sproc을 무효로 변경하면 TRY...CATCH이 예외를 잡아냅니다.

모든 스크립트를 한 스크립트로 작성하려면 temporary stored procedure으로 만들 수 있지만 sprocs를 만드는 동안 컴파일 오류를 처리해야합니다. 그것은 꽤 아니지만, 그것을 작동합니다

-- Creating error sproc to re-use code 
CREATE PROCEDURE #HandleError AS 
    Insert Into ExtractsErrorLog 
    SELECT GETDATE() as ErrorDate 
      ,object_name(@@procid) as ProcedureName 
      ,ERROR_NUMBER() as ErrorNumber 
      ,ERROR_LINE() as ErrorLine 
      ,ERROR_MESSAGE() as ErrorMessage; 

    DECLARE @errormessage as varchar(max); 
    DECLARE @errorseverity as int; 
    DECLARE @errorstate as int; 

    set @errormessage = ERROR_MESSAGE(); 
    set @errorseverity = ERROR_SEVERITY(); 
    set @errorstate = ERROR_STATE(); 

    RAISERROR (@errormessage, 
       @errorseverity, 
       @errorstate); 
GO 

-- Create a stored procedure of our INSERT and catch any compilation errors 
CREATE PROCEDURE #TEST AS 
    insert into tbl_X 
    select * from #temp_tbl_Y 
GO 
IF (@@ERROR <> 0) BEGIN 
    exeC#HandleError 
    -- If there was an error creating the sprocs, don't continue to the next batch 
    RETURN 
END 

-- If compilation succeeded, then run the sproc 
BEGIN TRY 
    exeC#TEST 
    RETURN 
END TRY 
BEGIN CATCH 
    exeC#HandleError 
END CATCH; 
-1

"반환 값 : 쿼리 또는 프로 시저에서 무조건 종료됩니다. RETURN은 즉각적이고 완전하며 프로 시저, 배치 또는 명령문 블록을 종료 할 때 언제든지 사용할 수 있습니다."

+0

''RETURN'에 도달하지 않았습니다. ""열 이름이나 제공된 값의 개수가 테이블 정의와 일치하지 않습니다. "오류 ... –

+0

감사합니다. Russell - Michael에 동의하지만 상당히 공정합니다. 특정 반품에 도달하지 못했습니다. 이 모든 것에 도움을 주셔서 감사합니다. Ivan은 위의 답변을 가지고 있다고 생각합니다. – DanBennett