#sql #sql-server
#sql #sql-сервер
Вопрос:
Я пытаюсь преобразовать varchar(255) в datetime в SQL. Я нашел этот пример:
DECLARE @IsoDate nvarchar(255)
SET @IsoDate = '2010-03-16T19:20:30.45123 01:00'
-- CONVERT TO DATETIME in SQL 2008
SELECT CAST(CONVERT(datetimeoffset, @IsoDate) AS datetime) as SQL2008
и это работает отлично. Поскольку я хочу изменить формат столбца для целого столбца, я попытался
SELECT CAST(CONVERT(datetimeoffset, [col1]) AS datetime)
from [table]
но это выдает ошибку: ошибка преобразования при преобразовании даты и / или времени из символьной строки.
Я не понимаю, в чем проблема, единственный способ, которым он работал с использованием столбца, — это
SELECT CAST(Left([col1]),18) AS datetime)
from [table]
но я бы предпочел не обрезать строку.
Ответ №1:
Вы можете использовать
SELECT *
from [table]
WHERE TRY_CONVERT(datetimeoffset, [col1]) IS NULL
чтобы увидеть, какие значения вызывают проблемы.
Если ваша версия (поскольку у вас есть комментарий к SQL Server 2008) не поддерживается TRY_CONVERT
, и TRY_CAST
вы можете выбрать часть записей, чтобы найти проблемы, используя предложение loop / where.
Ответ №2:
но я бы предпочел не обрезать строку.
Почему? При преобразовании DateTimeOffset
в DateTime
информация о часовом поясе в любом случае усекается (см. Документацию), и поскольку вы заявили, что это решает вашу проблему, это означает, что единственные места, где содержимое вашей строки вызывает проблемы, находятся где-то в этой части строки.
Кроме того, поскольку ваша строка ISO8601, вы можете безопасно использовать cast
вместо convert
(какой смысл использовать convert
, если вы все равно не собираетесь использовать style
параметр?) — или, что еще лучше, используйте try_cast
(если вы не работаете с версией ниже 2012, которую в этом случае вам следует рассмотреть возможность обновления, поскольку это самая старая версия, которая все еще поддерживается) — так:
SELECT CAST(TRY_CAST([col1] AS datetimeoffset) AS datetime2(7))
FROM [table]
При этом было бы лучше хранить значения datetime с учетом часового пояса DateTimeOffset
в типе данных — и другие значения datetime в DateTime2
типе данных (что лучше, чем DateTime
во всех отношениях).
Ответ №3:
Ваш код не работает, потому что у вас неверные значения. Вы можете игнорировать их, используя try_convert()
:
SELECT CAST(TRY_CONVERT(datetimeoffset, [col1]) AS datetime)
FROM [table]
Это поддерживается во всех поддерживаемых версиях SQL Server.
Поскольку часовой пояс игнорируется в этом процессе, вы также можете просто использовать:
select try_convert(datetime, left(col1, 23))