Как обновить и увеличить базу данных? - PullRequest
1 голос
/ 28 апреля 2019

У меня есть код для функции удаления, которая работает.Столбцы в БД: COL_TASK_TITLE и COL_NUM.моя функция приращения не работает.Я также предоставил функцию удаления ниже, которая полностью работает.

   public void deleteTask(View view) {

        View parent = (View) view.getParent();
        TextView taskTextView = (TextView) 
        parent.findViewById(R.id.task_title);
        String task = String.valueOf(taskTextView.getText());
        SQLiteDatabase db = mHelper.getWritableDatabase();
        db.delete(TaskContract.TaskEntry.TABLE,
        TaskContract.TaskEntry.COL_TASK_TITLE + " = ?",
        new String[]{task});
        db.close();
        updateUI();
    }


    public void incrment(View view) {
        View parent = (View) view.getParent();
        TextView taskTextView = (TextView) 
        parent.findViewById(R.id.task_title);
        String task = String.valueOf(taskTextView.getText());
        SQLiteDatabase db = mHelper.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("COL_NUM",COL_NUM+1)
        db.update(TaskContract.TaskEntry.TABLE,cv
            TaskContract.TaskEntry.COL_TASK_TITLE + " = ?",
            new String[]{task});
        db.close();
        updateUI();
    }

Ответы [ 2 ]

1 голос
/ 28 апреля 2019

При использовании метода обновления значение во втором параметре введенного ContentValues ​​(т. Е. COL_NUM + 1) обрабатывается как строка и заключается в одинарные кавычки, поэтому результирующее значение становится строкой COL_NUM1 которое в конечном итоге является значением, хранящимся в столбце, указанном 1-м параметром.

  • Заключение значений предназначено, по крайней мере частично, для защиты от SQL-инъекций. Однако в таких случаях это немного мешает.

В таком случае вы можете выполнить SQL напрямую с помощью метода execSQL . Для защиты от внедрения SQL вы можете использовать execSQL , который принимает два параметра. Второй параметр, являющийся аргументами, которые заменят? заполнители. ExecSQL .

  • Где написано Выполнить одну инструкцию SQL, которая НЕ является SELECT / INSERT / UPDATE / DELETE. На самом деле это не так. Скорее это (должно быть) предупреждение согласно (из execSQL, который не принимает 2-й параметр)
  • У него нет средств для возврата каких-либо данных (например, количества затронутых строки). Вместо этого вам рекомендуется использовать insert (java.lang.String, java.lang.String, android.content.ContentValues), обновление (java.lang.String, android.content.ContentValues, java.lang.String, java.lang.String []) и др., когда это возможно.

То есть запустить SQL UPDATE the_table SET COL_NUM = COL_NUM + 1 WHERE COL_TASK_TITLE = the_title

  • (где the_table и the_title соответственно изменены).

  • метод обновления генерирует и выполняет SQL UPDATE the_table SET COL_NUM = 'COL_NUM1' WHERE COL_TASK_TITLE = 'the_title'. Отсюда и проблема.

Вы можете использовать следующий метод: -

public void incrment(View view) {
    View parent = (View) view.getParent();
    TextView taskTextView = (TextView) 
    parent.findViewById(R.id.task_title);
    String task = String.valueOf(taskTextView.getText());        
    SQLiteDatabase db = mHelper.getWritableDatabase();

    db.execSQL(
            "UPDATE " + TaskContract.TaskEntry.TABLE +
            " SET " + TaskContract.TaskEntry.COL_NUM + " = " + 
            TaskContract.TaskEntry.COL_NUM + "+ 1 " +
            " WHERE " + TaskContract.TaskEntry.COL_TASK_TITLE + " = ?",
            new String[]{task}
    );

    /*
    // Alternative with COL_NUM hard coded rather than retrieved via TaskContract.TaskEntry.COL_NUM
    db.execSQL("UPDATE " + TaskContract.TaskEntry.TABLE +
            " SET COL_NUM  = COL_NUM + 1 " +
            "WHERE " +TaskContract.TaskEntry.COL_TASK_TITLE + " = ?"
            ,new String[]{task}
            );
    */
    db.close();
    updateUI();
}
  • Предполагается, что TaskContract.TaskEntry.COL_NUM определен (использование одного источника для имен снижает вероятность ошибок, если нет, тогда вы используете закомментированную альтернативу, которая использует жестко закодированный COL_NUM (удаляя или комментируя БД). execSQL в настоящее время используется)
0 голосов
/ 28 апреля 2019

Я думаю, COL_NUM это название столбца, верно?Так что эта строка неверна:

cv.put("COL_NUM", COL_NUM + 1);

, потому что вы думаете, что добавляете число к значению столбца, где в действительности вы объединяете 1 с именем столбца.То, что вы должны сделать, это увеличить текущее значение на 1 следующим образом:

db.execSQL(
    "update " + TaskContract.TaskEntry.TABLE + 
    " set " + COL_TaskContract.TaskEntry.COL_NUM + " = " + COL_TaskContract.TaskEntry.COL_NUM + " + 1" + 
    " where " + TaskContract.TaskEntry.COL_TASK_TITLE + " = ?", new Object[] {task});

Если есть случай, когда COL_NUM равен null, измените выражение на следующее:

db.execSQL(
    "update " + TaskContract.TaskEntry.TABLE + 
    " set " + COL_TaskContract.TaskEntry.COL_NUM + " = coalesce(" + COL_TaskContract.TaskEntry.COL_NUM + ", 0) + 1" + 
    " where " + TaskContract.TaskEntry.COL_TASK_TITLE + " = ?", new Object[] {task});

Итак, измените ваш метод следующим образом:

public void incrment(View view) {
    View parent = (View) view.getParent();
    TextView taskTextView = (TextView) parent.findViewById(R.id.task_title);
    String task = taskTextView.getText().toString();
    SQLiteDatabase db = mHelper.getWritableDatabase();
    db.execSQL(
        "update " + TaskContract.TaskEntry.TABLE +
        " set " + COL_TaskContract.TaskEntry.COL_NUM + " = coalesce(" + COL_TaskContract.TaskEntry.COL_NUM + ", 0) + 1" +
        " where " + TaskContract.TaskEntry.COL_TASK_TITLE + " = ?", new Object[] {task}
    );
    db.close();
    updateUI();
}

Конечно, вы можете использовать метод update(), как и вы, но сначала вы должны найти существующее значение в COL_NUM, увеличить его, поставить егов cv и затем выполните update().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...