#sql #sql-server #bulkinsert
#sql #sql-server #bulkinsert
Вопрос:
Я пытаюсь использовать массовую вставку для загрузки очень большого файла данных (5 строк). Все столбцы — это просто переменные, без преобразования. Таким образом, формат файла прост…
11.0
29
1 SQLCHAR 0 8 "" 1 AccountId ""
2 SQLCHAR 0 10 "" 2 TranDate ""
3 SQLCHAR 0 4 "" 3 TransCode ""
4 SQLCHAR 0 2 "" 4 AdditionalCode ""
5 SQLCHAR 0 11 "" 5 CurrentPrincipal ""
6 SQLCHAR 0 11 "" 6 CurrentInterest ""
7 SQLCHAR 0 11 "" 7 LateInterest ""
...
27 SQLCHAR 0 8 "" 27 Operator ""
28 SQLCHAR 0 10 "" 28 UpdateDate ""
29 SQLCHAR 0 12 "" 29 TimeUpdated ""
но каждый раз в какой-то момент я получаю одну и ту же ошибку:
Сообщение 4832, уровень 16, состояние 1, строка 1 Массовая загрузка: в файле данных обнаружен неожиданный конец файла. Сообщение об ошибке 7399, уровень 16, состояние 1, строка 1 Поставщик OLE DB «BULK» для связанного сервера «(null)» сообщил об ошибке. Поставщик не предоставил никакой информации об ошибке. Сообщение 7330, уровень 16, состояние 2, строка 1 Не может получить строку от поставщика OLE DB «BULK» для связанного сервера «(null)».
Я попробовал следующее:
Bulk Insert
[TableName] From 'dataFilePPathSpecification'
With (FORMATFILE = 'formatFilePPathSpecification')
но я получаю сообщение об ошибке примерно через 5-6 минут, и данные не были вставлены.
Когда я добавил параметр BatchSize, я получаю сообщение об ошибке через гораздо более длительное время, ближе к концу файла, после того, как все строки, за исключением очень немногих, были вставлены успешно.
Bulk Insert
[TableName] From 'dataFilePPathSpecification'
With (BATCHSIZE = 200,
FORMATFILE = 'formatFilePPathSpecification')
Когда я устанавливаю размер пакета на 2000, он выполняется намного быстрее (я предполагаю, что меньше, больше транзакций), но все равно происходит сбой.
Имеет ли это какое-то отношение к тому, как массовая вставка распознает конец файла? Если да, то что мне нужно сделать с файлом формата, чтобы исправить это?
Ответ №1:
Явно укажите свой завершитель строки:
BULK INSERT TableName FROM 'Path'
WITH (
DATAFILETYPE = 'char',
ROWTERMINATOR = 'rn'
With (FORMATFILE = 'formatFilePPathSpecification')
);
Если это по-прежнему не удается, проверьте свой файл, чтобы увидеть, есть ли у вас неожиданные терминаторы, встроенные в текстовые поля.
Комментарии:
1. Мой файл данных был файлом фиксированной ширины, без ограничителей полей, но что вы подразумеваете под
line
иrow
терминаторами, это одно и то же, нет? — или вы просто неправильно выразились?2. так и думал… Тогда вы правы, это исправлено… Но мне пришлось поставить » r n» для строки (последнего поля).
3. Да, во многом зависит от файла, который вы извлекаете. Соответствующим образом обновили ответ..
Ответ №2:
Попытка использовать спецификатор errorFile в части WITH для поиска некорректных данных:
ERRORFILE = ‘C:offendingdata.log ‘
Ответ №3:
Если у вас все еще есть проблема даже после включения вывода errorfile, вы можете выполнить бинарный поиск проблемы, установив параметры firstRow и lastRow и повторно запустив массовую вставку, чтобы изолировать проблему.
Честно говоря, ваш формат ввода выглядит настолько простым, что было бы неплохо написать небольшое приложение на C #, Python или что-то еще, что поддерживает ваше приложение boat, чтобы проверить качество ваших данных перед попыткой импорта. Вы можете просто удалить недопустимые строки (или, возможно, исправить их) или записать их в файл исключений для ручной обработки или просто остановить задание — т.Е. Файл должен быть идеальным, иначе он считается поврежденным. Проверка 5M строк таким образом будет довольно быстрой — по сути, настолько быстрой, насколько вы сможете прочитать файл (и, возможно, записать) файл.
Ответ №4:
Спасибо за предложения всем, я применил обе идеи… Я написал небольшой .Утилита обработки файлов Net (c #) сообщила мне, что в конце каждой строки есть дополнительные нули (двоичные нули ( 0), и я смог удалить их с помощью простой программы на c #.
В файле с ошибкой указано, что проблема была в самом конце (это то, что указано в сообщении об ошибке!)
Фактическая проблема заключалась в том, что массовая вставка не могла распознать EOF .. Мне пришлось изменить файл формата следующим образом, чтобы исправить это.. Тогда это сработало.
11.0
29
1 SQLCHAR 0 8 "" 1 AccountId ""
2 SQLCHAR 0 10 "" 2 TranDate ""
3 SQLCHAR 0 4 "" 3 TransCode ""
4 SQLCHAR 0 2 "" 4 AdditionalCode ""
5 SQLCHAR 0 11 "" 5 CurrentPrincipa ""
6 SQLCHAR 0 11 "" 6 CurrentInterest ""
7 SQLCHAR 0 11 "" 7 LateInterest ""
...
27 SQLCHAR 0 8 "" 27 Operator ""
28 SQLCHAR 0 10 "" 28 UpdateDate ""
29 SQLCHAR 0 12 "rn" 29 TimeUpdated ""