我正在尝试使用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(默认值)而不是','?
答案 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。
我认为解决方案之一是完美的。