1

Я выполняю импорт объемных данных в файлах CSV. В CSV-файлах мой столбец «Дата» содержит дату в формате «YYYYDDMMHHMM» (например, 200603010929).Преобразование VARCHAR в SMALLDATETIME как часть инструкции UPDATE

Как можно заметить, если я выбираю «smalldatetime» при создании таблицы, импорт данных потерпит неудачу с этой ошибкой:

Bulk load data conversion error (type mismatch or invalid character for the specified codepage) for row 2, column 2 (Date).

Как я понимаю, для того, чтобы работать дата должна быть определенный формат для работы.

Поэтому одна идея заключается в том, чтобы импортировать значения даты в поле типа VARCHAR, а затем, когда импорт завершен, я хочу выполнить UPDATE для каждой строки, чтобы преобразовать дату в smalldatetime. Это продлит процесс импорта, но я думаю, что было бы намного проще и намного быстрее, чем пытаться найти и заменить данные CSV (это огромный набор данных).

Итак, мой вопрос: 1) Возможно ли это? 2) Как его реализовать?

Это то, что я до сих пор:

UPDATE NYSE 
SET [date]=CONVERT(smalldatetime, [date]) 

Это не удается, так как текст не в нужном формате. Можно ли указать формат строки внутри функции CONVERT, или есть ли другой способ?

Я ценю все комментарии. Благодарю.

+0

Является ли это на самом деле YYYYDDMM и не YYyyMmDd? Итак, 20060301 - 3 января, а не 1 марта? –

+0

Да, это определенно YYYYDDMMHHMM, 3 января. У меня есть отдельный набор данных, который находится в формате YYYDDMM (без времени) и успешно импортируется в таблицу с типом данных DATE SQL. Это тот, который включает время, в которое я испытываю трудности. –

+1

Вы уверены, что YYYYDDMM без времени импортируется правильно? Вероятно, они заменяют значения D и M ... –

ответ

3
DECLARE @s TABLE([date] VARCHAR(20)); 

INSERT @s SELECT '200603010929'; 

UPDATE @s SET [date] = CONVERT(CHAR(16), CONVERT(SMALLDATETIME, 
    LEFT([date],4) + SUBSTRING([date],7,2) + SUBSTRING([date],5,2) 
    + ' ' + STUFF(RIGHT([date],4),3,0,':')), 120); 

SELECT [date], CONVERT(SMALLDATETIME, [date]) FROM @s; 

Если это, на самом деле, YYYYMMDD, то это немного проще:

DECLARE @s TABLE([date] VARCHAR(20)); 

INSERT @s SELECT '200603010929'; 

UPDATE @s SET [date] = CONVERT(CHAR(16), CONVERT(SMALLDATETIME, 
    LEFT([date],8) + ' ' + STUFF(RIGHT([date],4),3,0,':')), 120); 

SELECT [date], CONVERT(SMALLDATETIME, [date]) FROM @s; 
+0

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

+1

Это в основном просто вытягивает части неправильной строки, чтобы сформировать допустимую строку. Начиная со второй линии и разрабатывая, он берет первые 4 символа (2006), затем 7-й и 8-й символы (01), затем 5-й и 6-й символы (01). Это дает действительную и однозначную дату в формате YYYYMMDD. Затем на 3-й строке мы добавляем пробел и вводим двоеточие в последние 4 символа (0929), делая это допустимым временем (09:29) и формируя целую строку 20060103 09:29. Эта строка мы можем преобразовать в smalldatetime, но для того, чтобы сохранить строку таким образом, нам также нужен стиль. –

+0

Я выполнил инструкцию Update, как вы указали, но я получил сообщение об ошибке: «String или двоичные данные будут усечены». В настоящее время у моего варчара есть ограничение на 15 символов. Я изменил аргумент CHAR (16) на CHAR (15) - с этим он выбросил ошибку: «Преобразование типа данных varchar в тип данных smalldatetime приводит к значению вне диапазона». На этот раз он продолжался дольше. Должен ли я использовать лимит на моем варчаре, прежде чем запускать это? –