Dro*_*dOS 8 sqlite json sql-update sqlite-json1
SQLite JSON1 扩展有一些非常巧妙的功能。但是,我无法弄清楚如何更新或插入单个 JSON 属性值。
这是一个例子
CREATE TABLE keywords
(
id INTEGER PRIMARY KEY,
lang INTEGER NOT NULL,
kwd TEXT NOT NULL,
locs TEXT NOT NULL DEFAULT '{}'
);
CREATE INDEX kwd ON keywords(lang,kwd);
Run Code Online (Sandbox Code Playgroud)
我使用此表来存储关键字搜索并记录对象中启动搜索的位置locs。此数据库表中的示例条目如下所示
id:1,lang:1,kwd:'stackoverflow',locs:'{"1":1,"2":1,"5":1}'
Run Code Online (Sandbox Code Playgroud)
这里的位置对象属性是存储在其他地方的实际位置的索引。
现在想象一下以下场景
stackoverflow从位置索引“2”开始搜索。在这种情况下,我只想增加该索引处的值,以便在操作之后相应的行读取
id:1,lang:1,kwd:'stackoverflow',locs:'{"1":1,"2": 2 ,"5":1}'
从先前未知的位置索引“7”开始搜索stackoverflow,在这种情况下,更新后的相应行必须读取
id:1,lang:1,kwd:'stackoverflow',locs:'{"1":1,"2":1,"5":1, "7":1 }'
我不清楚这实际上是否可以做到。我尝试了一些类似的事情
UPDATE keywords json_set(locs,'$.2','2') WHERE kwd = 'stackoverflow';
Run Code Online (Sandbox Code Playgroud)
这给出了错误消息error near json_set。我非常感谢任何能够告诉我如何/是否应该/可以完成此操作的人。
小智 7
没有必要创建如此复杂的带有子查询的 SQL 来执行此操作。
下面的 SQL 可以满足您的需求。
UPDATE keywords
SET locs = json_set(locs,'$.7', IFNULL(json_extract(locs, '$.7'), 0) + 1)
WHERE kwd = 'stackoverflow';
Run Code Online (Sandbox Code Playgroud)
我知道这很旧,但它就像搜索时的第一个链接,它值得一个更好的解决方案。
我本可以删除这个问题,但考虑到 SQLite JSON1 扩展似乎相对不太被理解,我觉得在这里提供一个答案会更有用,以造福于其他人。我在这里打算做的事情是可能的,但 SQL 语法相当复杂。
UPDATE keywords set locs =
(select json_set(json(keywords.locs),'$.**N**',
ifnull(
(select json_extract(keywords.locs,'$.**N**') from keywords where id = '1'),
0)
+ 1)
from keywords where id = '1')
where id = '1';
Run Code Online (Sandbox Code Playgroud)
将完成我在上面的原始问题中描述的两项更新。考虑到这看起来有多复杂,有一些解释是有序的
UPDATE keywords部分进行实际更新,但它需要知道要更新什么SELECT json_set部分是我们建立要更新的值的地方+ 1空值执行操作,因此我们进行IFNULL测试WHERE id =位确保我们瞄准正确的行现在在 SQLite 中使用 JSON1 一段时间后,我有一个技巧可以与其他走同样道路的人分享。为了执行就地 JSON 操作,很容易浪费时间编写极其复杂且难以维护的 SQL。考虑在内存表中使用 SQLite -CREATE TEMP TABLE...存储中间结果并编写一系列 SQL 语句。这使得代码更容易理解和维护。
| 归档时间: |
|
| 查看次数: |
5664 次 |
| 最近记录: |