Массовая вставка канала SQL Server BCP, разделенная файлом формата текстового квалификатора - PullRequest
0 голосов
/ 02 мая 2019

У меня есть CSV-файл, который представляет собой вертикальную трубу, разделенную каждым столбцом, также с текстовым квалификатором ".

. Я пытался целую вечность пытаться заставить работать файл формата BCP, но безуспешно.

У меня есть следующая промежуточная таблица:

[ID] [VARCHAR](100) NULL,
[SUB_ID] [NUMERIC](18, 0) NULL,
[CODE1] [VARCHAR](20) NULL,
[CODE2] [NUMERIC](18, 0) NULL,
[DATE] [DATE] NULL

Данные в формате CSV:

"ID"|"SUB_ID"|"CODE1"|"CODE2"|"DATE"
"HAJHD87SADAD9A87SD9ADAS978DAA89D09AS"|"7510"|"N04FY-1"|"359420013"|"08/08/2018"

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

14.0
5
1   SQLCHAR   0  0   '"|"'  1  ID      ""
2   SQLCHAR   0  0   '"|"'  2  SUB_ID  ""
3   SQLCHAR   0  0   '"|"'  3  CODE1   SQL_Latin1_General_CP1_CI_AS
4   SQLCHAR   0  0   '"|"'  4  CODE2   ""
5   SQLCHAR   0  0   '"\n"' 5  DATE    ""

Когда япопытайтесь выполнить, используя следующую инструкцию SQL:

BULK INSERT [dbo].[TEST]
FROM 'G:\DATA\TABLE.csv'  
WITH (FIRSTROW = 2,
      FORMATFILE = 'G:\DATA\TEST.fmt')

Я получаю эту ошибку

Сообщение 4866, уровень 16, состояние 8, строка 1
Массовая загрузка не выполнена.Столбец слишком длинный в файле данных для строки 1, столбца 1. Убедитесь, что терминатор поля и терминатор строки указаны правильно.

Сообщение 7301, Уровень 16, Состояние 2, Строка 1
Невозможно получитьтребуемый интерфейс ("IID_IColumnsInfo") от поставщика OLE DB "BULK" для связанного сервера "(null)".

Я не могу понять, где происходит ошибка. Это тип данныхнесоответствие или мои FIELDTERMINATOR и ROWTERMINATOR неверны? Любые идеи будут приняты, яОн перепробовал так много комбинаций.

Ответы [ 2 ]

1 голос
/ 02 мая 2019

Во-первых, программа BCP распознает только двойную кавычку как контейнер разделителя. Таким образом, использование одинарных кавычек приводит к ошибке.

Во-вторых, поскольку в качестве разделителя вы хотите указать «|» включает в себя символ двойной кавычки, который BCP требует от вас использовать для включения вашего разделителя, вы должны использовать escape-символ, чтобы программа BCP игнорировала кавычки, которые вы хотите использовать в качестве разделителей. Экранирующий символ - это символ обратной косой черты. Итак ...

Вместо "|" ... используйте ... "\" | \ ""

Это скажет BCP игнорировать двойные кавычки, начинающиеся с обратной косой черты, и обрабатывать их как любой другой символ.

В-третьих, вы должны указать первое поле, которое имеет двойную кавычку. "|" терминатор, о котором я упоминал выше, не учитывает открывающую двойную кавычку в начале каждой строки для первого поля.

Чтобы справиться с этим, вы должны добавить в файл формата «фиктивное» поле и назначить его терминатор как \ "(или фактически" \ "" в файле формата). Затем, поскольку у вас теперь есть еще одно поле в файле, чем в таблице, вы должны сместить нумерацию столбцов, чтобы BCP пропустил это новое поле, которое заканчивается первой двойной кавычкой в ​​файле

Последнее, последнее поле не заканчивается только символом новой строки "\ n". Это также называется двойной кавычкой (без символа трубы). Итак, мы должны настроить конечный терминатор поля (который на самом деле является терминатором строки / строки). Вот так "\" \ n ".

Ваш файл формата теперь будет выглядеть так:

14.0
5
1   SQLCHAR   0  0   "\""  0  dummy_field   ""
2   SQLCHAR   0  0   "\"|\""  1  ID      ""
3   SQLCHAR   0  0   "\"|\""  2  SUB_ID  ""
4   SQLCHAR   0  0   "\"|\""  3  CODE1   SQL_Latin1_General_CP1_CI_AS
5   SQLCHAR   0  0   "\"|\""  4  CODE2   ""
6   SQLCHAR   0  0   "\"\n" 5  DATE    ""

Надеюсь, это поможет.

0 голосов
/ 24 июля 2019

То, что работало для меня, менялось

ROWTERMINATOR = '\ n'

до

ROWTERMINATOR = '0x0a'.

Просто выполните что-то вроде этого, если переписать это в ваш случай:

BULK INSERT [dbo].[TEST]
FROM 'G:\DATA\TABLE.csv' 
WITH 
(   
    FIRSTROW = 2 
    , FIELDTERMINATOR ='|'
    , ROWTERMINATOR = '0x0a'
);
...