Обновление базы данных SQLite с использованием функции замены - PullRequest
0 голосов
/ 16 мая 2018

Я хочу использовать базу данных SQLiteDatabase для выполнения обновления с использованием функции SQLite replace с LIMIT, где SQL будет выглядеть примерно так:

UPDATE tbl SET tel = replace(tel, '0501', '0502') where tel in (SELECT tel FROM tbl WHERE tel LIKE '0501%' ORDER BY tel LIMIT 100);

Это похоже на хороший SQLкак в этом fiddle .

Таким образом, подпись обновления выглядит примерно так:

db.update(String table, ContentValues values, String whereClause, String[] whereArgs)

Так что я попробовал как дикое предположение, используя ContentValues как:

ContentValues cv = new ContentValues();
cv.put("tel","replace( tel, '0511', '0513' )");
int result = db.update(tableName,cv,whereClause,null);

и это не выполняет функцию REPLACE, а воспринимает ее буквально так.

Так как использовать функцию REPLACE с использованием update - вопрос.

Мне нужно знать, сколько строк затронуто.

РЕДАКТИРОВАТЬ: я изменил запрос на допустимый синтаксис SQLite для ссылки на комментарий и теперь вижу, что он действителен, но REPLACE не оценивается.

1 Ответ

0 голосов
/ 17 мая 2018

Удобные методы имеют ограничения в отношении вложенных значений.

Вместо этого вы можете использовать метод execSQL (см. Code re rawQuery), например: -

public long alterRows(String from, String to, int limit) {
    long rv = 0;
    String[] args = new String[]{from,to,from,String.valueOf(limit)};
    String sql = "UPDATE " + TB_TBL +
            " SET " + COL_TBL_TEL + " = replace(" + COL_TBL_TEL + ",?,?) " + //<<<<IGNORE EXPRESSION EXPECTED
            " WHERE rowid IN (" +
            "SELECT rowid FROM " + TB_TBL +
            " WHERE " + COL_TBL_TEL + "=? " +
            "ORDER BY " + COL_TBL_TEL +
            " LIMIT ?" +
            ");" ;
    SQLiteDatabase db = this.getWritableDatabase();
    db.execSQL(sql,args);
    //mDB.rawQuery(sqlxxx,args); //<<<< only does 1 update not 2
    //Ascertain the number of updates
    Cursor csr = db.rawQuery("SELECT changes()",null);
    if (csr.moveToFirst()) {
        rv = csr.getLong(0);
    }
    csr.close();
    Log.d("Updates","Number of updates = " + String.valueOf(rv)); //<<<< LOG number of updates
    return rv;
}

Что можно назвать как: -

    SO50378333DBHelper mDBHlpr = new SO50378333DBHelper(this);
    mDBHlpr.alterRows("0501","0502",2); 
  • Где SO50378333DBHelper - это DatabaseHelper (для моего удобства он назван так), где существует приведенный выше код.

Пример, использованный для тестирования

Ниже приведен полный код, использованный для проверки этого.

Сначала DatabaseHelper SO50378333DBHelper.java

public class SO50378333DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "so50378333";
    public static final int DBVERSION = 1;
    public static final String TB_TBL = "tbl";
    public static final String COL_TBL_TEL = "tel";

    SQLiteDatabase mDB;

    public SO50378333DBHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        mDB = this.getWritableDatabase();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String crt_tbl = "CREATE TABLE IF NOT EXISTS " + TB_TBL +
                "(" +
                COL_TBL_TEL + " TEXT" +
                ")";
        db.execSQL(crt_tbl);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public void loadTBL() {
        ContentValues cv = new ContentValues();
        mDB.beginTransaction();
        mDB.delete(TB_TBL,null,null);
        for (int i = 0; i < 1000; i++) {
            cv.clear();
            if ( i % 4 == 0) {
                cv.put(COL_TBL_TEL,"0501");
            } else {
                cv.put(COL_TBL_TEL,"0504");
            }
            mDB.insert(TB_TBL,null,cv);
        }
        String sql = "SELECT sqlite_version() AS v";
        Cursor csr = mDB.rawQuery(sql,null);
        if (csr.moveToFirst()) {
            Log.d("SQLite VERSION","Version is " + csr.getString(0));
        }
        mDB.setTransactionSuccessful();
        mDB.endTransaction();

    }

    public long alterRows(String from, String to, int limit) {
        long rv = 0;
        String[] args = new String[]{from,to,from,String.valueOf(limit)};
        String sql = "UPDATE " + TB_TBL +
                " SET " + COL_TBL_TEL + " = replace(" + COL_TBL_TEL + ",?,?) " + //<<<<IGNORE EXPRESSION EXPECTED
                " WHERE rowid IN (" +
                "SELECT rowid FROM " + TB_TBL +
                " WHERE " + COL_TBL_TEL + "=? " +
                "ORDER BY " + COL_TBL_TEL +
                " LIMIT ?" +
                ");" ;
        SQLiteDatabase db = this.getWritableDatabase();
        db.execSQL(sql,args);
        //mDB.rawQuery(sqlxxx,args); //<<<< only does 1 update not 2
        //Ascertain the number of updates
        Cursor csr = db.rawQuery("SELECT changes()",null);
        if (csr.moveToFirst()) {
            rv = csr.getLong(0);
        }
        csr.close();
        Log.d("Updates","Number of updates = " + String.valueOf(rv)); //<<<< LOG number of updates
        return rv;
    }
}
  • Смотрите комментарии // <<<< </li>
  • rawQuery фактически не обновляет ни одной строки, даже если функция changes () указывает, что она обновила 1 вместо 2. Вероятно, это связано с тем, что она сообщает о последней вставке из-за того, что rawQuery не выполняет никаких обновлений. .
  • rawQuery не обновляется, так как до тех пор, пока не будет получен результат (курсор) (например, moveToFirst ()) (что не так), он будет выполнять свою работу.

Второй вызывающий код внутри действия ( MainActivity.java )

    SO50378333DBHelper mDBHlpr = new SO50378333DBHelper(this);
    mDBHlpr.loadTBL();
    mDBHlpr.alterRows("0501","0502",2);
  • Обратите внимание, что вызов loadTBL загружает данные в таблицу (удаляя все строки перед этим). 1000 строк вставлено, каждая первая строка 4 будет "0501" (250), все остальные строки (750) будут "0504"

Результаты в журнале сверху: -

05-16 23:19:31.554 2622-2622/? D/SQLite VERSION: Version is 3.7.11
05-16 23:19:31.558 2622-2622/? D/Updates: Number of updates = 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...