INSERT失败后如何继续执行当前块?

时间:2011-11-25 20:24:02

标签: sql-server-2008 tsql sql-server-2008-r2

考虑下表:

CREATE TABLE [dbo].[OrderingTest](
    [ColKey] [int] IDENTITY(1,1) NOT NULL,
    [Col0] [int] NULL,
    [Col1] [int] NOT NULL,
    [Col2] [int] NOT NULL
) ON [PRIMARY]

......以及以下批次:

BEGIN
  INSERT INTO OrderingTest(Col0,Col1,Col2)
  VALUES (1,NULL,3);

  SELECT SCOPE_IDENTITY();
END;

Test表在Col1中不允许NULL值,因此插入将失败。我希望在此时使用SCOPE_IDENTITY()的值测试失败。但是,不是看到SELECT SCOPE_IDENTITY()生成带有NULL列的单行作为输出,而是在失败的插入后终止执行批处理并且永远不会执行SELECT SCOPE_IDENTITY()行。

更新

我错误地在“结果”窗格中显示SCOPE_IDENTITY()的结果。我很困惑,因为SSMS将“消息”窗格切换为焦点而不是“结果”窗格(因为发生了错误)。

但是,在ColKey失败后,会显示标识列NULL的最新值,而不是INSERT。我认为如果SCOPE_IDENTITY()失败,INSERT应该返回NULL。

1 个答案:

答案 0 :(得分:1)

我尝试了这些命令:

BEGIN   
    DECLARE @theKey INT
    BEGIN TRY
        INSERT INTO OrderingTest(Col0,Col1,Col2)   
        VALUES (1,NULL,3);    
        SELECT @theKey = SCOPE_IDENTITY();      
    END TRY
    BEGIN CATCH
         SET @theKey = - 1
    END CATCH
    select @theKey
END; 

以下

BEGIN   
    DECLARE @theKey INT
    SET @theKey = 1
        INSERT INTO OrderingTest(Col0,Col1,Col2)   
        VALUES (1,NULL,3);    
        SELECT @theKey = SCOPE_IDENTITY();      
    select @theKey

END; 

在这两种情况下,SELECT @theKey都已执行,但在第二个示例中,错误消息显示在打印窗口中。请注意,在您的示例中,您尝试插入TEST表而不是OrderingTest表。这将产生错误而不运行SELECT。你确定你的例子是对的吗?

请注意,在此示例中,SCOPE_IDENTITY返回上次成功INSERT的标识,而不是NULL

BEGIN   
INSERT INTO OrderingTest(Col0,Col1,Col2)   VALUES (1,2,3);    

INSERT INTO OrderingTest(Col0,Col1,Col2)   VALUES (1,NULL,3);    
SELECT SCOPE_IDENTITY(); 
END;