SQLBulkCopy и даты (01.01.1753) - PullRequest
       33

SQLBulkCopy и даты (01.01.1753)

0 голосов
/ 18 ноября 2011

У меня есть приложение, которое уже давно работает нормально, но есть раздражающий элемент, который по-прежнему мешает.

Допустим, я использую такой объект, как OracleDataReader или MySQLDataReader, чтобы передать данные в объект sqlbulkcopy для вставки.Давайте предположим, что все столбцы отображаются нормально и по большей части все работает хорошо.

Конечно, у меня нет контроля над исходным приложением или базой данных (то есть MySQL или Oracle).Таким образом, некоторые глупости переходят в другое приложение и помещают дату в таблицу счетов-фактур от 31.05.02.Он действительно собирался сдать 31.05.2010, но приложение, которое он использует, не очень тщательно проверяет данные, и база данных Oracle принимает его.Для всех интенсивных целей данные от 31.05.02 являются действительной датой для базы данных Oracle.Это может быть глупо с точки зрения ввода данных, но это то, что есть на данный момент.

Теперь наш OracleDataReader приходит и передает эту таблицу счетов-фактур на SQL Server через SQLBulkCopy.Он передает данные в идеально согласованную таблицу с правильными именами столбцов и типами данных.Вы можете видеть, что произойдет.Эта дата от 31.05.0210 от Oracle не принимается ядром базы данных SQL Server, поскольку в поле DATETIME допускаются только даты с 01.01.1753 по 31.129999.

Когда он встречает эту запись, он просто терпит неудачу и выдает ошибку переполнения.Это не пропускает запись, это убивает подачу.Таким образом, если в таблице с миллионами записей произойдет тысяча записей, вы не получите оставшиеся 999 000 записей.

Есть ли способ обойти эту проблему, чтобы канал продолжался?

В идеале я хотел бы переместить принимающую БД SQL Server в 2008 г. и использовать DATETIME2, что позволило бы использовать эти глупые даты, но, к сожалению, не все мои клиенты готовы перейти на эту версию, поэтому яЯ застрял с DATETIME в SQL 2000/2005/2008.

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

Любые мысли будут оценены.

1 Ответ

0 голосов
/ 19 ноября 2011

Один из вариантов - изменить тип столбца datetime на varchar.Затем добавьте производный столбец для преобразования строки в datetime.Хитрость заключается в том, чтобы использовать функцию в производном столбце для проверки даты и поставить произвольную дату и время, если покрытие не удастся.Если вы сравниваете тяжелые даты, сохраняйте вычисленный столбец и / или индексируйте его.

Я говорю все это под впечатлением, что sqlbulkcopy не может выполнять преобразования.Может быть, вы можете.Надеемся, что кто-нибудь ответит на вопрос:

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

...