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

发布于 2024-12-19 05:26:14 字数 1906 浏览 3 评论 0原文

我在 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 格式化程序在表中导入文件。我遇到了问题,因为我的表有“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" />    

I created a table in SQL server like:

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]

I want to import a file in my table using xml formater. I got a problem because my table had "myId". I think it's a bug in bcp because, if i don't add myId column, the importation works fine.

File:

Test      0010000290

Xml format file:

<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>

Output:

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

Editing

@MatthewMartin:
The "value" came null whit my first format.
It works if i create this strange xml format with null column

<COLUMN SOURCE="2" NAME="null" xsi:type="SQLCHAR" />
<COLUMN SOURCE="1" NAME="name" xsi:type="SQLCHAR" />
<COLUMN SOURCE="3" NAME="value" xsi:type="SQLINT" />    

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ˇ宁静的妩媚 2024-12-26 05:26:14

您极不可能在一个众所周知的、被广泛使用且有详尽记录的工具中发现错误。您更有可能没有找到正确的格式说明组合或犯了其他错误。

话虽如此,(对我来说)仍然不完全清楚你想要实现什么。我最好的理解是,您的文件有 3 个固定长度值,您的表有 3 列,并且您希望将文件中的 2 个值复制到表中的 2 列,这样您最终会在名称列中看到“Test”值栏中的 100?

这意味着您想要跳过文件中的最后一个值和表中的第一列。请注意文档中的这段引用:

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

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

插入...从OPENROWSET中选择(批量...)

基于所有这些背景,您可以创建视图并使用 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,请参见 示例 XML 格式文件):

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 是一个 ODBC 保留关键字 Microsoft 建议不要在 SQL Server 中使用。

It is extremely unlikely that you have found a bug in a well-known, intensively used and exhaustively documented tool. It is far more likely that you haven't found the correct combination of formatting instructions or are making some other mistake.

Having said that, it's still not entirely clear (to me) what you want to achieve. My best understanding is that your file has 3 fixed-length values, your table has 3 columns, and you want to copy 2 values from the file to 2 columns in the table, so that you end up with 'Test' in the name column and 100 in the value column?

That would mean you want to skip the last value in the file and the first column in the table. Note this quote from the documentation:

With an XML format file, you cannot skip a column when you are
importing directly into a table by using a bcp command or a BULK
INSERT statement. However, you can import into all but the last column
of a table. If you have to skip any but the last column, you must
create a view of the target table that contains only the columns
contained in the data file. Then, you can bulk import data from that
file into the view.

To use an XML format file to skip a table column by using
OPENROWSET(BULK...), you have to provide explicit list of columns in
the select list and also in the target table, as follows:

INSERT ... SELECT FROM OPENROWSET(BULK...)

Based on all of that background, you can either create a view and use bcp.exe or just use OPENROWSET() with the table, which I think is easier:

The table:

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

The data file (row terminated with a Windows newline, i.e. CR+LF, see example F under sample XML format files):

Test      0010000290

The format file:

<?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>

The command:

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

Finally, a couple of other small points. Please always mention which version and edition of SQL Server you're using: many features are only available in specific versions/editions. You should also review your column names; I know you may have simply used them for a quick example here, but they are not very descriptive and VALUE is an ODBC reserved keyword that Microsoft recommends should not be used in SQL Server.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文