2011-09-17 105 views
2

在之前的問題Problem with alter then update in try catch with tran using Transact-SQL中,我發現爲了讓SQL運行起來,我不得不將它分成兩批。這是SQL的:Transact-SQL - 如果第一批失敗,如何防止第二批運行?

USE PUK; 
GO 
BEGIN TRANSACTION; 
BEGIN TRY 

    -- - Modify RETRIEVAL_STAT 
    alter table dbo.RETRIEVAL_STAT add 
     SOURCE nvarchar(10) NULL, 
     ACCOUNTNUMBER nvarchar(50) NULL, 
     PUK nvarchar(20) NULL; 

END TRY 
BEGIN CATCH 
    SELECT 
     ERROR_NUMBER() AS ErrorNumber 
     ,ERROR_SEVERITY() AS ErrorSeverity 
     ,ERROR_STATE() AS ErrorState 
     ,ERROR_PROCEDURE() AS ErrorProcedure 
     ,ERROR_LINE() AS ErrorLine 
     ,ERROR_MESSAGE() AS ErrorMessage; 
    IF @@TRANCOUNT > 0 
     ROLLBACK TRANSACTION; 
END CATCH; 
IF @@TRANCOUNT > 0 
    COMMIT TRANSACTION; 
GO 


USE PUK; 
GO 
BEGIN TRANSACTION; 
BEGIN TRY 

    -- transform logic. 
    UPDATE  dbo.RETRIEVAL_STAT 
    SET   SOURCE = 'ABC', 
       ACCOUNTNUMBER = ABC.ACCOUNTNUMBER, 
       PUK = ABC.PUK 
    FROM  RETRIEVAL_STAT RS 
    INNER JOIN ABC 
    ON   RS.SERVICE_NUMBER = ABC.SERVICENUMBER; 

    --- ... snip 

END TRY 
BEGIN CATCH 
    SELECT 
     ERROR_NUMBER() AS ErrorNumber 
     ,ERROR_SEVERITY() AS ErrorSeverity 
     ,ERROR_STATE() AS ErrorState 
     ,ERROR_PROCEDURE() AS ErrorProcedure 
     ,ERROR_LINE() AS ErrorLine 
     ,ERROR_MESSAGE() AS ErrorMessage; 
    IF @@TRANCOUNT > 0 
     ROLLBACK TRANSACTION; 
END CATCH; 
IF @@TRANCOUNT > 0 
    COMMIT TRANSACTION; 
GO 

我現在的問題是:如果第一批次失敗,如何防止第二批次運行?

感謝您的任何建議!

羅布 :)

+1

可能重複[SQL服務器 - 停止或中斷一個SQL腳本的執行(http://stackoverflow.com/questions/659188/sql-server-stop-or-break-execution-of-a -sql-script) –

+0

@Martin Smith好的** ** raiserror('哦,沒有致命的錯誤',20,-1)和log **很好地完成了這項工作。謝謝。 –

+0

@Martin Smith再次想到,我仍然缺少一些信息:如何檢測錯誤情況?在上面的例子中,我試着改變alter table的名字,並把RAISERROR放入catch中。它沒有工作。它告訴我**無法找到對象「dbo.RETRIEVAL_SdTAT」,因爲它不存在或者您沒有權限。**並且愉快地繼續運行其餘的SQL。 –

回答

1

繼在您的評論的附加信息,您所遇到的問題是,因爲這不是一個開捕錯誤。

解析第一批失敗是由於一個不存在的對象導致整個批處理失敗(包括您的raiserror語句)。

給一個簡單的例子

SELECT * FROM NonExistentTable 

GO 

SELECT 1 AS [SecondBatch] 

返回

Msg 208, Level 16, State 1, Line 3 
Invalid object name 'NonExistentTable'. 


SecondBatch 
----------- 
1 

一對夫婦的解決此辦法將是把每個批次到子範圍使用動態SQL

BEGIN TRY 
EXEC('SELECT * FROM NonExistentTable') 
END TRY 
BEGIN CATCH 
RAISERROR('Oh no a fatal error', 20, -1) WITH LOG 
END CATCH 

EXEC('SELECT 1 AS [SecondBatch]') 

退貨

Msg 2745, Level 16, State 2, Line 5 
Process ID 55 has raised user error 50000, severity 20. SQL Server is terminating this process. 
Msg 50000, Level 20, State 1, Line 5 
Oh no a fatal error 
Msg 0, Level 20, State 0, Line 0 
A severe error occurred on the current command. The results, if any, should be discarded. 

或者(因爲批次之間的變量將超出範圍),您可以在每個批次結束時使用SET CONTEXT_INFO,然後在下一批次開始時檢查該數據。

BEGIN TRY 
SELECT * FROM NonExistentTable 
SET CONTEXT_INFO 1 
END TRY 
BEGIN CATCH 

END CATCH 
GO 
IF CONTEXT_INFO() <> 1 
    RETURN 

BEGIN TRY 
SELECT 1 AS [SecondBatch] 
SET CONTEXT_INFO 2 
END TRY 
BEGIN CATCH 
END CATCH 


GO 

IF CONTEXT_INFO() <> 2 
    RETURN 

BEGIN TRY 
SELECT 1 AS [ThirdBatch] 
SET CONTEXT_INFO 3 
END TRY 
BEGIN CATCH 
END CATCH 
+0

「不是一個可捕捉的錯誤」 - 是因爲它打破了編譯?什麼定義了可捕獲的錯誤?我認爲@Mikael Eriksson提供了一個簡單的建議::在出錯時退出 –

+0

請參見[不受TRY ... CATCH構造影響的錯誤](http://msdn.microsoft.com/zh-cn/library/ms175976.aspx) –

相關問題