Android 中的 SQLite“更新后”触发器不会在每次记录更新后出现 运行

SQLite “after update” trigger in Android does not appear to run after every record update

问题: 什么,如果有的话,可能会导致 SQLite 触发器仅 运行 某些时间?

摘要: 我在 SQLite 中编写的新触发器得到的结果看似不一致,我想了解是否发生了这种情况因为我在我的 SQL/Java 代码中犯了一个错误,或者如果我可能遇到 SQL 触发器可能无法按预期工作的罕见情况。

详情: 在处理 Android 项目时,我遇到了我最初认为是 SQLite 触发器的问题。但是,由于我的新触发器与同一个项目中的其他几个工作触发器完全匹配(table 名称除外),我开始怀疑我的 Java 代码是否是问题所在。

我遇到麻烦的触发器的目的是监视对 TableA 的更改,例如在 DismissDateUTC 列中添加一个值。当对 TableA 中的任何数据进行更新时,触发器应该将更新后的 TableA 记录的 ID 放入 TableAChanges 中,稍后用于确定更新了哪些记录并应将其发送回 Web 服务器。

当使用数据库检查器(在 Android Studio v4.2.1 中)或程序“DB Browser for SQLite”和 运行手动对 TableA 进行更新查询时,触发器完全按预期工作,记录出现在 TableAChanges 中。当我以编程方式对 TableA 进行更新时,触发器不会显示为 运行。我相信它不是 运行ning,因为在将更新写入 TableA 后,没有记录写入 TableAChanges。

到目前为止我尝试过的事情:

表和触发器 SQL:

CREATE TABLE TableA (
    ID INTEGER PRIMARY KEY NOT NULL 
    -- (more table columns) --
    , DismissDateUTC TEXT NULL
);

CREATE TABLE TableAChanges (
    ID INTEGER PRIMARY KEY NOT NULL
);

CREATE TRIGGER trigTableA_U AFTER UPDATE ON TableA
BEGIN
    REPLACE INTO TableAChanges(ID)
        SELECT old.ID;  
END

TableA DAO中的AndroidJavaclass:

public boolean saveChanges() {
    boolean ret = true;
    
    ContentValues cv = new ContentValues();
    cv.put("ID", mId);
    // (more table columns)
    cv.put("DismissDateUtc", mDismissDateUtc);

    SQLiteDatabase db = DB.getInstance().getWritableDatabase();
    try {
        db.replaceOrThrow("TableA", null, cv);
    } catch (SQLException e) {
        ExceptionDao.logToAcra(e);
        ret = false;
    } finally {
        db.close();
    }
    
    return ret;
}

*** 为了透明起见,我已经知道我可以通过手动将记录写入 TableAChanges 来解决此问题。但是,我还是想在这里post这个问题,因为我希望了解这个问题的原因,而不是忽略这个问题。

触发器不起作用的原因是因为它是一个AFTER UPDATE触发器,这意味着它只有在table更新后才会起作用。

另一方面,replaceOrThrow() 不更新 table。
它实际上是在执行一个 INSERT OR REPLACE INTO... 或简单的 REPLACE INTO... 语句,如果 table 中不存在新的 ID 则在 table 中插入一个新行,或者如果存在,则删除包含现有 ID 的行并插入新行。