如何为 NULL 子值保留一个空的 JSON 父对象 - SQL Server FOR JSON PATH
How to retain an empty JSON parent object for NULL child values - SQL Server FOR JSON PATH
我在问和回答我自己的问题,但我想看看是否还有其他人对如何执行此操作有更好的想法。
我有一些 JSON 要发送给第三方 API。我已经为我正在尝试做的事情创建了一个虚假的简化表示。
有一个 primary_selection
及其子元素和一个 secondary_selection
及其子元素。如果副选不存在,则子元素全部为NULL。根据 API,secondary_selection
是必需的,但可以为空。他们还希望排除 NULL 元素。
DECLARE @JSON_WITHOUT_NULLS NVARCHAR(500)
SELECT @JSON_WITHOUT_NULLS = (
SELECT '123456' [administrative_info.account_num],
'1' [administrative_info.user_id],
'whole wheat bread' [primary_selection.vehicle_for_sauce],
'avocado' [primary_selection.topping],
'mayo' [primary_selection.sauce_type],
NULL [secondary_selection.vehicle_for_mayo],
NULL [secondary_selection.topping],
NULL [secondary_selection.sauce_type]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
SELECT @JSON_WITHOUT_NULLS
上面的 SQL 产生以下结果:
"administrative_info": {
account_num": "123456",
"user_id": "1"
},
"primary_selection": {
"vehicle_for_sauce": "whole wheat bread",
"topping": "avocado",
"sauce_type": "mayo"
}
但我想要的是:
"administrative_info": {
"account_num": "123456",
"user_id": "1"
},
"primary_selection": {
"vehicle_for_sauce": "whole wheat bread",
"topping": "avocado",
"sauce_type": "mayo"
},
"secondary_selection": {}
所以,这是我的解决方案,但想看看是否还有其他人知道如何执行此操作。
DECLARE @JSON_WITHOUT_NULLS NVARCHAR(500)
SELECT @JSON_WITHOUT_NULLS = (SELECT '123456' [administrative_info.account_num],
'1' [administrative_info.user_id],
'whole wheat bread' [primary_selection.vehicle_for_sauce],
'avocado' [primary_selection.topping],
'mayo' [primary_selection.sauce_type],
NULL [secondary_selection.vehicle_for_mayo],
NULL [secondary_selection.topping],
NULL [secondary_selection.sauce_type]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
SELECT @JSON_WITHOUT_NULLS
DECLARE @EMPTY_OBJECT NVARCHAR(2) = '{}'
SELECT @JSON_WITHOUT_NULLS = JSON_MODIFY(@JSON_WITHOUT_NULLS,'$.secondary_selection',JSON_QUERY(@EMPTY_OBJECT))
SELECT @JSON_WITHOUT_NULLS
另一种可能的选择是下面的语句。您需要使用 FOR JSON PATH
.
生成每个一级 JSON 对象
请注意,您需要调用 JSON_QUERY()
以防止转义特殊字符。文档中对此进行了解释:JSON_QUERY return 是一个有效的 JSON 片段。因此,FOR JSON 不会转义 JSON_QUERY return 值中的特殊字符。如果您 return 使用 FOR JSON 计算结果,并且您要包括已经采用 JSON 格式的数据(在列中或作为表达式的结果),请将 JSON 数据 JSON_QUERY 没有路径参数 .
DECLARE @JSON_WITHOUT_NULLS NVARCHAR(max)
SELECT @JSON_WITHOUT_NULLS = (
SELECT
administrative_info = JSON_QUERY((
SELECT '123456' [account_num], '1' [user_id]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)),
primary_selection = JSON_QUERY((
SELECT 'whole wheat bread' [vehicle_for_sauce], 'avocado' [topping], 'mayo' [sauce_type]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)),
secondary_selection = JSON_QUERY((
SELECT NULL [vehicle_for_mayo], NULL [topping], NULL [sauce_type]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
))
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
结果:
{
"administrative_info":{
"account_num":"123456",
"user_id":"1"
},
"primary_selection":{
"vehicle_for_sauce":"whole wheat bread",
"topping":"avocado",
"sauce_type":"mayo"
},
"secondary_selection":{
}
}
我在问和回答我自己的问题,但我想看看是否还有其他人对如何执行此操作有更好的想法。
我有一些 JSON 要发送给第三方 API。我已经为我正在尝试做的事情创建了一个虚假的简化表示。
有一个 primary_selection
及其子元素和一个 secondary_selection
及其子元素。如果副选不存在,则子元素全部为NULL。根据 API,secondary_selection
是必需的,但可以为空。他们还希望排除 NULL 元素。
DECLARE @JSON_WITHOUT_NULLS NVARCHAR(500)
SELECT @JSON_WITHOUT_NULLS = (
SELECT '123456' [administrative_info.account_num],
'1' [administrative_info.user_id],
'whole wheat bread' [primary_selection.vehicle_for_sauce],
'avocado' [primary_selection.topping],
'mayo' [primary_selection.sauce_type],
NULL [secondary_selection.vehicle_for_mayo],
NULL [secondary_selection.topping],
NULL [secondary_selection.sauce_type]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
SELECT @JSON_WITHOUT_NULLS
上面的 SQL 产生以下结果:
"administrative_info": {
account_num": "123456",
"user_id": "1"
},
"primary_selection": {
"vehicle_for_sauce": "whole wheat bread",
"topping": "avocado",
"sauce_type": "mayo"
}
但我想要的是:
"administrative_info": {
"account_num": "123456",
"user_id": "1"
},
"primary_selection": {
"vehicle_for_sauce": "whole wheat bread",
"topping": "avocado",
"sauce_type": "mayo"
},
"secondary_selection": {}
所以,这是我的解决方案,但想看看是否还有其他人知道如何执行此操作。
DECLARE @JSON_WITHOUT_NULLS NVARCHAR(500)
SELECT @JSON_WITHOUT_NULLS = (SELECT '123456' [administrative_info.account_num],
'1' [administrative_info.user_id],
'whole wheat bread' [primary_selection.vehicle_for_sauce],
'avocado' [primary_selection.topping],
'mayo' [primary_selection.sauce_type],
NULL [secondary_selection.vehicle_for_mayo],
NULL [secondary_selection.topping],
NULL [secondary_selection.sauce_type]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
SELECT @JSON_WITHOUT_NULLS
DECLARE @EMPTY_OBJECT NVARCHAR(2) = '{}'
SELECT @JSON_WITHOUT_NULLS = JSON_MODIFY(@JSON_WITHOUT_NULLS,'$.secondary_selection',JSON_QUERY(@EMPTY_OBJECT))
SELECT @JSON_WITHOUT_NULLS
另一种可能的选择是下面的语句。您需要使用 FOR JSON PATH
.
请注意,您需要调用 JSON_QUERY()
以防止转义特殊字符。文档中对此进行了解释:JSON_QUERY return 是一个有效的 JSON 片段。因此,FOR JSON 不会转义 JSON_QUERY return 值中的特殊字符。如果您 return 使用 FOR JSON 计算结果,并且您要包括已经采用 JSON 格式的数据(在列中或作为表达式的结果),请将 JSON 数据 JSON_QUERY 没有路径参数 .
DECLARE @JSON_WITHOUT_NULLS NVARCHAR(max)
SELECT @JSON_WITHOUT_NULLS = (
SELECT
administrative_info = JSON_QUERY((
SELECT '123456' [account_num], '1' [user_id]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)),
primary_selection = JSON_QUERY((
SELECT 'whole wheat bread' [vehicle_for_sauce], 'avocado' [topping], 'mayo' [sauce_type]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)),
secondary_selection = JSON_QUERY((
SELECT NULL [vehicle_for_mayo], NULL [topping], NULL [sauce_type]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
))
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
结果:
{
"administrative_info":{
"account_num":"123456",
"user_id":"1"
},
"primary_selection":{
"vehicle_for_sauce":"whole wheat bread",
"topping":"avocado",
"sauce_type":"mayo"
},
"secondary_selection":{
}
}