2014-12-04 69 views
0

我有一個ID爲smallint和Code varchar(5)字段的表,在代碼上有一個唯一鍵約束。 已經有一排「ABC」的代碼字段表爲什麼使用Throw自定義異常不執行下一條語句,而表約束異常呢它

我已經寫了下面的存儲過程中插入值,它

  ALTER Procedure [dbo].[Insert] 
       @Id smallint output, 
       @Code varchar(5) 
      AS 
      SET NOCOUNT OFF; 
      IF not EXISTS (select Code from SomeTable where Code like '%'[email protected] and Code <> @Code) 
      BEGIN 
       Insert into dbo.SomeTable (Code) values (@Code) 
      END 
      ELSE 
      BEGIN 
       Throw 50000,'Violation of UNIQUE KEY constraint. Cannot insert Code which is already a suffix of existing Code in table ''dbo.SomeTable''.',1 
      END 
      Select Id,Code from dbo.SomeTable where SomeTableCode = 'ABC' 

你可以看到我寫的自定義拋出異常,這應該代碼作爲任何現有代碼的後綴存在時被拋出。

當我測試使用下面的語句

DECLARE @return_value int, 
      @Id smallint 

    EXEC @return_value = [dbo].[Insert] 
      @Id = @Id OUTPUT, 
      @Code = N'ABC' 

我得到下面的異常插入重複碼:

Msg 2627, Level 14, State 1, Procedure Insert, Line 19 
    Violation of UNIQUE KEY constraint 'IX_SomeTable_1'. Cannot insert duplicate key in object 'dbo.SomeTable'. The duplicate key value is (ABC). 
    The statement has been terminated. 
    (1 row(s) affected) 

而且我可以看到在結果選項卡中的行(select語句執行)

但是,當我嘗試使用以下語句將代碼作爲後綴插入到表中的其他代碼中時:

DECLARE @return_value int, 
      @Id smallint 

    EXEC @return_value = [dbo].[Insert] 
      @Id = @Id OUTPUT, 
      @Code = N'BC' 

我得到以下錯誤,但Select語句沒有執行,我看不到結果選項卡中的行,爲什麼?

Msg 50000, Level 16, State 1, Procedure Insert, Line 24 
    Violation of UNIQUE KEY constraint. Cannot insert Code which is already a suffix of existing Code in table 'dbo.SomeTable'. 

回答

0

THROW on MSDN

如果一個try ... catch結構是不可用的,

您未使用的try/catch所以THROW停止存儲過程的會話結束執行。

一般來說,這payttern是不可靠的

  • 兩個併發會話既可以找到NOT EXISTS爲真,但只有一個插件能夠成功。使用合併
  • 拋出正顯示出「已存在或存在作爲後綴」,它實際上不是違反
  • 沒有的try/catch

編輯,使用類似

BEGIN TRY 
    MERGE into dbo.SomeTable 
    etc 

END TRY 
BEGIN CATCH 
    DECLARE @errmsg nvarchar(2000); 
    IF ERROR_NUMBER() = 2627 
     SET @errmsg = 'Already exists etc' 
    ELSE 
     SET @errmsg = ERROR_MESSAGE(); 
    THROW 50000, @errmsg, 1; 
END CATCH 
SELECT Id,Code from dbo.SomeTable where SomeTableCode = 'ABC'; 

並完全讀取Error Handling in SQL 2005 and Later

+0

我可以做出什麼改變來拋出異常以及執行下一條語句? – 2014-12-04 09:56:00

相關問題