SQL Server BCP批量插入管道,以文本限定符格式文件分隔

时间:2019-05-02 18:42:57

标签: sql-server bulkinsert bcp

我有一个csv文件,该文件是垂直管道,每列分隔,文本限定符为“。

我一直在尝试尝试使BCP格式文件正常工作,但没有运气。

我有以下登台表:

[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')

我收到此错误

  

4866级消息,第16级,状态8,第1行
  批量加载失败。数据文件中第1行第1列的列太长。请验证是否正确指定了字段终止符和行终止符。

     

消息7301,第16级,状态2,第1行
  无法从OLE DB提供程序“ BULK”获得链接服务器“(空)”的必需接口(“ IID_IColumnsInfo”)。

我无法找出问题出在哪里。是数据类型不匹配,还是我的FIELDTERMINATOR和ROWTERMINATOR不正确?任何想法都会受到欢迎,我尝试了很多组合。

2 个答案:

答案 0 :(得分:0)

首先,BCP程序仅将双引号识别为定界符的容器。因此,使用单引号会导致错误。

第二,由于您要指定分隔符“ |”包括BCP要求您用来包围定界符的双引号字符,您必须使用转义字符来使BCP程序忽略要用作定界符的引号。转义字符是反斜杠字符。所以...

代替...,使用...“ \” | \“”

这将告诉BCP忽略以反斜杠开头的双引号,并将其视为其他任何字符。

第三,必须说明第一个具有双引号的字段。 “ |”我上面提到的终止符不会解释第一个字段在每行开头的双引号。

要处理此问题,必须在格式文件中添加一个“虚拟”字段,并将其终止符分配为\“(或在格式文件中实际为“ \””)。然后,由于文件中的字段比表中的字段多,因此必须偏移列编号,以告诉BCP跳过由文件中第一个双引号终止的新字段

最后,最后一个字段不是仅由换行符“ \ n”终止。它也被称为双引号(不包括管道字符)。因此,我们必须自定义最终的字段终止符(实际上是行/行终止符)。像这样的“ \” \ 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    ""

我希望有帮助。

答案 1 :(得分:0)

对我有用的是改变

ROWTERMINATOR ='\ n'

ROWTERMINATOR ='0x0a'。

如果将其重写为您的情况,则只需执行以下操作即可

BULK INSERT [dbo].[TEST]
FROM 'G:\DATA\TABLE.csv' 
WITH 
(   
    FIRSTROW = 2 
    , FIELDTERMINATOR ='|'
    , ROWTERMINATOR = '0x0a'
);