Преобразование varchar в datetime2 в SQL Server

#sql #sql-server

#sql #sql-сервер

Вопрос:

Я использую SQL Server 2008 R2 и выполнил импорт из плоского файла. Я не смог правильно импортировать datetime столбец, поэтому я временно указал его как varchar(50) . Теперь я хочу преобразовать его в datetime2 формат. Однако при этом я получаю сообщение об ошибке —

Ошибка преобразования при преобразовании даты и / или времени из символьной строки.

Данные, которые в данный момент находятся в моем varchar(50) столбце, выглядят следующим образом:

 2008-04-02-16.43.32.179530
2009-01-12-20.15.41.936632
2009-02-18-16.54.49.071662
  

Каков наилучший способ преобразовать его в datetime2 ?

Ответ №1:

Не очень

 ;WITH T(YourCol) As
(
SELECT '2008-04-02-16.43.32.179530' union all
SELECT '2009-01-12-20.15.41.936632' union all
SELECT '2009-02-18-16.54.49.071662'
)
SELECT CAST(
            STUFF(REPLACE(
                          STUFF(YourCol,11,1,'T')
                  ,'.',':')
            ,20,1,'.')
        AS DATETIME2)
FROM T
  

Комментарии:

1. Вероятно, я должен упомянуть, что у меня есть несколько тысяч дат, поэтому написание SELECT для каждой из них было бы болезненным.

2. Мой код не выполняет SELECT для каждого из них. Он просто использует обычное табличное выражение с вашими 3 строками примеров данных для демонстрационных целей.

3. Понял, и, глядя на запрос, нужно заменить разделители на соответствующие.

4. ДА. На самом деле, stuff возможно, потребуется, чтобы среднее значение было STUFF(YourCol,11,1,'T') вместо STUFF(YourCol,11,1,' ') , чтобы гарантировать работу независимо от региональных настроек. На данный момент не уверен в этом, но я отредактирую это изменение независимо от того, поскольку это формат ISO.

5. Похоже, это сработало, я также изменил CAST на CONVERT , указал datetime2 формат в начале и удалил AS DATETIME2 .

Ответ №2:

К сожалению, это не распознанный формат метки времени. Это близко к каноническому формату ODBC, но не совсем. Вам придется выполнить некоторые манипуляции со строками.

Если взять первые 10 символов, то это дата в каноническом формате ODBC (гггг-мм-дд), никаких изменений не требуется. Это достаточно просто: LEFT(dateAsStringColumn, 10) . Теперь вам нужны символы с 12 по 19 (без тире между датой и временем), но с заменой «.» на «:». Наконец, дословно повторите символы 20-26. Преобразуйте все это в Datetime2, используя стиль 21 (ODBC Canonical с миллисекундами).

Попробуйте это:

 SELECT CONVERT(datetime2, LEFT(myColumn, 10)   " "   REPLACE(SUBSTRING(myColumn, 12, 8), ".", ":")   RIGHT(myColumn, 7), 21) as DateFromString FROM myTable