Sql 用于JSON时,获取值数组而不是对象数组
我正在尝试展平一个对象数组,它是由JSON的Sql 用于JSON时,获取值数组而不是对象数组,sql,json,sql-server,tsql,for-json,Sql,Json,Sql Server,Tsql,For Json,我正在尝试展平一个对象数组,它是由JSON的构建的 我的查询如下所示: select ( select id from MyTable where id in (select value from OPENJSON(@jsonArray)) FOR JSON PATH ) existing, ( select value id from OPENJSON(@jsonAr
构建的
我的查询如下所示:
select
(
select id from MyTable
where id in (select value from OPENJSON(@jsonArray))
FOR JSON PATH
) existing,
(
select value id from OPENJSON(@jsonArray)
where value not in (select Id from MyTable)
FOR JSON PATH
) missing
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
生成的JSON是:
{
"existing": [
{
"id": "a00cd8f6-d1c6-4604-b235-59d3cacd5bcc"
},
{
"id": "052455b6-6bf5-47d3-8bee-7ba98d7fbd50"
}
],
"missing": [
{
"id": "328add2d-e8f2-4a0e-af54-5b1733310170"
}
]
}
我想要的是:
{
"existing": [
{
"id": "a00cd8f6-d1c6-4604-b235-59d3cacd5bcc"
},
{
"id": "052455b6-6bf5-47d3-8bee-7ba98d7fbd50"
}
],
"missing": [
"328add2d-e8f2-4a0e-af54-5b1733310170"
]
}
缺少的数组不应包含json对象,而应包含值。
有什么建议吗?如果您使用的是SQL Server 2017,您可以使用JSON\u QUERY
和STRING\u AGG
构建您的数组(对于SQL Server 2016,您不能使用STRING\u AGG
,因此您需要做一些estra工作,但以下想法仍然有效):
结果:
{
"existing": [
{
"id": "a00cd8f6-d1c6-4604-b235-59d3cacd5bcc"
},
{
"id": "052455b6-6bf5-47d3-8bee-7ba98d7fbd50"
}
],
"missing": [
"328add2d-e8f2-4a0e-af54-5b1733310170"
]
}
这并不像应该的那么容易
抱歉,没有办法用sql server创建一个裸json数组。但您可以在字符串级别上解决此问题:
DECLARE @exist TABLE(id VARCHAR(100));
DECLARE @miss TABLE(id VARCHAR(100));
INSERT INTO @exist VALUES ('exist1'),('exist2');
INSERT INTO @miss VALUES ('miss1'),('miss2');
--这将创建所需的对象数组
SELECT id FROM @exist
FOR JSON PATH
--这将使用一些相当丑陋的技巧创建裸阵列
SELECT REPLACE(REPLACE(REPLACE(
(
SELECT id from @miss
FOR JSON PATH
),'"id":',''),'{',''),'}','')
--现在我们必须把两者结合起来。我们需要一个技巧。我们在JSON文本上使用JSON\u QUERY()
,以避免转义引号
SELECT
(
SELECT id FROM @exist
FOR JSON PATH
) AS existing
,JSON_QUERY(
REPLACE(REPLACE(REPLACE(
(
SELECT id from @miss
FOR JSON PATH
),'"id":',''),'{',''),'}','')
) AS missing
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;
这就是结果
{
"existing":[{"id":"exist1"},{"id":"exist2"}] <--array of objects
,"missing":["miss1","miss2"] <--array of naked values
}
{
“existing”:[{“id”:“exist1”},{“id”:“exist2”}]使用从游标追加
DECLARE @missing nvarchar(max),
@json nvarchar(max) = (select
(
select id from MyTable
where id in (select value from OPENJSON(@jsonArray))
FOR JSON PATH
) existing
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
DECLARE missing_cursor CURSOR FOR
select value id
from OPENJSON(@jsonArray)
where value not in (select Id from MyTable)
OPEN missing_cursor
FETCH NEXT FROM missing_cursor
INTO @missing
WHILE @@FETCH_STATUS = 0
BEGIN
SET @json = JSON_MODIFY(@json,'append $.missing', @missing)
FETCH NEXT FROM missing_cursor
INTO @missing
END
CLOSE missing_cursor;
DEALLOCATE missing_cursor;
select @json
如果id
包含任何要转义的字符,则QUOTENAME
将不会生成有效的JSON。我建议改用'“+STRING”转义(id,'JSON')+'”
(即使在作为GUID的id
的情况下这并不重要)@jeroemostert没有想到这一点:你完全正确!我更新了我的答案,包括STRING\u ESCAPE
,谢谢。如果JSON值本身包含{
或}
字符,这将无法正常工作-替换将无情地删除这些字符。(没有任何JSON值将包含“id”:
当然,这还是安全的。)MS SQL Server中的整个JSON功能对我来说似乎不完整。
DECLARE @missing nvarchar(max),
@json nvarchar(max) = (select
(
select id from MyTable
where id in (select value from OPENJSON(@jsonArray))
FOR JSON PATH
) existing
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)
DECLARE missing_cursor CURSOR FOR
select value id
from OPENJSON(@jsonArray)
where value not in (select Id from MyTable)
OPEN missing_cursor
FETCH NEXT FROM missing_cursor
INTO @missing
WHILE @@FETCH_STATUS = 0
BEGIN
SET @json = JSON_MODIFY(@json,'append $.missing', @missing)
FETCH NEXT FROM missing_cursor
INTO @missing
END
CLOSE missing_cursor;
DEALLOCATE missing_cursor;
select @json