Ошибка импорта BCP с файлом формата XML и столбцом идентификаторов - PullRequest
1 голос
/ 01 декабря 2011

Я создал таблицу на сервере SQL, например:

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: «Значение» не имеет значенияпервый формат.Это работает, если я создаю этот странный XML-формат с 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" />    

1 Ответ

2 голосов
/ 08 декабря 2011

Крайне маловероятно, что вы обнаружили ошибку в хорошо известном, интенсивно используемом и исчерпывающе документированном инструменте. Скорее всего, вы не нашли правильную комбинацию инструкций по форматированию или сделали какую-то другую ошибку.

Сказав это, мне все еще не совсем ясно, чего вы хотите достичь. Насколько я понимаю, ваш файл имеет 3 значения фиксированной длины, ваша таблица имеет 3 столбца, и вы хотите скопировать 2 значения из файла в 2 столбца таблицы, чтобы в результате вы получили «Test» в столбце имени а 100 в столбце значений?

Это значит, что вы хотите пропустить последнее значение в файле и первый столбец в таблице. Обратите внимание на эту цитату из документации :

С файлом формата XML вы не можете пропустить столбец, когда вы импорт непосредственно в таблицу с помощью команды bcp или BULK Вставить заявление. Тем не менее, вы можете импортировать все, кроме последнего столбца стола. Если вам нужно пропустить любой, кроме последнего столбца, вы должны создать представление целевой таблицы, которая содержит только столбцы содержится в файле данных. Затем вы можете массово импортировать данные из этого файл в представление.

Чтобы использовать файл формата XML для пропуска столбца таблицы с помощью 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, см. Пример F в образцах файлов формата 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.

...