如何在 SQLite 中将元素插入数组(json)的中间?

发布于 2025-01-16 01:04:02 字数 544 浏览 6 评论 0原文

我在SQLite文档的json部分找到了一个方法json_insert。但它似乎并没有按照我预期的方式工作。

例如 select json_insert('[3,2,1]', '$[3]', 4) as result;

result 列返回 '[3 ,2,1,4]',这是正确的。

但是对于 select json_insert('[3,2,1]', '$[1]', 4) as result;

我期待类似 '[3,2,4, 1]' 返回,而不是 '[3,2,1]'

我错过了什么吗?我没有看到 json_insert 的替代方法。

PS我正在https://sqlime.org/#demo.db(SQLite)上玩它版本是3.37.2

I found a method json_insert in the json section of the SQLite document. But it seems to be not working in the way that I expected.

e.g. select json_insert('[3,2,1]', '$[3]', 4) as result;

The result column returns '[3,2,1,4]', which is correct.

But for select json_insert('[3,2,1]', '$[1]', 4) as result;

I am expecting something like '[3,2,4,1]' to be returned, instead of '[3,2,1]'.

Am I missing something ? I don't see there is an alternative method to json_insert.

P.S. I am playing it on https://sqlime.org/#demo.db, the SQLite version is 3.37.2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清醇 2025-01-23 01:04:02

文档指出 json_insert() 不会覆盖值“如果已存在则覆盖? - 否”)。这意味着您不能在数组中间插入元素。

我的解释:该函数主要是为了将键插入到对象中,这种行为更有意义——不改变数组的长度是为了一致性的牺牲。

您可以通过将 JSON 数组转换为表、附加元素、对结果进行排序并将其全部转换回 JSON 数组来将其硬塞到 SQLite 中:

select json_group_array(x.value) from (
    select key, value from json_each('[3,2,1]')
    union
    select 1.5, 4  -- 1.5 = after 1, before 2
    order by 1
) x

这将生成 '[3,2,4,1]'

但您可能会发现这无法扩展,即使有一个内置函数可以为您完成此操作,它也无法扩展。字符串操作很慢。对于一次性或不经常这样做的情况来说,它可能效果很好。

从长远来看,我建议正确规范化数据库结构,而不是将“非 blob”数据存储在 JSON blob 中。操作规范化数据比操作 JSON 容易得多,更不用说速度可能快几个数量级了。

The documentation states that json_insert() will not overwrite values ("Overwrite if already exists? - No"). That means you can't insert elements in the middle of the array.

My interpretation: The function is primarily meant to insert keys into an object, where this kind of behavior makes more sense - not changing the length of an array is a sacrifice for consistency.

You could shoehorn it into SQLite by turning the JSON array into a table, appending your element, sorting the result, and turning it all back into a JSON array:

select json_group_array(x.value) from (
    select key, value from json_each('[3,2,1]')
    union
    select 1.5, 4  -- 1.5 = after 1, before 2
    order by 1
) x

This will produce '[3,2,4,1]'.

But you can probably see that this won't scale, and even if there was a built-in function that did this for you, it wouldn't scale, either. String manipulation is slow. It might work well enough for one-offs, or when done infrequently.

In the long run, I would recommend properly normalizing your database structure instead of storing "non-blob" data in JSON blobs. Manipulating normalized data is much easier than manipulating JSON, not to mention faster by probably orders of magnitude.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文