SQL Server BULK INSERT - вставка значений DateTime - PullRequest
6 голосов
/ 21 августа 2011

У меня есть 6 миллионов строк данных, которые я хочу вставить в свою базу данных SQL Server.Я могу сделать это медленно с 6 миллионами операторов INSERT (по моим подсчетам это займет 18 часов) или я могу попробовать BULK INSERT.

BULK INSERT имеет проблемы с невозможностью экранировать символы, ноданные в этом случае очень просты, и поэтому не должны сталкиваться с этой проблемой.

Однако SQL Server, похоже, не нравится какая-либо форма данных даты / времени, вставляемая в поле.

Вот таблица (psuedo-SQL)

CREATE TABLE Tasks (
    TaskId bigint NOT NULL IDENTITY(1,1) PRIMARY KEY,
    TriggerId bigint NOT NULL FOREIGN KEY,
    Created datetime NOT NULL,
    Modified datetime NOT NULL,
    ScheduledFor datetime NULL,
    LastRan datetime NULL,
    -- and about 10 more fields after this
)

Вот мой оператор BULK INSERT:

SET DATEFORMAT dmy
BULK INSERT Tasks
FROM 'C:\TasksBulk.dat'
WITH (
    -- CHECK_CONSTRAINTS is not necessary as the only constraints are always enforced regardless of this option (UNIQUE, PRIMARY KEY, and NOT NULL)
    CODEPAGE = 'RAW',
    DATAFILETYPE = 'native',

    KEEPIDENTITY,
    MAXERRORS = 1,
    ORDER ( CallId ASC ),

    FIELDTERMINATOR = '\t',
    ROWTERMINATOR   = '\0'
)

А вот первая строка данных в TasksBulk.dat:

1000\t1092\t01/01/2010 04:00:17\t01/01/2010 04:00:17\t\t01/01/2010 04:00:14\0

(Для удобства чтения переформатирован символами табуляции, замененными на 4 пробела:)

1000    1092    01/01/2010 04:00:17    01/01/2010 04:00:17        01/01/2010 04:00:14\0

Однако, когда я запускаю инструкцию BULK INSERT, я получаю эту ошибку:

Сообщение 4864, Уровень 16, Состояние 1, Строка 2 Ошибка преобразования данных при массовой загрузке (несоответствие типов или недопустимый символ для указанной кодовой страницы) для строки 1, столбца 3 (Создано).

Я пробовал использовать разные терминаторы строк и полейи каждый другой формат даты / времени (включая «01/01/2010», «2010-01-01», как с компонентом времени «04:00:17», так и без него).Я не знаю, что я делаю здесь не так.

Ответы [ 3 ]

5 голосов
/ 21 августа 2011

Оказывается, что изменение DATAFILETYPE с «native» на «char» решило проблему.«Нативный» тип подразумевает строгий формат данных для всего, в то время как «char» предназначен для более простых текстовых файлов.

1 голос
/ 21 августа 2011

У вас CODDEPAGE установлено значение RAW (предположительно для скорости).

Сообщение об ошибке означает, что ваши данные содержат символы вне кодовой страницы.

CODEPAGE [ = 'ACP' | 'OEM' | 'RAW' | 'code_page' ]

Определяет кодовую страницу данных в файле данных.CODEPAGE имеет значение только в том случае, если данные содержат столбцы типа char, varchar или text со значениями символов больше 127 или меньше 32.

Но это может ввести в заблуждение .В вашем примере строка данных содержит отсутствующий столбец.Если вы не используете файл форматирования, необходимо использовать каждое поле в таблице.

Таким образом, вы можете либо создать файл форматирования, либо создать промежуточную таблицу с помощью varchar (25) для столбцов datetime, импортируя изатем выполните обновление из промежуточной таблицы в таблицу назначения.Таким образом, вы сможете лучше контролировать конверсии и отсутствующие данные.

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

Метод, с которым я знаком, состоит в том, чтобы вставить ваши даты в виде целого числа.

Я использую количество секунд, начиная с определенной даты (в прошлом я использовал один более 10 лет, так как нет данных, к которым я бы обращался или генерировал, которые старше этого)

Дата 2012-01-02 12: 15: 10.000 будет сохранена как 378637886 с использованием контрольной точки 1 января 2000 года.

При запросе к базе данных вы можете получить столбец, возвращенный с помощью DateAdd (SS, имя_столбца, '2000-01-01').

Вы также можете сделать это за миллисекунды, если нужна такая точность.

Я использую свою собственную пользовательскую функцию для преобразования своего времени в секундах в любой формат, который мне нравится, и я использую другую пользовательскую функцию для преобразования дат обратно в секунды.

Я понимаю, что это не может быть хорошим методом, потому что он может потребовать изменения базы данных и кода для вас, но, возможно, это может быть концепция решения, которую другие сочтут полезным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...