使用 JSON1 在 SQLite 中更新 JSON

Updating JSON in SQLite with 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);

我正在使用此 table 来存储关键字搜索并记录在对象 locs 中启动搜索的位置。此数据库中的示例条目 table 如下所示

 id:1,lang:1,kwd:'Whosebug',locs:'{"1":1,"2":1,"5":1}'

此处的位置对象属性是存储在别处的实际位置的索引。

现在想象一下下面的场景

我不清楚这是否真的可以做到。我尝试了一些类似

的方法
UPDATE keywords json_set(locs,'$.2','2') WHERE kwd = 'Whosebug';

给出了错误信息 error near json_set。如果有人能告诉我 how/whether 这个 should/can 完成,我将非常感激。

我本可以删除这个问题,但考虑到 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';

将完成我在上面的原始问题中描述的两项更新。鉴于这看起来有多复杂,一些解释是有序的

  • UPDATE keywords 部分进行实际更新,但它需要知道要更新什么
  • SELECT json_set 部分是我们建立要更新的值的地方
  • 如果首先不存在相关值,我们不想对空值执行 + 1,因此我们执行 IFNULL TEST
  • WHERE id = 位确保我们定位正确的行

现在我在 SQLite 中与 JSON1 合作了一段时间,我有一个提示可以与其他走同一条路的人分享。为了执行就地 JSON 操作,编写极其复​​杂且难以维护的 SQL 很容易浪费您的时间。考虑在内存表中使用 SQLite - CREATE TEMP TABLE... 来存储中间结果并改为编写一系列 SQL 语句。这使得代码更易于理解和维护。

没有必要创建如此复杂的 SQL 子查询。

下面的SQL可以解决您的需求。

UPDATE keywords 
SET locs = json_set(locs,'$.7', IFNULL(json_extract(locs, '$.7'), 0) + 1) 
WHERE kwd = 'Whosebug';

我知道这是旧的,但它就像搜索时的第一个 link,值得更好的解决方案。