Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sqlite 在更新时获取行id_Sqlite_Upsert - Fatal编程技术网

Sqlite 在更新时获取行id

Sqlite 在更新时获取行id,sqlite,upsert,Sqlite,Upsert,假设我有一个如下结构的表: | name | Type | | ----------- |:-------------:| | id | primary | | word | unique | | frequency | integer | 对于这个表,我正在进行插入,当出现重复时,我将更新频率列。伪代码如下所示: try { INSERT into WORDLIST word1

假设我有一个如下结构的表:

| name        | Type          |
| ----------- |:-------------:|
| id          | primary       |
| word        | unique        |
| frequency   | integer       |
对于这个表,我正在进行插入,当出现重复时,我将更新频率列。伪代码如下所示:

try {
    INSERT into WORDLIST word1
    id = lastInsertedId
} catch(Exception) {
    //if a duplicate happens
    UPDATE wordlist WHERE word = "word1"
    id = SELECT id FROM wordlist where word = "word1"
}
//save the updated/inserted id somewhere
上面代码的问题是,当重复发生时,我被迫执行额外的select查询以获取更新行的id,这是一个性能问题,会使应用程序的速度降低约30%


我对其他方法持开放态度,但我想不出比这种带有额外查询的try/catch方法更好的方法了。UPDATE语句无法返回数据。如果需要ID,则需要运行SELECT

请注意,任何插入或更新都必须检查
word
列中是否有重复项,因此SELECT将完全从缓存运行。任何减速都可能来自使用自动事务运行多个更改

此外,如果存在任何其他错误,依赖异常来检测复制将崩溃。最好先检查副本(不会因为上述原因而降低效率):


由于
word
已经有一个唯一的索引,您可以尝试使用以下方法简化查询:

请注意,在冲突情况下,将创建一个新的rowid/ID,并删除旧的rowid/ID。如果需要保留ID,可以使用触发器,这可能比在应用程序代码中处理特殊情况更好


如果您只想实现一个点击计数器,您可以查看以下答案:

谢谢您的回复。我已经尝试过这种方法,但它比try/catch慢。上面的代码经过了简化,当然只是为了指出问题所在,catch块会检查它是否是一个完整性约束错误,并且还会处理其他情况。为了进一步解释我的情况,以及为什么上面的用例没有如预期的那样提高性能。如果表中有100个不存在的单词,则将运行100次SELECT和100次INSERT。使用try-catch方法,只有INSERT发生,因此当表为空时,只有INSERT被命中,并且在数据集增长之后,它开始命中更多更新并选择。因此,在某些情况下,您的方法会更有效。这有点取决于数据集。但基于平均数据集,try/catch似乎更快更具意义,它是一个文本索引器,可以索引数百万个文本文档,因此即使是一个小小的改进也可以节省大量时间我知道更新不会返回数据,但是,当它无法返回失败行的ID时,是否可以强制插入?请提供一个。好吧,如果没有大型数据集,我无法向您展示一个示例,这里的代码非常完美,但我有一些问题:插入或替换到wordlist(术语,频率)值(“word”,频率+1)似乎无法说明列频率不存在。当发生重复关键点约束时,我需要增加frequency@Nenad如果我做对了,这是一种;看我的更新。是的,你说得对,我会接受你的答案,因为它回答了最初的问题
BEGIN;
SELECT id FROM wordlist WHERE word = ?;
if found:
    UPDATE wordlist ... WHERE id = ?;   -- faster than word=?
else:
    INSERT INTO wordlist;
COMMIT;
INSERT OR REPLACE into WORDLIST word1
id = last_insert_rowid()