带FIRSTROW参数的SQL大容量插入跳过以下行
我似乎不明白这是怎么发生的 以下是我试图批量插入SQL server 2005的文件的示例:带FIRSTROW参数的SQL大容量插入跳过以下行,sql,sql-server-2005,bulkinsert,Sql,Sql Server 2005,Bulkinsert,我似乎不明白这是怎么发生的 以下是我试图批量插入SQL server 2005的文件的示例: ***A NICE HEADER HERE*** 0000001234|SSNV|00013893-03JUN09 0000005678|ABCD|00013893-03JUN09 0000009112|0000|00013893-03JUN09 0000009112|0000|00013893-03JUN09 以下是我的批量插入语句: BULK INSERT sometable FROM 'E:\f
***A NICE HEADER HERE***
0000001234|SSNV|00013893-03JUN09
0000005678|ABCD|00013893-03JUN09
0000009112|0000|00013893-03JUN09
0000009112|0000|00013893-03JUN09
以下是我的批量插入语句:
BULK INSERT sometable
FROM 'E:\filefromabove.txt
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR= '|',
ROWTERMINATOR = '\n'
)
但是,出于某种原因,我能得到的唯一输出是:
0000005678|ABCD|00013893-03JUN09
0000009112|0000|00013893-03JUN09
0000009112|0000|00013893-03JUN09
第一条记录总是被跳过,除非我完全删除了头并且不使用FIRSTROW参数。这怎么可能
提前谢谢 是否可以检查标题是否与ROWTERMINATOR中指定的实际数据行具有相同的行尾 更新:发件人: FIRSTROW属性不适用 跳过列标题。跳过 大容量不支持标头 插入语句。跳过行时, SQL Server数据库引擎看起来 仅在现场终端,以及 不验证中的数据 跳过行的字段
我不认为使用大容量插入/BCP可以跳过不同格式的行 当我运行此命令时:
TRUNCATE TABLE so1029384
BULK INSERT so1029384
FROM 'C:\Data\test\so1029384.txt'
WITH
(
--FIRSTROW = 2,
FIELDTERMINATOR= '|',
ROWTERMINATOR = '\n'
)
SELECT * FROM so1029384
我得到:
col1 col2 col3
-------------------------------------------------- -------------------------------------------------- --------------------------------------------------
***A NICE HEADER HERE***
0000001234 SSNV 00013893-03JUN09
0000005678 ABCD 00013893-03JUN09
0000009112 0000 00013893-03JUN09
0000009112 0000 00013893-03JUN09
看起来它甚至在头数据中也需要“|”,因为它在第一列中读取到了“|”,在第一列中包含了一个换行符。显然,如果包含字段终止符参数,它希望每一行都必须有一个
您可以通过预处理步骤剥离该行。另一种可能是只选择完整的行,然后将它们排除在标题之外进行处理。或者使用一个可以处理这个问题的工具,比如SSIS。我发现最简单的方法是将整行内容读入一列,然后使用XML解析数据
IF (OBJECT_ID('tempdb..#data') IS NOT NULL) DROP TABLE #data
CREATE TABLE #data (data VARCHAR(MAX))
BULK INSERT #data FROM 'E:\filefromabove.txt' WITH (FIRSTROW = 2, ROWTERMINATOR = '\n')
IF (OBJECT_ID('tempdb..#dataXml') IS NOT NULL) DROP TABLE #dataXml
CREATE TABLE #dataXml (ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED, data XML)
INSERT #dataXml (data)
SELECT CAST('<r><d>' + REPLACE(data, '|', '</d><d>') + '</d></r>' AS XML)
FROM #data
SELECT d.data.value('(/r//d)[1]', 'varchar(max)') AS col1,
d.data.value('(/r//d)[2]', 'varchar(max)') AS col2,
d.data.value('(/r//d)[3]', 'varchar(max)') AS col3
FROM #dataXml d
考虑到BCP从非SQL数据源导入SQL Server后,某些数据可能会被破坏,我建议首先将所有BCP导入到一些临时表中 比如说 截断表地址\u导入\u tbl 批量插入dbo.Address\u Import\u tbl 来自“E:\external\SomeDataSource\Address.csv” 具有 FIELDTERMINATOR='|',ROWTERMINATOR='\n',MAXERRORS=10 确保Address_Import_tbl中的所有列都是nvarchar,以使其尽可能不可知,并避免类型转换错误 然后应用您需要的任何修复来解决导入问题。比如删除不需要的标题 然后运行INSERT SELECT查询,从地址\u导入\u tbl复制到地址\u tbl,以及所需的任何数据类型转换。例如,将导入的日期强制转换为SQL DATETIME 您可以使用下面的代码段
让SQL处理引号转义和其他所有操作
BULK INSERT Test_CSV
FROM 'C:\MyCSV.csv'
WITH (
FORMAT='CSV'
--FIRSTROW = 2, --uncomment this if your CSV contains header, so start parsing at line 2
);
关于其他答案,以下是有价值的信息:
我一直在所有答案中看到这一点:行终止符='\n'
\n表示LF,它是Linux风格的EOL
在Windows中,下线由2个字符CRLF组成,因此需要行终止符='\r\n'
嗨,马克,是的,不幸的是每一行都有一个CRLF。不过,感谢您的输入。对于CRLF,您需要使用ROWTERMINATOR='\r\n'您是正确的!当我在标题的末尾添加“| |”时,效果很好。我想我将尝试从插入的每个文件中去掉头。谢谢这也适用于我使用逗号。同样,在插入之前,将去掉标题。谢谢。这是一个避免使用SSI的神奇脚本。它只允许我导入第一行,检查它是否与目标行一致,然后继续导入除标题以外的所有数据。谢谢
BULK INSERT Test_CSV
FROM 'C:\MyCSV.csv'
WITH (
FORMAT='CSV'
--FIRSTROW = 2, --uncomment this if your CSV contains header, so start parsing at line 2
);