6

来自 sqlite3 文档

select json_insert('{"a":2,"c":4}', '$.e', 99) -- → '{"a":2,"c":4,"e":99}'

但是如何将新元素附加到数组中?

select json_insert('[1,2,3]', ??, 4) -- → '[1, 2, 3, 4]'
update someTable set someArray = json_insert(someArray, ??, 'some new value') 
4

3 回答 3

6

经过几次尝试,我终于想通了

update some_table
  set some_array = json_insert(
    some_array,
    '$[' || json_array_length(some_array) || ']',
    'new item'
  )
  where id = some_id;
于 2018-03-26T05:02:29.330 回答
2

显然没有功能或简单的方法可以做到这一点,但我们可以通过以下方式实现:

  • 将每个数组值分成一行json_each
  • 为我们要添加的值添加行UNION ALL
  • 用子查询对它们进行分组,然后GROUP BY
  • 将它们包装在一起json_group_array

例如,如果您有一个Messages包含 PRIMARY KEY 的表id和一个 JSON 数组 in account,您可以在所有行中向 account 数组中添加一个元素:

SELECT id, json_group_array(value) FROM (
    SELECT Messages.id, json_each.value
    FROM Messages, json_each(Messages.account)
    UNION ALL SELECT Messages.id, 'new_account' FROM Messages
) GROUP BY id;

我们需要再次包装以放入 aUPDATE因为 SQLite 不支持UPDATE+ JOIN。这会将新帐户添加到所有行:

UPDATE Messages SET account = (SELECT account FROM (
    SELECT id, json_group_array(value) as account FROM (
        SELECT Messages.id, json_each.value
        FROM Messages, json_each(Messages.account)
        UNION ALL SELECT Messages.id, 'new_account' FROM Messages
    ) GROUP BY id
) WHERE id = Messages.id);

如果您只想像这样更新一行,我们可以简化这一点:

UPDATE Messages SET account = (
    SELECT json_group_array(value) FROM (
        SELECT json_each.value
        FROM Messages, json_each(Messages.account)
        WHERE Messages.id = 123456789
        UNION ALL SELECT 'new_account'
    ) GROUP BY ''
) WHERE id = 123456789;
于 2018-03-25T03:45:28.087 回答
2

在3.31.0版本中引入了一个新的符号来直接支持这个功能:

select json_insert('[1,2,3]', '$[#]', 4) -- → '[1, 2, 3, 4]'
于 2021-04-17T20:38:25.727 回答