Импорт в SQL Server с форматным файлом и массовой вставкой - PullRequest
3 голосов
/ 06 марта 2012

Всем привет. У меня сложная проблема с использованием команды BULK INSERT при попытке импортировать данные из текстового файла.

Я нашел много статей и примеров в Интернете об импорте с помощью программы BULK INSERT или BCP, но они мне не помогают.

Проблема:
Я делаю экспорт из Oracle в текстовый файл с разделителем столбцов {#} и разделителем строк <#> и импортирую его в SQL Server.

Таблица (SQL Server):

CREATE TABLE my_DATA
(
ID_PK     NUMERIC(30)  NOT NULL ,
BEGIN_TIME    DATETIME  NULL ,
END_TIME      DATETIME  NULL
);

для Oracle:

CREATE TABLE my_DATA
(
ID_PK     NUMBER(30)  NOT NULL ,
BEGIN_TIME    TIMESTAMP  NULL ,
END_TIME      TIMESTAMP  NULL
);

Файл с разделителем:

ID_PK{#}BEGIN_TIME{#}END_TIME<#>296167{#}01/01/2012 01:30:00.000{#}01/01/2012 02:00:00.000<#>296178{#}01/01/2012 02:00:00.000{#}01/01/2012 02:30:00.000<#>

Формат файла:

9.0                         
3                           
1   SQLNUMERIC  0   19  {#} 1   ID_PK   ""
2   SQLDATETIME 0   8   {#} 2   BEGIN_TIME  ""
3   SQLDATETIME 0   8   <#> 3   END_TIME    ""

Поэтому, когда я использовал команду:

BULK INSERT my_DATA 
FROM 'D:\my_DATA.txt' 
WITH 
(CODEPAGE = '1251',
 FIELDTERMINATOR = '{#}', 
 FIRSTROW = 2, 
 ROWTERMINATOR = '<#>' );

Это работает, но когда я пытаюсь использовать формат файла, это не работает:

BULK INSERT my_DATA 
FROM 'D:\my_DATA.txt' 
WITH (CODEPAGE = '1251',
      FORMATFILE ='D:\format_file.txt');

Ошибка:

Ошибка преобразования данных при массовой загрузке (несоответствие типов или недопустимый символ для указанной кодовой страницы) для строки 2, столбца 2 (begin_time).

Я искал об этой проблеме, попробуйте изменить datetime на smalldate, попробуйте изменить длину на 23 или 24. Это не работает. Поэтому я пытаюсь импортировать другую таблицу без даты, я использую числовой столбец и столбцы с символами, но я столкнулся с той же проблемой с числовым столбцом:

Ошибка преобразования данных при массовой загрузке (несоответствие типов или недопустимый символ для указанной кодовой страницы) для строки 2, столбца 1 (id_pk).

таблица:

CREATE TABLE unit_table
(
id_pk  NUMERIC(30)  NOT NULL ,
name             NVARCHAR(200)  NULL ,
name_full        NVARCHAR(200)  NULL ,
CONSTRAINT  PK_unit_table_2C1 PRIMARY KEY (bule_biz_unit_level_id_pk)
);

формат файла:

9.0
3
1       SQLNUMERIC    0       1      "{#}"      1     id_pk                              ""
2       SQLNCHAR      0       11     "{#}"      2     name                                              ""
3       SQLNCHAR      0       11     "{#}"      3     name_full                                         ""

Файл данных содержит только 3 строки (одинаковая команда массовой вставки):

ID_PK{#}NAME{#}NAME_FULL<#>1{#}factory{#}factory<#>2{#}station{#}station<#>

Интересно, если файл содержит только 2 строки:

ID_PK{#}NAME{#}NAME_FULL<#>1{#}factory{#}factory<#>

Результат массовой вставки:

(затронуто 0 строк)

Я тоже пытаюсь сделать пример http://msdn.microsoft.com/en-us/library/ms178129.aspx но сталкиваюсь с ошибкой:

Невозможно выполнить массовую загрузку, поскольку файл "D: \ myTest.txt" не может быть прочитан. Код ошибки операционной системы (ноль).

И последнее, я пытался использовать это с bcp программой и тоже сталкивался с ошибками.

Может кто-нибудь помочь мне с моей проблемой или дать мне хотя бы один рабочий пример с массовой вставкой и форматированием файла.

P.S. Я использую MS SQL Server 2005 обновлен до последней версии. ОС Windows 7 x64.

Ответы [ 2 ]

3 голосов
/ 07 марта 2012

Спасибо всем.Но проблема заключалась в том, что MS SQL Server требует тип SQLCHAR при импорте из текстового файла и не имеет значения, какой тип столбца в базе данных.В моей проблеме решение заменяет любые типы столбцов, такие как SQLNUMERIC, SQLDATETIME на SQLCHAR в файле формата.

1 голос
/ 07 марта 2012

Это не совсем то, что вы просили, но я проверил это и должен найти вас, куда вам нужно идти.Насколько я знаю, следующее должно быть выполнено с сервера, на котором размещен SQL Server.Вероятно, вы можете настроить запланированное задание или что-то более сложное в будущем.

Сначала вам нужно создать файл формата.Я привел разные типы данных в примере, чтобы показать, как их следует использовать.

<?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="{#}" MAX_LENGTH="24"/>
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="{#}" MAX_LENGTH="35" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR="{#}" MAX_LENGTH="12"/>
  <FIELD ID="4" xsi:type="CharTerm" TERMINATOR="{#}" MAX_LENGTH="41"/>
  <FIELD ID="5" xsi:type="CharTerm" TERMINATOR="<#>" MAX_LENGTH="30"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="RpPrdEndDt" xsi:type="SQLDATETIME"/>
  <COLUMN SOURCE="2" NAME="ContrCustNum" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="3" NAME="ClimateZone" xsi:type="SQLINT"/>
  <COLUMN SOURCE="4" NAME="BCMsrQty" xsi:type="SQLDECIMAL" PRECISION="16" SCALE="3"/>
  <COLUMN SOURCE="5" NAME="RMsrPricePerUnit" xsi:type="SQLMONEY"/>
 </ROW>
</BCPFORMAT>

Во-вторых, вам нужно создать оператор SQL INSERT для ваших данных:

INSERT INTO TableName
            (RpPrdEndDt,
             ContrCustNum,
             ClimateZone,
             BCMsrQty,
             RMsrPricePerUnit)
SELECT RpPrdEndDt,
       ContrCustNum,
       ClimateZone,
       BCMsrQty,
       RMsrPricePerUnit
FROM   OPENROWSET(BULK 'C:\ImportFileName.csv',
                  FORMATFILE='C:\FormatFile.xml' ) AS t1; 

И в-третьих, если вы хотите запустить это из командной строки, как вы бы BCP, вы можете использовать это:

sqlcmd -S ServerName\InstanceName -i C:\SavedSQLFile.sql
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...