【问题标题】:How can I avoid failing an entire INSERT batch due to 1 NULL如何避免由于 1 NULL 而导致整个 INSERT 批次失败
【发布时间】:2012-03-07 08:01:20
【问题描述】:

我有一个带有主键的表和一个用于插入该表的存储过程。我无法控制存储过程,也无法更改它。有时,该过程会返回许多记录和 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

【问题讨论】:

  • 只是出于好奇,为什么不能改变程序?
  • 阅读一下。 stackoverflow.com/questions/728898/…。虽然远非辉煌......
  • 如果值为 null 以忽略这些行或默认为“有效”值,期望的结果是什么。

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


【解决方案1】:

在 col INT 上不要有 NOT NULL。它仍然可以是 PK,但它只允许一个空值。然后就可以删除空行了。

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

【讨论】:

  • 如果集合是values (null), (1), (null), (2)呢?
  • SQL Server 似乎根本不允许可为空的主键。
  • 我的建议是回退唯一约束(它确实允许 one NULL)。
  • 对不起,你是对的。我确实通过在 SQL Management Studio 中创建一个表来测试它,并且我有一个可以为空的 int 作为 PK。表保存没有错误,所以假设它花了。但它没有保存为可为空的。
  • 进行了更多测试,null 不能是 PK,但它可以是唯一的非集群。
【解决方案2】:

假设我们不是真的在谈论#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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    相关资源
    最近更新 更多