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

Viewed 148

QUESTION: What, if anything, could cause an SQLite trigger to only run some of the time?

SUMMARY: I'm getting seemingly inconsistent results from a new trigger I've written in SQLite and I'd like to understand if this is happening because I've made a mistake in my SQL/Java code or if I've possibly encountered a rare scenario where SQL triggers may not work as expected.

DETAILS: While working on an Android project I have encountered what I originally perceived to be a problem with an SQLite trigger. However, since my new trigger exactly matches several other working triggers in the same project (except for the table names) I am beginning to wonder if my Java code is the issue instead.

The purpose of the trigger I am having trouble with is to monitor changes to TableA, such as the addition of a value in the DismissDateUTC column for example. When an update is made to any data in TableA, the trigger is supposed to put the ID of that updated TableA record into TableAChanges which is later used to determine which records were updated and should be sent back to a web server.

When using the database inspector (in Android Studio v4.2.1) or the program “DB Browser for SQLite” and running an update query on TableA manually, the trigger works exactly as expected and records appear in TableAChanges. When I make updates to TableA programmatically, the trigger does not appear to run. I believe it is not running because no records are written to TableAChanges after updates have been written to TableA.

Things I have tried so far:

  • Running the app on an Android 7.1.1 device (trigger is NOT working)
  • Running the app on an Android 8.1.0 device (trigger is NOT working)
  • Running the app on an Android 11 device (trigger is NOT working)
  • Running manual update query on TableA from Android Studio DB Inspector (trigger IS working)
  • Running manual update query on TableA from DB Browser for SQLite (trigger IS working)
  • Running manual update query on TableA from Android Debug Database by “amitshekhar” (trigger IS working)

The Tables and Trigger 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

The Android Java in the TableA DAO class:

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;
}

*** In the interest of transparency, I am already aware that I can work around this issue by manually writing records to TableAChanges. However, I still wanted to post this question here because I am hoping to gain an understanding of the cause of this issue rather than ignoring the issue.

1 Answers

The reason that the trigger does not work is because it is an AFTER UPDATE trigger, which means that it will work only after the table is updated.

On the other hand, replaceOrThrow() does not update the table.
It is actually executing an INSERT OR REPLACE INTO... or simply REPLACE INTO... statement which either inserts a new row in the table if the new ID does not already exist in the table, or if it exists, deletes the row that contains the existing ID and inserts the new row.

Related