【问题标题】:BCP returns no errors, but also doesn't copy any rowsBCP 不返回错误,但也不复制任何行
【发布时间】:2013-04-24 23:02:00
【问题描述】:

我正在尝试将大量数据从 .csv 文件转储到 SQL Server 2012 数据库中。我正在调查 bcp,而不是进行数千次 INSERT。

编辑:这是一个自动化的过程,而不仅仅是一次性的。我也没有此数据库的BULK INSERT 权限。

当我尝试将数据复制到数据库中时,bcp 不会返回任何错误,但实际上也不会复制任何内容 - 它只是返回 0 rows copied。我已将其缩减为一个不起作用的最小案例。

首先,创建一个包含两列的简单表:

CREATE TABLE [dbo].[mincase](
    [key] [varchar](36) NOT NULL,
    [number] [int] NOT NULL

    PRIMARY KEY CLUSTERED 
    (
        [key] ASC
    )
    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 40) ON [PRIMARY]
) ON [PRIMARY]

GO

然后,使用bcp 从中创建一个格式文件。请注意,此示例创建了一个 XML 格式文件,但它是 XML 还是本机无关紧要。

bcp MyDB.dbo.mincase format nul -T -n -f mincasexml.fmt -x -S .\SQLEXPRESS

现在创建一个 data.csv 文件,其中包含一行和两个条目,以制表符分隔。就我而言,文件很简单:

somecharacters  12345

同样,这是一个制表符,而不是两个空格,而且后面是否有换行似乎并不重要。

现在尝试将bcp 与该格式文件一起使用以插入该文件中的数据:

bcp MyDB.dbo.mincase in data.csv -f mincasexml.fmt -T -S .\SQLEXPRESS

我没有将数据复制到数据库,而是这样:

Starting copy...

0 rows copied.
Network packet size (bytes): 4096
Clock Time (ms.) Total     : 1

有人知道这里发生了什么吗?

谢谢!

【问题讨论】:

  • 您是否尝试过导入数据选项?

标签: sql sql-server bcp


【解决方案1】:

bcp 命令通常需要一个标识符来指定 bcp 文件的格式模式。

  • -c 指定字符(明文)模式
  • -n 指定纯模式
  • -w 指定unicode模式

在您的测试用例中,您创建的文件是纯文本文件,因此您应该在命令中的 bcp 中指定“-c”。

bcp MyDB.dbo.mincase in data.csv -c -T -S .\SQLEXPRESS

Microsoft Recommends 对导入和导出使用“-n”以避免字段分隔符出现在列值中的问题(请参阅字符模式和本机模式最佳实践部分)。

【讨论】:

  • 就是这样,稍作修改:-f 覆盖 -c,因此完全删除格式文件非常巧妙地解决了问题。最终结果是:bcp MyDB.dbo.mincase in data.csv -c -T -S .\SQLEXPRESS
【解决方案2】:

我遇到了类似的问题,除了我已经在使用格式文件,因此添加格式标志之一无济于事。对于最终来到这里的其他人,我想为我解释导致此问题的原因(并希望有助于解释根本问题原因是什么)。

问题在于 BCP 实际上并不处理文件中的文本行。相反,它只是根据您给它的指令处理数据流。 这意味着如果您(不小心)告诉 BCP 这样做,换行符将被忽略。

就我而言,这是格式文件最后一行的错字:

13.0
1348
1 SQLCHAR 0 21 "," 1 RecordKey ""
2 SQLCHAR 0 30 "," 0 SubmissionKey ""
3 SQLCHAR 0 1 "," 2 A1cLvl ""
...
1347 SQLCHAR 0 1 "," 0 WoundIntVac ""
1348 SQLCHAR 0 1 "/r/n" 0 XClampTm ""

如果您仔细观察,您会发现最后一行的终止符字段中的斜线是向后的。因此,BCP 不是在寻找 Windows 风格的行尾,而是在数据流中寻找文本字符串“/r/n”。

由于该字符串实际上根本没有出现在我的数据中,因此 BCP 从未真正找到与我的最终字段匹配的任何内容。因此,它找到“0 行”进行复制是有道理的。

我仍然不确定为什么这不会导致“遇到意外的 EOF”错误之类的错误,但希望其他人能够对此进行扩展。

【讨论】:

  • 这对于您使用的 BCP 示例会更有用。
猜你喜欢
  • 2015-04-04
  • 1970-01-01
  • 1970-01-01
  • 2018-02-06
  • 2016-07-04
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 2021-02-26
相关资源
最近更新 更多