我似乎无法弄清楚这是怎么回事。
以下是我尝试批量插入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:\filefromabove.txt
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR= '|',
ROWTERMINATOR = '\n'
)
但是,出于某种原因,我能得到的唯一输出是:
0000005678|ABCD|00013893-03JUN09
0000009112|0000|00013893-03JUN09
0000009112|0000|00013893-03JUN09
除非我完全删除标题并且不使用FIRSTROW参数,否则总是会跳过第一条记录。这怎么可能?
提前致谢!
答案 0 :(得分:14)
我认为您不能使用BULK INSERT
/ 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。
答案 1 :(得分:8)
也许检查标题是否与实际数据行具有相同的行结尾(在ROWTERMINATOR
中指定)?
更新:来自MSDN:
不打算使用FIRSTROW属性 跳过列标题。跳绳 BULK不支持标头 INSERT语句。跳过行时, SQL Server数据库引擎看起来 只在现场终结者,和 不验证中的数据 跳过的字段。
答案 2 :(得分:6)
我发现最简单的方法是将整行读入一列,然后使用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
答案 3 :(得分:0)
BULK INSERT TextData
FROM 'E:\filefromabove.txt'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = '|', --CSV field delimiter
ROWTERMINATOR = '\n', --Use to shift the control to next row
ERRORFILE = 'E:\ErrorRows.csv',
TABLOCK
)
答案 4 :(得分:0)
要让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
);
关于其他答案,这也是有价值的信息:
我一直在所有答案中看到这一点:ROWTERMINATOR = '\n'
\n
表示LF,它是Linux风格的EOL
在Windows中,EOL由2个字符的CRLF组成,因此您需要ROWTERMINATOR = '\r\n'
答案 5 :(得分:-1)
鉴于BCP从非SQL数据源导入SQL Server后,一些数据可能会出现多少损坏,我建议先将所有BCP导入到某些临时表中。
例如
截断表Address_Import_tbl
BULK INSERT dbo.Address_Import_tbl 来自'E:\ external \ SomeDataSource \ Address.csv' WITH( FIELDTERMINATOR ='|',ROWTERMINATOR ='\ n',MAXERRORS = 10 )
确保Address_Import_tbl中的所有列都是nvarchar(),以使其尽可能不可知,并避免类型转换错误。
然后将所需的任何修复应用于Address_Import_tbl。比如删除不需要的标题。
然后运行INSERT SELECT查询,从Address_Import_tbl复制到Address_tbl,以及您需要的任何数据类型转换。例如,将导入的日期强制转换为SQL DATETIME。