BULK INSERT为empy字段插入分隔符而不是默认的NULL值

时间:2017-02-13 11:28:31

标签: sql-server bulkinsert

我正在尝试使用BULK INSERT插入一些行:

CREATE TABLE Foo (
  Id UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT newsequentialid(),
  Name NVARCHAR(255) NULL,
  CreatedOn DATETIME NOT NULL DEFAULT GETDATE(),
  CreatedBy NVARCHAR(255) NOT NULL DEFAULT SUSER_NAME(),
  ModifiedOn DATETIME NULL DEFAULT NULL,
  ModifiedBy NVARCHAR(255) NULL DEFAULT NULL
);

我从具有UTF8编码的CSV文件,用于分隔符的逗号和用于行结尾的LF插入:

 ,Fizz,,,,,

My BULK INSERT语句如下所示:

BULK INSERT Foo 
FROM 'C:\foo.csv' 
WITH (CODEPAGE = '65001', FIELDTERMINATOR = ',' , ROWTERMINATOR = '0x0a');

但插入行的最后一个字段(ModifiedBy)的值为','(逗号分隔符:

49625A3B-DCF1-E611-8D73-B00594F7CD91    Fizz    2017-02-13 12:04:48.223 sa  NULL    ,

我做错了什么,如何让BULK INSERT将最后一个字段插入为NULL(默认值)而不是','?

3 个答案:

答案 0 :(得分:2)

在分配其他列之后,表的最后一列接收输入行中的所有剩余数据,显然没有解析。如果你在输入行中放入100个逗号,你将在导入表的最后一列中获得95个逗号(我通过快速测试验证了这一点)。正如Marcus所指出的那样,你必须有5个分隔符才能进行6列布局。

如果您无法从输入文件中删除额外字段,则可以使用格式文件进行列映射,以排除上面列出的最后一列:https://msdn.microsoft.com/en-us/library/ms187908.aspx

如果您的输入文件确实用于6列,并且最后一个分隔符按惯例存在,即“每列之后有一个分隔符”而不是“列之间的分隔符”,那么@ SqlZim的解决方案应该可以正常工作大多。但是,你必须确保在一行中的最后一个分隔符之后没有添加空格等(例如手动编辑时),否则该行的导入将失败,因为它与行分隔符不匹配。所以,为了更加万无一失,我再次建议使用列映射方法,为最后一个分隔符添加一个虚拟字段定义,并在导入过程中跳过它。

看起来Sql server希望灵活或选择不丢失孤立数据,但会造成更多混乱而不是帮助。

答案 1 :(得分:1)

算一下逗号......

Foo表有六个列,而给定的输入有七个位置。

最后一个逗号被假定为ModifiedBy列的值。

Id <强>, NAME <强>, CreatedOn <强>, CreatedBy ModifiedOn <强>, ModifiedBy 下,?

带有七个逗号的输入,Fizz,,,,,,将为,,呈现ModifiedBy

答案 2 :(得分:0)

我想,你几乎没有选择。

i)更改批量插入方法,而是使用OPENROWSET或OPENQUERY.IT允许您提及列名。示例链接,

https://www.mssqltips.com/sqlservertip/1207/different-options-for-importing-data-into-sql-server/

ii)如果你不接受i),你可以在表格上定义“After insert”触发器,你可以再次将modifiedDate更新为null。

我认为解决方案之一是完美的。