在 SQL Server 中读取 JSON 数据时无法从字符串转换为日期时间
Posted
技术标签:
【中文标题】在 SQL Server 中读取 JSON 数据时无法从字符串转换为日期时间【英文标题】:Cannot Convert from String to Datetime while reading JSON data in SQL Server 【发布时间】:2021-12-28 09:32:36 【问题描述】:DECLARE @JSON AS varchar(MAX)
SET @JSON = '[
"UserId": "XYZ12345",
"LoginTime": "2021-12-25T07:48:59Z"
,
"UserId": "XYZ67890",
"LoginTime": "2021-12-24T07:48:59Z"
]'
SELECT *
FROM OPENJSON(@json)
WITH (
UserId nvarchar(MAX) '$.UserId',
LoginTime datetime '$.LoginTime'
)
ORDER BY UserId ASC
但是,我得到一个错误
从字符串转换日期和/或时间时转换失败
【问题讨论】:
Cannot reproduce。语言设置也不应该影响这一点。您可以尝试DATETIMEOFFSET
,因为它明确设计用于处理时区(如果您不需要时区信息,您可以进一步转换它),但如果“修复”它,仍然会有一些奇怪的事情发生。
同意,您使用的格式是明确的,这意味着您实际上拥有的日期/时间值是完全无效的。如2021-02-29T25:00:17Z
。
@Larnu 这将产生不同的错误消息(至少在 2019 年 - The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.
)但是我同意这很可能是由无效数据引起的 - 但我怀疑它可能更像是打字错误 - 某人使用O
而不是0
或类似的东西。
请更新此working DB Fiddle 以重现错误
值得注意的是,如果输入中存在 not Z
的时区,则会发生此确切错误。显然,如果使用 UTC 时区字符串,则仅允许以静默方式转换为 DATETIME
;对于其他时区偏移,必须使用 DATETIMEOFFSET
。当然,如果已知输入包含时区指示符,则显式使用 DATETIMEOFFSET
是个好主意。
【参考方案1】:
JSON 数据中的一些登录时间可能有时区。
将其转换为 DATETIME 时会引发错误。
但是将它们转换为 DATETIME2 或 DATETIMEOFFSET 就可以了。
那么 DATETIMEOFFSET 可能是更好的选择,因为它会包含时区。
简化测试:
消息 241 级别 16 状态 1 第 1 行 从字符串转换日期和/或时间时转换失败。SELECT * FROM OPENJSON('["LoginTime": "2021-12-25T07:48:59+01:00"]') WITH ( LoginTime datetime '$.LoginTime' ) GO
|登录时间 | | :---------------------------- | | 2021-12-25 07:48:59.0000000 |SELECT * FROM OPENJSON('["LoginTime": "2021-12-25T07:48:59+01:00"]') WITH ( LoginTime datetime2 '$.LoginTime' ) GO
登录时间 |登录时间Zulu :--------------------------------- | :-------------------------------- 2021-12-25 07:48:59.0000000 +03:00 | 2021-12-25 04:48:59.0000000 +00:00SELECT * , SWITCHOFFSET(LoginTime, '+00:00') AS LoginTimeZulu FROM OPENJSON('["LoginTime": "2021-12-25T07:48:59+03:00"]') WITH ( LoginTime datetimeoffset '$.LoginTime' ) GO
db小提琴here
【讨论】:
哎哟。它允许在丢弃 TZ 信息的同时静默转换为DATETIME2
,这有点不妥,因为除非所有偏移量都恰好相同,否则这没有希望是正确的。这使得在涉及时区时使用DATETIMEOFFSET
变得更加重要(如果需要,以后可以转换)。
@JeroenMostert 情况更糟。 DATETIMEOFFSET 到 DATETIME2 或 DATETIME 的 CAST 不会根据时区更改时间。以上是关于在 SQL Server 中读取 JSON 数据时无法从字符串转换为日期时间的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server OPENJSON 读取嵌套的 json
我已经安装了json-server 但是就是读不到配置文件当前目录下的db.json