Android中的SQLite"更新后"触发器似乎不会在每次记录更新后运行



问题:如果有什么原因,会导致SQLite触发器只运行一部分时间?

摘要:我用SQLite编写的一个新触发器的结果似乎不一致,我想知道这是因为我在SQL/Java代码中犯了一个错误,还是因为我可能遇到了SQL触发器可能无法按预期工作的罕见情况。

详细信息:在安卓项目中,我遇到了最初认为是SQLite触发器问题的问题。然而,由于我的新触发器与同一项目中的其他几个工作触发器完全匹配(除了表名(,我开始怀疑我的Java代码是否是问题所在。

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

当使用数据库检查器(在Android Studio v4.2.1中(或程序"DB Browser for SQLite"并手动在TableA上运行更新查询时,触发器会完全按照预期工作,并且记录会显示在TableA更改中。当我以编程方式更新TableA时,触发器似乎不会运行。我认为它没有运行,因为在将更新写入TableA之后,没有记录写入TableA更改。

到目前为止我尝试过的东西:

  • 在Android 7.1.1设备上运行应用程序(触发器不起作用(
  • 在Android 8.1.0设备上运行应用程序(触发器不起作用(
  • 在Android 11设备上运行应用程序(触发器不起作用(
  • 从Android Studio DB Inspector在TableA上运行手动更新查询(触发IS工作(
  • 从DB Browser for SQLite在TableA上运行手动更新查询(触发IS工作(
  • 通过"amitshekhar"在Android调试数据库的TableA上运行手动更新查询(触发IS工作(

表和触发器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类中的Android Java:

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来解决这个问题。但是,我还是想把这个问题放在这里,因为我希望了解这个问题的原因,而不是忽视这个问题。

触发器不工作的原因是因为它是AFTER UPDATE触发器,这意味着它只有在表更新后才能工作

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

最新更新