我在SQL Server 2017中有一个存储过程,该过程将结果集输出为JSON。它可以很好地输出设置,但是我希望使用其他格式。
根据MS文档,其发送的格式符合预期,但对我来说似乎违反直觉。无论如何我都不是JSON专家,但我一直认为它是结构的单个对象表示形式。
查询为:
SELECT
e.EventID AS 'Event.ID',
EventDate AS 'Event.Date',
ea.ActivityID AS 'Event.Activity.ID',
ea.CreateDate AS 'Event.Activity.Date',
ea.Notes AS 'Event.Activity.Notes'
FROM
Events e
JOIN
dbo.EventActivities ea ON e.EventID = ea.EventID
FOR JSON PATH
这将返回以下输出:
[
{"Event": {
"ID":"236",
"Date":"2019-03-01",
"Activity": {"ID": 10,
"Date":"2019-01-02T11:47:33.2800000",
"Notes":"Event created"}
}
},
{"Event": {
"ID":"236",
"Date":"2019-03-01",
"Activity": {"ID":20,
"Date":"2019-01-02T11:47:34.3933333",
"Notes":"Staff selected"}
}
},
{"Event": {
"ID":"236",
"Date":"2019-03-01",
"Activity": {"ID":20,
"Date":"2019-01-02T11:47:34.3933333",
"Notes":"Staff selected"}
}
}
]
当我手动设置格式时(为了更好地显示它,它给我每个活动一个3个相同事件的数组。这与MS在Format Nested JSON中所说的一致
我期望(或更希望)看到类似的东西:
[
{
"Event": {
"ID": "236",
"Date": "2019-03-01",
"Activity": [
{
"ID": 10,
"Date": "2019-01-02T11:47:33.2800000",
"Notes": "Event created"
},
{
"ID": 20,
"Date": "2019-01-02T11:47:34.3933333",
"Notes": "Staff selected"
},
{
"ID": 20,
"Date": "2019-01-02T11:47:34.3933333",
"Notes": "Staff selected"
}
]
}
}
]
是否可以得到这样的输出?还是无效?
答案 0 :(得分:1)
首先,您可以使用ISJSON测试JSON字符串是否有效。您指示的预期输出未通过验证,但是接近。内部数组缺少“ []”。
但是,我知道您的处理方法。为了更好地解释我认为您遇到的问题是什么,我将美化查询中输出JSON的格式以匹配您期望的JSON。
原始输出如下:
[
{"Event":
{"ID":"236","Date":"2019-03-01",
"Activity":{
"ID":10,"Date":"2019-01-02T11:47:33.2800000","Notes":"Event created"
}
}
},
{"Event":
{"ID":"236","Date":"2019-03-01",
"Activity":{
"ID":20,"Date":"2019-01-02T11:47:34.3933333","Notes":"Staff selected"}
}
},
{"Event":
{"ID":"236","Date":"2019-03-01",
"Activity":{
"ID":20,"Date":"2019-01-02T11:47:34.3933333","Notes":"Staff selected"
}
}
}
]
根据您的理想格式,可能的有效JSON字符串如下:
{"Event":
[
{"ID":236,"Date":"2019-03-01",
"Activity":
[
{"ID":10,"Date":"2019-01-02T11:47:33.2800000","Notes":"Event created"},
{"ID":20,"Date":"2019-01-02T11:47:34.3933333","Notes":"Staff selected"},
{"ID":20,"Date":"2019-01-02T11:47:34.3933333","Notes":"Staff selected"}
]
}
]
}
您可以通过调整第二个表的表别名并使用FOR JSON AUTO和ROOT来实现。它将返回其每个“ EventActivities”都没有重复的“ Event”属性的输出。对于每个“事件”,它将其相关的“ EventActivities”放入数组中。
以下SQL将返回所需的输出:
SELECT [Event].EventID AS 'ID',
[Event].EventDate AS 'Date',
Activity.ActivityID AS 'ID',
Activity.CreateDate AS 'Date',
Activity.Notes AS 'Notes'
FROM #Events [Event]
JOIN #EventActivities Activity
ON [Event].EventID = Activity.EventID
FOR JSON AUTO, ROOT('Event')
确切的输出如下:
{"Event":[{"ID":236,"Date":"2019-03-01","Activity":[{"ID":10,"Date":"2019-01-02T11:47:33.2800000Z","Notes":"Event created"},{"ID":20,"Date":"2019-01-02T11:47:33.2800000Z","Notes":"Staff selected"},{"ID":20,"Date":"2019-01-02T11:47:33.2800000Z","Notes":"Staff selected"}]}]}
它不会以美化的格式返回,但是可以添加空格和缩进,而不会损害它是有效JSON的事实,同时还可以达到预期的数组要求。
答案 1 :(得分:0)
您的预期输出不是有效的JSON。但是,假设您将“活动”字段引用为活动数组,则可以使用嵌套查询。
SELECT
E.EventID AS 'Event.ID',
E.EventDate AS 'Event.Date',
(
SELECT
A.ActivityID AS 'ID',
A.CreateDate AS 'Date',
A.Notes AS 'Notes'
FROM dbo.EventActivities AS A
WHERE A.EventID = E.EventID
FOR JSON PATH
) AS 'Event.Activities'
FROM dbo.Events AS E
FOR JSON PATH