当列不允许为null时,SQL Server批量插入引发null抛出错误

时间:2018-11-09 14:58:24

标签: sql-server bulkinsert

在SQL Server(我正在使用2016)中,有一个名为“大容量插入”的功能,可用于从平面文件插入记录。

当平面文件中的字段为空并且SQL Server中的字段未标记为允许空值时,大容量插入将在插入操作期间静默使用空字符串。

是否有一种方法可以覆盖此行为,所以当字段为null时,它将使用null而不是空字符串。并且因为该字段未设置为null,然后抛出错误?

我为什么要这个?好吧,因为字段默默地插入了一个空字符串值,而我不希望这样做。

注意:我严格是指使用BULK INSERT(不是bcp或任何其他方式)使用T-SQL

注意:我见过Keep Nulls or Use Default Values During Bulk Import (SQL Server),这是我在此文档中找不到的内容。如果您认为它确实包含了我要寻找的内容,请指出我所缺少的,而不是将我定向到该文档。谢谢。

注意:这是一个简单的示例(请注意,这不是我正在使用的表格,只是一个简单的示例,可以用来说明问题)

表定义:

CREATE TABLE [dbo].[TableOne](
    [Id] [int] NOT NULL,
    [Name] [varchar](10) NOT NULL
)

批量插入命令

BULK
  INSERT TableOne
      FROM 'R:\TableOne.txt'
            WITH(
                  DATAFILETYPE = 'widechar',
                  FIELDTERMINATOR = '\t',
                  ROWTERMINATOR = '\n'
                )

文件

1   

因此,在此示例中,基本上是:1 [Tab] [CRLF],其中第二列是name,它为空。

结果

enter image description here

1 个答案:

答案 0 :(得分:2)

您不能仅通过BULK INSERT来执行此操作-这种行为是documented,据我所知,没有选择可以更改任何内容:

  

当导入由NOT NULL定义的字符列时   约束,BULK INSERT在没有值时插入一个空白字符串   在文本文件中。

没有TREAT_BLANK_AS_NULL选项或类似选项可以帮助解决此问题。

我唯一想到的解决方案是添加约束并在CHECK_CONSTRAINTS中使用BULK INSERT。如果您不满意用此约束永久性地标记该列(因为其他情况可能有合法需要插入空值或它们已经存在?),可以暂时添加它:

ALTER TABLE TableOne WITH NOCHECK ADD CONSTRAINT CK_Name_NotEmpty CHECK ([Name] <> '');
BEGIN TRY
    BULK INSERT TableOne FROM 'C:\Temp\a.txt' WITH (
        DATAFILETYPE = 'widechar',
        FIELDTERMINATOR = '\t',
        ROWTERMINATOR = '\n',
        CHECK_CONSTRAINTS
    )
END TRY
BEGIN CATCH
    ALTER TABLE TableOne DROP CONSTRAINT CK_Name_NotEmpty;
    THROW;
END CATCH
ALTER TABLE TableOne DROP CONSTRAINT CK_Name_NotEmpty;

很显然,如果表是动态的,这会有点不舒服,您需要以这种方式处理许多列,否则您实际上负担不起检查约束。到那时,我建议使用适当的ETL解决方案,例如SSIS软件包。