bcp导入错误与xml格式文件和标识列

时间:2011-12-01 19:38:12

标签: sql-server bcp

我在SQL server中创建了一个表,如:

CREATE TABLE [dbo].[    
    [myId] [smallint] IDENTITY(1,1) NOT NULL,
    [name] [nchar](10) NOT NULL,
    [value] [int] NOT NULL,
CONSTRAINT [PK_metadado] PRIMARY KEY CLUSTERED 
(
  [myId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]

我想使用xml formater导入表格中的文件。我遇到了问题,因为我的桌子上有“myId”。我认为这是bcp中的一个错误,因为如果我不添加myId列,导入工作正常。

文件:

Test      0010000290

Xml格式文件:

<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="CharFixed" LENGTH="10"/>
    <FIELD ID="2" xsi:type="CharFixed" LENGTH="5"/>     
    <FIELD ID="3" xsi:type="CharFixed" LENGTH="5"/> 
</RECORD>
<ROW>
    <COLUMN SOURCE="3" NAME="value" xsi:type="SQLINT" />
    <COLUMN SOURCE="1" NAME="name" xsi:type="SQLCHAR" />
</ROW>
</BCPFORMAT>

输出:

Starting copy...
SQLState = 23000, NativeError = 515
Error = [Microsoft][SQL Server Native Client 10.0][SQL Server]Cannot insert the value NULL into column 'value', table 'XXX.dbo.metadata'; column does not allow nulls. INSERT fails.
SQLState = 01000, NativeError = 3621
Warning = [Microsoft][SQL Server Native Client 10.0][SQL Server]The statement has been      terminated.
BCP copy in failed

编辑

@MatthewMartin: 我的第一种格式是“价值”。 如果我使用 null

创建这种奇怪的xml格式,它会起作用
<COLUMN SOURCE="2" NAME="null" xsi:type="SQLCHAR" />
<COLUMN SOURCE="1" NAME="name" xsi:type="SQLCHAR" />
<COLUMN SOURCE="3" NAME="value" xsi:type="SQLINT" />    

1 个答案:

答案 0 :(得分:2)

您极不可能在众所周知,密集使用且详尽记录的工具中发现错误。您很可能没有找到正确的格式化指令组合或者犯了其他错误。

话虽如此,我(你)想要实现的目标仍然不完全清楚。我最好的理解是,您的文件有3个固定长度值,您的表有3列,并且您希望将文件中的2个值复制到表中的2列,以便最终在名称列中使用“Test”和值列中的100?

这意味着您要跳过文件中的最后一个值以及表中的第一列。请注意the documentation的引用:

  

使用XML格式文件时,您无法跳过列   使用bcp命令或BULK直接导入表   INSERT语句。但是,您可以导入除最后一列之外的所有列   一张桌子。如果你必须跳过除最后一列之外的任何一栏,你必须   创建仅包含列的目标表的视图   包含在数据文件中。然后,您可以批量导入数据   将文件存入视图。

     

使用XML格式文件通过使用跳过表格列   OPENROWSET(BULK ...),您必须提供明确的列列表   选择列表以及目标表中,如下所示:

     

INSERT ...从OPENROWSET中选择(BULK ...)

基于所有这些背景,你可以创建一个视图并使用bcp.exe或者只使用表中的OPENROWSET(),我认为这样更容易:

表格:

CREATE TABLE [dbo].metadata (
    [myId] [smallint] IDENTITY(1,1) NOT NULL,
    [name] [nchar](10) NOT NULL,
    [value] [int] NOT NULL,
    CONSTRAINT [PK_metadado] PRIMARY KEY CLUSTERED ([myId] ASC)
)

数据文件(以Windows换行符终止的行,即CR + LF,请参阅sample XML format files下的示例F):

Test      0010000290

格式文件:

<?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="CharFixed" LENGTH="10"/>
  <FIELD ID="2" xsi:type="CharFixed" LENGTH="5"/>
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR="\r\n"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="name" xsi:type="SQLNCHAR"/>
  <COLUMN SOURCE="2" NAME="value" xsi:type="SQLINT"/>
 </ROW>
</BCPFORMAT>

命令:

insert into dbo.metadata ([name], [value])
select [name], [value]
from openrowset(bulk 'C:\SomeFolder\data.bcp',
    formatfile = 'C:\SomeFolder\format.xml'
    ) dt

最后,还有其他一些小问题。请始终提及您正在使用的SQL Server版本和版本:许多功能仅适用于特定版本/版本。您还应该检查您的列名称;我知道您可能只是在这里使用它们作为一个快速示例,但它们不是非常具有描述性,而且VALUE是Microsoft建议不应在SQL Server中使用的ODBC reserved keyword