【问题标题】:Simple SQL Bulk Insert not working简单的 SQL 批量插入不起作用
【发布时间】:2016-11-23 06:39:37
【问题描述】:

我正在尝试创建一个简单的Bulk Insert 命令来将固定宽度的文本文件导入表格。完成这项工作后,我将对其进行扩展以使我的更复杂的导入工作。

我目前收到错误消息...

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

显然我已经检查了文件中的终止符。对于测试数据,我只是在记事本中键入了一个 3 行文本文件。在这个阶段,我只是想每行导入一列。我已经填充了前两行,所以每行都是 18 个字符。

Test.txt

This is line one  
This is line two  
This is line three

当我在 Notepad++ 中查看文件并打开所有字符时,我在每行的末尾看到 CRLF,而文件末尾没有空行。

这是我正在使用的 SQL:

USE [Strata]
GO
drop table VJR_Bulk_Staging

Create Table [dbo].[VJR_Bulk_Staging](
[rowid] int Identity(1,1) Primary Key,
[raw] [varchar](18) not null)

GO
Bulk Insert [VJR_Bulk_Staging] 
From 'c:\temp\aba\test.txt'
with (FormatFile='c:\temp\aba\test2.xml')

这是格式 XML 文件。我尝试了几种变体。这是使用 BCP 命令创建的。

bcp strata.dbo.vjr_bulk_staging format nul -f test2.xml -x -n -T -S Server\Instance

这为我的 rowid 列创建了一条记录和一个行条目,我认为这是一个身份字段,因此我将其删除。

<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <RECORD>
  <FIELD ID="1" xsi:type="CharPrefix" PREFIX_LENGTH="2" MAX_LENGTH="18" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="raw" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>

我正在 SQL Server 2008 R2 Express 上进行测试。

任何想法我哪里出错了?

【问题讨论】:

    标签: sql-server tsql bulkinsert bcp sql-server-2008r2-express


    【解决方案1】:

    我认为问题在于您的前缀长度为 2 个字节:

    xsi:type="CharPrefix" PREFIX_LENGTH="2"
    

    根据您发布的内容,您的数据文件中没有前缀。在格式文件中将PREFIX_LENGTH 设置为 0,或在数据文件中提供正确的前缀。

    您可以在文档中找到有关前缀数据类型和前缀含义的更多信息:Specify Prefix Length in Data Files by Using bcp (SQL Server)

    我认为您真正想要的是输入 CharTerm 和正确的 TERMINATOR(在您的情况下为 /r/n)。

    【讨论】:

    • 它不喜欢 PREFIX_LENGTH="0" 并返回此错误。消息 4858,级别 16,状态 1,第 1 行格式文件“c:\temp\aba\test2.xml”中的第 4 行:属性“PREFIX_LENGTH”的错误值 0。我只使用它是因为它是 bcp 命令生成的。从您的链接中,我现在看到了 PreFixLength 的用途,我当然不需要它。我的数据文件没有这个。现在我考虑一下,我的文件确实有固定的行长,所以即使 CR LF 也是多余的。我只需要允许它。我会在这里看看其他一些建议。谢谢。
    • @DavidPollard 不客气 =)。 CharFixed 是另一种选择:固定长度且没有终止符。我已经认为CharPrefix 不适用于您所拥有的。祝你好运!
    【解决方案2】:

    这行得通。

    选项 1:非 XML 格式文件

    9.0  
    1
    1 SQLCHAR 0 18 "\r\n" 2 raw SQL_Latin1_General_CP1_CI_AS
    

    或者干脆

    9.0  
    1
    1 SQLCHAR "" "" "\r\n" 2 "" ""
    

    选项 2:XML 格式文件

    丑陋的解决方法

    <?xml version="1.0"?>
    <BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     <RECORD>
      <FIELD ID="1" xsi:type="CharTerm" TERMINATOR="\r" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
      <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\n"/>
     </RECORD>
     <ROW>
      <COLUMN SOURCE="2" xsi:type="SQLINT"/>
      <COLUMN SOURCE="1" xsi:type="SQLCHAR"/>  
     </ROW>
    </BCPFORMAT>
    

    附言
    在我看来,XML格式文件的设计存在错误。
    与非 XML 格式文件不同,没有选项来指示加载列的位置(名称只是为了脚本的清晰性,它们没有真正的含义)。
    文档中的 XML 示例不起作用
    Use a Format File to Skip a Table Column (SQL Server)

    【讨论】:

    • 我尝试了非xml格式。又名“非丑陋的地狱” :) 我在这里找到了这个文件的一个很好的描述msdn.microsoft.com/en-us/library/ms191479.aspx
    • 它出现了这个奇怪的错误。消息 4862,级别 16,状态 1,第 1 行无法批量加载,因为无法读取文件“c:\temp\aba\format.fmt”。操作系统错误代码(空)。即使每个人都拥有该文件的完全权限。原来我需要在 FMT 文件的末尾有一个空行。现在我需要决定使用临时表或尝试直接导入到我完成的表中。谢谢杜杜。你的答案是最简单的。
    【解决方案3】:

    您能否尝试以下命令并检查 BULK 插入是否正在发生。请注意我添加了最后一行提到分隔符。

    USE [Strata]
    GO
    drop table VJR_Bulk_Staging
    
    Create Table [dbo].[VJR_Bulk_Staging](
    [rowid] int Identity(1,1) Primary Key,
    [raw] [varchar](18) not null)
    
    GO
    Bulk Insert [VJR_Bulk_Staging] 
    From 'c:\temp\aba\test.txt'
    WITH ( FIELDTERMINATOR ='\t', ROWTERMINATOR ='\n',FIRSTROW=1 )
    

    【讨论】:

    • 感谢您的努力。我尝试了上面的其他解决方案,其中一个有效。您的建议产生了错误。消息 4832,级别 16,状态 1,第 1 行批量加载:在数据文件中遇到意外的文件结尾。消息 7399,级别 16,状态 1,第 1 行链接服务器“(null)”的 OLE DB 提供程序“BULK”报告了错误。提供商没有提供有关该错误的任何信息。消息 7330,级别 16,状态 2,第 1 行无法从链接服务器“(null)”的 OLE DB 提供程序“BULK”获取行。
    猜你喜欢
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    • 2013-10-01
    • 2021-04-23
    相关资源
    最近更新 更多