简体   繁体   中英

How to implement Room database query at runtime or dynamically

I need to create a room database query dynamically because I have lots of fields for UPDATE in the database.

If I used like below method then it works, but I have lots of fields that's why I can't create a separate UPDATE method like this.

@Query("UPDATE PROCEDUREMODEL SET patient_in_time = :val WHERE procedure_sr_number LIKE :sr")
void updateP(String val, String sr);

Now I try below but it does not work.

In DAO class I created this

@RawQuery
ProcedureModel updateProcedure(SupportSQLiteQuery supportSQLiteQuery);

And use like this

public static void updateProcedure(Context context, String colName, String val, String id) {
    String s = "UPDATE PROCEDUREMODEL SET " + colName + " = :" + val + " WHERE procedure_sr_number LIKE :" + id;
    SupportSQLiteQuery supportSQLiteQuery = new SimpleSQLiteQuery(s);
    Thread thread = new Thread(() -> {
        DatabaseHelper.getInstance(context).getDao().updateProcedure(supportSQLiteQuery);
    });
    thread.start();
}

I want to run the UPDATE query at runtime in Room database.

I believe that your issue is with the SQL being passed:-

 String s = "UPDATE PROCEDUREMODEL SET " + colName + " = :" + val + " WHERE procedure_sr_number LIKE :" + id;

As the value val is non-numeric, because of the : 's (which you probably don't want), likewise for the id (if not numeric) the values should be enclosed in single quotes.

So using:-

String s = "UPDATE PROCEDUREMODEL SET " + colName + " = ':" + val + "' WHERE procedure_sr_number LIKE '" + id + "'";

would work. Although you very likely don't want the : as part of the value so you very likely want:-

String s = "UPDATE PROCEDUREMODEL SET " + colName + " = '" + val + "' WHERE procedure_sr_number LIKE '" + id + "'";

Saying that it is not recommended to apply literal values via string concatenation but to utilise parameter binding. This protects against SQL injection. As such you may wish to consider the following version:-

public static void updateProcedureBetter(Context context, String colName, String val, String id) {
    String s = "UPDATE PROCEDUREMODEL SET " + colName + "=? WHERE procedure_sr_number LIKE ?";
    Thread thread = new Thread(() -> {
        DatabaseHelper.getInstance(context).getDao().updateProcedure(new SimpleSQLiteQuery(s,new Object[]{val,id}));
    });
    thread.start();
}
  • notice the ? 's in the SQL these being replaced by the objects in the Object[], the values being properly enclosed by SQLite parameter binding.
    • the replacement is on a 1 by/for 1 basis (first? replace by first object in array, 2nd? by second object....)
  • note also that the intermediate supportSQLiteQuery object has been done away with.
  • component names (tables, columns etc) typically cannot be bound/changed so the column name has to be concatenated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM