英文:
OPENJSON and incremental value
问题
我正在尝试解析以下JSON文档:
DECLARE @doc nvarchar(max) = '
{
"0": {
"start_time": "1685959230501",
"timestamp": "10:00:30",
"running_time": "1.2s",
},
"1": {
"start_time": "1685959230502",
"timestamp": "10:00:30",
"running_time": "1.2s",
},
"2": {
"start_time": "1685959230886",
"timestamp": "10:00:30",
"running_time": "889.3ms",
},
"3": {
"start_time": "1685959230887",
"timestamp": "10:00:30",
"running_time": "883.9ms",
}'
SELECT *
FROM OPENJSON(@doc, '$.sql:identity()')
WITH (
start_time datetime2(3) N'$.start_time',
[timestamp] varchar(128) N'$.timestamp',
running_time varchar(128) N'$.running_time'
) AS i
然而,它引发了以下异常:
Msg 13607, Level 16, State 4, Line 24
JSON path is not properly formatted. Unexpected character ':' is found at position 5.
我尝试了多种使用OPENJSON函数的第二个参数的方法,但都没有成功。有人有什么想法吗?
英文:
I'm trying to parse the following JSON document :
DECLARE @doc nvarchar(max) = '
{
"0": {
"start_time": "1685959230501",
"timestamp": "10:00:30",
"running_time": "1.2s",
},
"1": {
"start_time": "1685959230502",
"timestamp": "10:00:30",
"running_time": "1.2s",
},
"2": {
"start_time": "1685959230886",
"timestamp": "10:00:30",
"running_time": "889.3ms",
},
"3": {
"start_time": "1685959230887",
"timestamp": "10:00:30",
"running_time": "883.9ms",
}"'
SELECT *
FROM OPENJSON(@doc, '$.sql:identity()')
WITH (
start_time datetime2(3) N'$.start_time'
, [timestamp] varchar(128) N'$.timestamp'
, running_time varchar(128) N'$.running_time'
) AS i
However it raises the following exception :
> Msg 13607, Level 16, State 4, Line 24
> JSON path is not properly formatted. Unexpected character ':' is found at position 5.
I tried several ways using the second parameter of the OPENJSON function, but none has been working.
Does someone have an idea ?
答案1
得分: 1
在修复您的无效JSON后,看起来您想要以下T-SQL查询:
SELECT
j1.[key],
j2.*
FROM OPENJSON(@doc) j1
CROSS APPLY OPENJSON(j1.value)
WITH (
start_time bigint,
[timestamp] time,
running_time varchar(128)
) AS j2;
使用OPENJSON
而不带模式来获取一系列的key, value
对,然后再次使用带模式的APPLY OPENJSON
将每个对象拆分为属性。
还请注意数据类型的更改。
英文:
After fixing up your invalid JSON, it looks like you want this
SELECT
j1.[key],
j2.*
FROM OPENJSON(@doc) j1
CROSS APPLY OPENJSON(j1.value)
WITH (
start_time bigint
, [timestamp] time
, running_time varchar(128)
) AS j2;
Use OPENJSON
without a schema to get a series of key, value
pairs, then APPLY OPENJSON
again with a schema to break out each object into properties.
Note also the changes to the data types.
答案2
得分: 1
你的JSON不是有效的,这是一个问题。首先,在每个内部数组的最后一个键/值对之后,你有一个尾随逗号,例如 "running_time": "1.2s",}
。此外,你的JSON末尾有一个多余的双引号("
),并且你没有关闭外部对象。
出于这个答案的目的,我将“假设”你有有效的JSON。如果不是有效的JSON,请修复创建上述JSON的过程;它存在缺陷,创建了损坏的JSON,这意味着SQL Server 无法 使用它。
这个答案的目的是翻译上述内容,不包含其他内容。
英文:
Your JSON isn't valid, which is a problem. For starters, you have a trailing comma after the last key/value pair in each of your inner arrays; for example "running_time": "1.2s",}
. You also have a stray double quote ("
) at the end of your JSON and you don't close the outer object.
For the purposes of this answer, I'm going to "assume" you have valid JSON. If you don't, then you need to fix whatever process is creating the above JSON; it is flawed and creating broken JSON meaning that SQL Server cannot consume it.
This takes a guess of the results you want, but presumable you want one row per object, with a column that includes the value of the name of that object.
One method would be to use 2 calls to OPENJSON
; the first puts the "identity" value into a key
column and the inner object into another column. Then you can consume that inner object with another call with OPENJSON
. This results in the following:
SELECT d.[key],
v.start_time,
v.timestamp,
v.running_time
FROM OPENJSON(@doc) d
CROSS APPLY OPENJSON(d.[value])
WITH (start_time bigint,
timestamp time(0),
running_time varchar(10)) v;
This produces the following results (with valid JSON):
key | start_time | timestamp | running_time |
---|---|---|---|
0 | 1685959230501 | 10:00:30 | 1.2s |
1 | 1685959230502 | 10:00:30 | 1.2s |
2 | 1685959230886 | 10:00:30 | 889.3ms |
3 | 1685959230887 | 10:00:30 | 883.9ms |
If you need the column start_time
to be an actual date and time data type (datetime2(0)
?) there are plenty of duplicates, such as:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论