如何避免因1 NULL而导致整个INSERT批处理失败

时间:2012-02-15 22:32:11

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

我有一个表,其中包含一个主键和一个用于插入该表的存储过程。我无法控制存储过程,无法更改它。有时,该过程返回许多记录和1个记录,主键列的值为NULL。目前,整批新行无法插入。

如何将我的代码或表配置为仅在具有NULL值的1行上失败,但允许插入其他行?

以下是一些测试代码:

    IF OBJECT_ID('tempdb..#tbl') IS NOT NULL
     DROP TABLE #tbl

    CREATE TABLE #tbl (
     col INT NOT NULL,
     CONSTRAINT PK_tbl PRIMARY KEY (col ASC)
     WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE  = OFF,
     IGNORE_DUP_KEY = ON, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)
    )

    SET XACT_ABORT OFF

    --Imagine this is the procedure that cannot be edited
    insert into #tbl (col) values 
    (null), (1), (2)

    --Ideally, the table would have 1 and 2
    select * from #tbl

2 个答案:

答案 0 :(得分:4)

假设我们没有真正谈论#temporary表,你可以创建一个而不是插入触发器。

CREATE TRIGGER dbo.PreventNullsOnTableName
ON dbo.TableName
INSTEAD OF INSERT
AS
BEGIN
    SET NOCOUNT ON;

    INSERT dbo.TableName SELECT col1 FROM inserted WHERE col1 IS NOT NULL;
END
GO

您可能还希望使用GROUP BY col1来防止违反PK,但这取决于您是要优雅地处理还是引发错误。

您还可以删除NOT NULL约束,而不是PRIMARY KEY,而是创建唯一的过滤索引WHERE col1 IS NOT NULL

答案 1 :(得分:0)

在col INT上没有NOT NULL。它仍然可以是PK但它只允许一个null。然后你可以删除空行。

好吧我错了,PK不能为空。但是,您可以拥有一个null唯一的非聚集索引。它基本上是一个PK但不是聚集的。如果插入最多只有一个null,那么插入将成功,然后您可以删除1行为空。