SQLite插入或替换的奇怪行为

时间:2015-04-11 16:58:51

标签: python sqlite insert increment

如果该行存在,我试图增加SQLite数据库中的行数,或者如果它不存在则添加新行(如果在SO帖子中完成的话。但是,当我尝试快速连续多次执行此SQL proc时,我会遇到一些奇怪的行为。作为示例,我尝试运行此代码:

db = connect_to_db()
c = db.cursor()
for i in range(10):
    c.execute("INSERT OR REPLACE INTO subject_words (subject, word, count) VALUES ('subject', 'word', COALESCE((SELECT count + 1 FROM subject_words WHERE subject = 'subject' AND word = 'word'), 1));")
    db.commit()
db.close()

并将以下内容插入数据库

sqlite> select * from subject_words;
subject|word|1
subject|word|2
subject|word|2
subject|word|2
subject|word|2
subject|word|2
subject|word|2
subject|word|2
subject|word|2
subject|word|2

对于主题为'subject'的单词'word'的19个条目总计。任何人都可以解释这种奇怪的行为吗?

2 个答案:

答案 0 :(得分:1)

我认为您并不了解INSERT OR REPLACE实际上做了什么。只有在无法进行插入时才会发挥REPLACE子句的作用,因为违反了唯一约束。例如,您的subject列是主键。

但是,没有任何主键或其他约束,通过插入具有相同主题的多行,不会有任何违反;所以没有理由调用REPLACE子句。

答案 1 :(得分:1)

如果使用两个SQL语句执行此操作,则更容易编写和理解:

c.execute("""UPDATE subject_words SET count = count + 1
             WHERE subject = ? AND WORD = ?""",
          ['subject', 'word'])
if c.rowcount == 0:
    c.execute("INSERT INTO subject_words (subject, word, count) VALUES (?,?,?)",
              ['subject', 'word', 1])

这不需要对要检查的列具有UNIQUE约束,效率也不高。