SQL 服务器 BCP 批量插入用文本限定符格式文件分隔的管道
SQL Server BCP Bulk insert Pipe delimited with text qualifier format file
我有一个 csv 文件,它是用垂直管道分隔的,每列还带有文本限定符“。
多年来我一直在尝试让 BCP 格式文件工作,但没有成功。
我有以下分期table:
[ID] [VARCHAR](100) NULL,
[SUB_ID] [NUMERIC](18, 0) NULL,
[CODE1] [VARCHAR](20) NULL,
[CODE2] [NUMERIC](18, 0) NULL,
[DATE] [DATE] NULL
csv 格式的数据:
"ID"|"SUB_ID"|"CODE1"|"CODE2"|"DATE"
"HAJHD87SADAD9A87SD9ADAS978DAA89D09AS"|"7510"|"N04FY-1"|"359420013"|"08/08/2018"
格式化文件:
14.0
5
1 SQLCHAR 0 0 '"|"' 1 ID ""
2 SQLCHAR 0 0 '"|"' 2 SUB_ID ""
3 SQLCHAR 0 0 '"|"' 3 CODE1 SQL_Latin1_General_CP1_CI_AS
4 SQLCHAR 0 0 '"|"' 4 CODE2 ""
5 SQLCHAR 0 0 '"\n"' 5 DATE ""
当我尝试使用以下 SQL 语句执行时:
BULK INSERT [dbo].[TEST]
FROM 'G:\DATA\TABLE.csv'
WITH (FIRSTROW = 2,
FORMATFILE = 'G:\DATA\TEST.fmt')
我收到这个错误
Msg 4866, Level 16, State 8, Line 1
The bulk load failed. The column is too long in the data file for row 1, column 1. Verify that the field terminator and row terminator are specified correctly.
Msg 7301, Level 16, State 2, Line 1
Cannot obtain the required interface ("IID_IColumnsInfo") from OLE DB provider "BULK" for linked server "(null)".
我不知道哪里出了问题。是数据类型不匹配还是我的 FIELDTERMINATOR 和 ROWTERMINATOR 不正确?任何想法都会受到很大的欢迎,我尝试了很多组合。
首先,BCP程序只将双引号识别为分隔符的容器。因此,使用单引号会导致错误。
其次,由于要指定分隔符“|”包括 BCP 要求您用来括起定界符的双引号字符,您必须使用转义字符让 BCP 程序忽略要用作定界符的引号。转义字符是反斜杠字符。所以...
代替“|”...使用...“\”|\“”
这将告诉 BCP 忽略以反斜杠开头的双引号,并将它们视为任何其他字符。
第三,您必须考虑前面带有双引号的第一个字段。 “|”我上面提到的终止符不会解释第一个字段每行开头的开头双引号。
要处理该问题,您必须将 "dummy" 字段添加到您的格式文件并将其终止符指定为 \"(或者在格式文件中实际上是“\"")。然后,由于现在文件中的字段比 table 中多了一个字段,因此您必须偏移列编号以告诉 BCP 跳过这个由文件中的第一个双引号终止的新字段
最后,最后一个字段不只是换行符“\n”结束。它也由双引号(不包含管道字符)命名。因此,我们必须自定义最终字段终止符(实际上是 line/row 终止符)。像这样 "\"\n".
您的格式文件现在将如下所示:
14.0
5
1 SQLCHAR 0 0 "\"" 0 dummy_field ""
2 SQLCHAR 0 0 "\"|\"" 1 ID ""
3 SQLCHAR 0 0 "\"|\"" 2 SUB_ID ""
4 SQLCHAR 0 0 "\"|\"" 3 CODE1 SQL_Latin1_General_CP1_CI_AS
5 SQLCHAR 0 0 "\"|\"" 4 CODE2 ""
6 SQLCHAR 0 0 "\"\n" 5 DATE ""
希望对您有所帮助。
对我有用的东西正在改变
ROWTERMINATOR = '\n'
至
ROWTERMINATOR = '0x0a'。
如果将其重写为您的情况,只需执行类似这样的操作:
BULK INSERT [dbo].[TEST]
FROM 'G:\DATA\TABLE.csv'
WITH
(
FIRSTROW = 2
, FIELDTERMINATOR ='|'
, ROWTERMINATOR = '0x0a'
);
我有一个 csv 文件,它是用垂直管道分隔的,每列还带有文本限定符“。
多年来我一直在尝试让 BCP 格式文件工作,但没有成功。
我有以下分期table:
[ID] [VARCHAR](100) NULL,
[SUB_ID] [NUMERIC](18, 0) NULL,
[CODE1] [VARCHAR](20) NULL,
[CODE2] [NUMERIC](18, 0) NULL,
[DATE] [DATE] NULL
csv 格式的数据:
"ID"|"SUB_ID"|"CODE1"|"CODE2"|"DATE"
"HAJHD87SADAD9A87SD9ADAS978DAA89D09AS"|"7510"|"N04FY-1"|"359420013"|"08/08/2018"
格式化文件:
14.0
5
1 SQLCHAR 0 0 '"|"' 1 ID ""
2 SQLCHAR 0 0 '"|"' 2 SUB_ID ""
3 SQLCHAR 0 0 '"|"' 3 CODE1 SQL_Latin1_General_CP1_CI_AS
4 SQLCHAR 0 0 '"|"' 4 CODE2 ""
5 SQLCHAR 0 0 '"\n"' 5 DATE ""
当我尝试使用以下 SQL 语句执行时:
BULK INSERT [dbo].[TEST]
FROM 'G:\DATA\TABLE.csv'
WITH (FIRSTROW = 2,
FORMATFILE = 'G:\DATA\TEST.fmt')
我收到这个错误
Msg 4866, Level 16, State 8, Line 1
The bulk load failed. The column is too long in the data file for row 1, column 1. Verify that the field terminator and row terminator are specified correctly.Msg 7301, Level 16, State 2, Line 1
Cannot obtain the required interface ("IID_IColumnsInfo") from OLE DB provider "BULK" for linked server "(null)".
我不知道哪里出了问题。是数据类型不匹配还是我的 FIELDTERMINATOR 和 ROWTERMINATOR 不正确?任何想法都会受到很大的欢迎,我尝试了很多组合。
首先,BCP程序只将双引号识别为分隔符的容器。因此,使用单引号会导致错误。
其次,由于要指定分隔符“|”包括 BCP 要求您用来括起定界符的双引号字符,您必须使用转义字符让 BCP 程序忽略要用作定界符的引号。转义字符是反斜杠字符。所以...
代替“|”...使用...“\”|\“”
这将告诉 BCP 忽略以反斜杠开头的双引号,并将它们视为任何其他字符。
第三,您必须考虑前面带有双引号的第一个字段。 “|”我上面提到的终止符不会解释第一个字段每行开头的开头双引号。
要处理该问题,您必须将 "dummy" 字段添加到您的格式文件并将其终止符指定为 \"(或者在格式文件中实际上是“\"")。然后,由于现在文件中的字段比 table 中多了一个字段,因此您必须偏移列编号以告诉 BCP 跳过这个由文件中的第一个双引号终止的新字段
最后,最后一个字段不只是换行符“\n”结束。它也由双引号(不包含管道字符)命名。因此,我们必须自定义最终字段终止符(实际上是 line/row 终止符)。像这样 "\"\n".
您的格式文件现在将如下所示:
14.0
5
1 SQLCHAR 0 0 "\"" 0 dummy_field ""
2 SQLCHAR 0 0 "\"|\"" 1 ID ""
3 SQLCHAR 0 0 "\"|\"" 2 SUB_ID ""
4 SQLCHAR 0 0 "\"|\"" 3 CODE1 SQL_Latin1_General_CP1_CI_AS
5 SQLCHAR 0 0 "\"|\"" 4 CODE2 ""
6 SQLCHAR 0 0 "\"\n" 5 DATE ""
希望对您有所帮助。
对我有用的东西正在改变
ROWTERMINATOR = '\n'
至
ROWTERMINATOR = '0x0a'。
如果将其重写为您的情况,只需执行类似这样的操作:
BULK INSERT [dbo].[TEST]
FROM 'G:\DATA\TABLE.csv'
WITH
(
FIRSTROW = 2
, FIELDTERMINATOR ='|'
, ROWTERMINATOR = '0x0a'
);