在SQLite中的一个语句中递增计数器或插入行

时间:2010-09-05 19:31:34

标签: sql sqlite query-optimization

在SQLite中,给定此数据库架构

CREATE TABLE observations (
    src TEXT,
    dest TEXT,
    verb TEXT,
    occurrences INTEGER
);
CREATE UNIQUE INDEX observations_index
    ON observations (src, dest, verb);

每当有新的观察元组(:src, :dest, :verb)进来时,我想要为该元组的现有行递增“occurrence”列,或者如果还没有,则添加一个出现次数= 1的新行。具体的伪代码:

if (SELECT COUNT(*) FROM observations
        WHERE src == :src AND dest == :dest AND verb == :verb) == 1:
    UPDATE observations SET occurrences = occurrences + 1
        WHERE src == :src AND dest == :dest AND verb == :verb
else:
    INSERT INTO observations VALUES (:src, :dest, :verb, 1)

我想知道是否可以在一个SQLite语句中执行整个操作。这将简化应用程序逻辑(这需要与数据库操作完全异步)并且还避免使用完全相同的密钥进行双索引查找。 INSERT OR REPLACE似乎不是我想要的,唉没有UPDATE OR INSERT。

2 个答案:

答案 0 :(得分:12)

我在sqlite-users上得到了Igor Tandetnik的答案:

INSERT OR REPLACE INTO observations
VALUES (:src, :dest, :verb,
  COALESCE(
    (SELECT occurrences FROM observations
       WHERE src=:src AND dest=:dest AND verb=:verb),
    0) + 1);

它略微但始终比dan04的方法更快。

答案 1 :(得分:3)

不知道如何在一个声明中执行此操作,但您可以尝试

BEGIN;
    INSERT OR IGNORE INTO observations VALUES (:src, :dest, :verb, 0);
    UPDATE observeraions SET occurrences = occurrences + 1 WHERE
        src = :src AND dest = :dest AND verb = :verb;
COMMIT;