当前位置:  开发笔记 > 前端 > 正文

使用JSON_MODIFY向数组添加范围

如何解决《使用JSON_MODIFY向数组添加范围》经验,为你挑选了1个好方法。

我正在尝试使用将数组添加到另一个数组JSON_MODIFY
情况是,我在数据库中存储了数组类型的json数据。看起来像这样:

declare @base nvarchar(max) = '[{"name":"base"}]';

我得到的另一组数据也是数组形式的:

declare @test1 nvarchar(max) = '[{"name":"test1"},{"name":"example1"}]';

我正在尝试使用JSON_MODIFYJSON_QUERY魔术将它们附加在一起,但这给了我意外的结果。

declare @base nvarchar(max) = '[{"name":"base"}]';
declare @test1 nvarchar(max) = '[{"name":"test1"},{"name":"example1"}]';
set @base = JSON_MODIFY(@base,'append $',JSON_QUERY(@test1));
select @base;

输出:

[{"name":"base"}, [{"name":"test1"},{"name":"example1"}]]

但是我想要的是使用这些方法使其像以下那样工作Add-Range

[{"name":"base"},{"name":"test1"},{"name":"example1"}]

我对这个过程有些迷惑,我不知道在哪里可以找到这种功能。
我将在C#服务中使用它来直接通过代码进行修改。这就是为什么我不能同时使用Store过程和函数的原因。

编辑#1:

关于@Salman A的答复,我非常感谢您的回答,但正如我之前所说,事情很难在通过代码运行的查询中使用。这是:

declare @test1 nvarchar(max) = '[{"name":"test1"},{"name":"example1"}]';
UPDATE dbo.ExampleTable 
   SET [Data] = JSON_MODIFY([Data], 'append $', JSON_QUERY(@test1))
   WHERE [UniqueId] = 'some_guid_here'

我已经尝试过适应我喜欢的答案:

declare @test1 nvarchar(max) = '[{"name":"test1"},{"name":"example1"}]';
UPDATE dbo.ExampleTable 
   SET [Data] = (
      select [Data] = JSON_MODIFY([Data],'append $',item)
      from OPENJSON(@test1)
      with ([item] nvarchar(max) '$' as JSON)
   )
   WHERE [UniqueId] = 'some_id'

实际上,如果@test1只有1个项目,则可以使用,但如果中有1个以上@test1,则会出现错误:

子查询返回的值超过1。当子查询遵循= ....时,不允许这样做。

update set subquery



1> Salman A..:

您可以OPENJSON用来将数组转换为行,并一一追加项目:

declare @base nvarchar(max) = '[{"name":"base"}]';
declare @test1 nvarchar(max) = '[{"name":"test1"},{"name":"example1"}]';

select @base = json_modify(@base, 'append $', item)
from openjson(@test1)
with ([item] nvarchar(max) '$' as json);

select @base;

返回值:

[{"name":"base"},{"name":"test1"},{"name":"example1"}]

修改后的更新查询答案

如果您使用的是SQL Server 2017+,那么一个比较安全的解决方案是使用串联数组,STRING_AGG但使用JSON函数构建单个行。在更新查询中使用此想法相对容易:

DECLARE @base NVARCHAR(MAX) = '[{"name":"base"}]';
DECLARE @test NVARCHAR(MAX) = '[{"foo":"bar"},{"baz":"meh"}]';

SELECT '[' + STRING_AGG(jsonstr, ',') WITHIN GROUP (ORDER BY pos) + ']'
FROM (
    SELECT value, 1000 + [key] FROM OPENJSON(@base)
    UNION ALL
    SELECT value, 2000 + [key] FROM OPENJSON(@test)
) AS x(jsonstr, pos);

或者,您可以使用JSON_MODIFY多次调用的递归CTE 来构建JSON。您可以在更新查询中使用结果:

CREATE TABLE t(
    id INT NOT NULL PRIMARY KEY IDENTITY,
    data NVARCHAR(MAX)
);

INSERT INTO t(data) VALUES
('[{"name":"1.1"}]'),
('[{"name":"2.1"},{"name":"2.2"}]');

WITH rows(data, pos) AS (
    SELECT value, [key]
    FROM OPENJSON('[{"foo":"bar"},{"baz":"meh"}]')
), rcte(id, data, pos) AS (
    SELECT id, data, -1
    FROM t
    UNION ALL
    SELECT prev.id, JSON_MODIFY(prev.data, 'append $', JSON_QUERY(curr.data)), prev.pos + 1
    FROM rcte AS prev
    JOIN rows AS curr ON curr.pos = prev.pos + 1
)
UPDATE t
SET data = (
    SELECT TOP 1 data
    FROM rcte
    WHERE id = t.id
    ORDER BY pos DESC
);

db <> fiddle上的演示

推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有