db.query не может сделать выбор, используя целочисленное поле - PullRequest
1 голос
/ 02 июля 2019

У меня есть БД с 2 таблицами - категориями и задачами, каждая задача имеет поле, связанное с полем категории _id.Проблема заключается в том, что выборка на tasks.category_id = идентификатор текущей категории возвращает пустой курсор.

В режиме отладки видно, что критерии выбора верны;Поля БД проверены и имеют правильные значения;удаление критериев выбора возвращает полную БД правильно.Замена .query на .rawQuery возвращает правильные значения, если весь выбор сделан в первом аргументе.Этот работает хорошо:

  String selection = "select * from task where category_id = " + mId;
  Cursor taskCursor = mDb.rawQuery(selection, null);

MainActivity:

 //request data from categories table
    mDb = mDbOpenHelper.getReadableDatabase();
    final Cursor categoryCursor = mDb.query(CategoryEntry.TABLE_NAME, 
        null,null, null, null, null, null);

    int mCategoryIdPos = mCursor.getColumnIndex(CategoryEntry._ID);
    int mId = mCursor.getInt(mCategoryIdPos);
 //request data from tasks table for the selected category
    String selection = TaskEntry.COLUMN_CATEGORY_ID + " = ?";
    String selectionArgs = Integer.toString(mId);
    Cursor taskCursor = mDb.query(TaskEntry.TABLE_NAME, null, selection, 
        selectionArgs, null, null, null, null)

taskCursor пуст.

DatabaseContractClass:

    public static final class TaskEntry implements BaseColumns {
    public static final String TABLE_NAME = "task";
    public static final String COLUMN_TASK_NAME = "task_name";
    public static final String COLUMN_CATEGORY_ID = "category_id";
    public static final String COLUMN_SKILL_ID = "skill_id";
    public static final String COLUMN_TASK_PD = "task_pd";
    public static final String COLUMN_TASK_DATE = "task_date";
    public static final String COLUMN_TASK_PERIOD = "task_period";
    public static final String COLUMN_TASK_FREQUENCY = "task_frequency";
    public static final String COLUMN_TASK_ONBY = "task_onby";
    public static final String COLUMN_TASK_COMPLETION = 
      "task_completion";

    public static final String SQL_CREATE_TABLE = "CREATE TABLE " + 
         TABLE_NAME + " (" +
            _ID + " INTEGER PRIMARY KEY, " +
            COLUMN_TASK_NAME + " TEXT UNIQUE NOT NULL, " +
            COLUMN_CATEGORY_ID + ", " +
            COLUMN_SKILL_ID + ", " +
            COLUMN_TASK_PD + ", " +
            COLUMN_TASK_DATE + ", " +
            COLUMN_TASK_PERIOD + ", " +
            COLUMN_TASK_FREQUENCY + ", " +
            COLUMN_TASK_ONBY + ", " +
            COLUMN_TASK_COMPLETION + ")";
}

public static final class CategoryEntry implements BaseColumns{
    public static final String TABLE_NAME = "category";
    public static final String COLUMN_CATEGORY_NAME = "category_name";
    public static final String COLUMN_CATEGORY_PD = "category_pd";
    public static final String COLUMN_CATEGORY_DATE = "category_date";
    public static final String COLUMN_CATEGORY_PERIOD = 
   "category_period";
    public static final String COLUMN_CATEGORY_FREQUENCY = 
     "category_frequency";
    public static final String COLUMN_CATEGORY_ONBY = "category_onby";
    public static final String COLUMN_CATEGORY_COMPLETION = 
       "category_completion";

    public static final String SQL_CREATE_TABLE = "CREATE TABLE " + enter 
      code hereTABLE_NAME + " (" +
            _ID + " INTEGER PRIMARY KEY, " +
            COLUMN_CATEGORY_NAME + " TEXT UNIQUE NOT NULL, " +
            COLUMN_CATEGORY_PD + ", " +
            COLUMN_CATEGORY_DATE + ", " +
            COLUMN_CATEGORY_PERIOD + ", " +
            COLUMN_CATEGORY_FREQUENCY + ", " +
            COLUMN_CATEGORY_ONBY + ", " +
            COLUMN_CATEGORY_COMPLETION + ")";
}

1 Ответ

1 голос
/ 02 июля 2019

У вас, похоже, есть несколько проблем.

Выпуск 1

Аргументы выбора, 4-й параметр запроса , должны быть String[], а не String.

т.е..

public Cursor query (String table, 
            String[] columns, 
            String selection, 
            String[] selectionArgs, //<<<<<<<<<<
            String groupBy, 
            String having, 
            String orderBy)

Попробуйте использовать: -

String selection = TaskEntry.COLUMN_CATEGORY_ID + " = ?";
String[] selectionArgs = new String[]{Integer.toString(mId)};
Cursor taskCursor = mDb.query(TaskEntry.TABLE_NAME, null, selection, 
    selectionArgs, null, null, null, null)

Выпуск 2

Поскольку вы определили столбец category_id без TYPE, используется сходство типов по умолчанию NUMERIC, и вы, к сожалению, столкнулись с нюансом, в котором имеет значение AFFINITY TYPE.

Короче говоря, вы должны применять подходящий тип столбца (INTEGER будет правильным, хотя TEXT также будет работать) в качестве такого использования: -

    public static final String SQL_CREATE_TABLE = "CREATE TABLE " +
            TABLE_NAME + " (" +
            _ID + " INTEGER PRIMARY KEY, " +
            COLUMN_TASK_NAME + " TEXT UNIQUE NOT NULL, " +
            COLUMN_CATEGORY_ID + " INTEGER , " + //<<<<<<<<<<
            COLUMN_SKILL_ID + " INTEGER, " + //<<<<<<<<<<
            COLUMN_TASK_PD + ", " +
            COLUMN_TASK_DATE + ", " +
            COLUMN_TASK_PERIOD + ", " +
            COLUMN_TASK_FREQUENCY + ", " +
            COLUMN_TASK_ONBY + ", " +
            COLUMN_TASK_COMPLETION + ")";
  • предлагается включить ожидаемый тип для всех столбцов.
  • Обратите внимание, что для запуска вышеупомянутого вам нужно будет удалить базу данных или удалить таблицу. Это может быть достигнуто путем выполнения 1 из следующих

    1. удаление приложения и повторный запуск или
    2. очистка данных приложения с последующим повторным запуском или
    3. IF метод onUpgrade был надлежащим образом закодирован, после чего можно увеличить номер версии базы данных (4-й параметр супер-вызова SQLiteOpenHelper).
      • для соответствующей кодировки потребуется, чтобы он отбросил таблицу и затем создал таблицу (обычно таблицы удаляются, а затем вызывается метод onCreate)
  • Если вы не можете позволить себе потерять данные, вам необходимо переименовать таблицу (используя ALTER TABLE), а затем создать ее и затем загрузить данные из переименованной исходной таблицы.

Проблема 2 - Альтернативное решение

Альтернативой изменению столбца TYPE может быть использование CAST для принудительной привязки типа, например Вы можете использовать: -

String selection = TaskEntry.COLUMN_CATEGORY_ID + " = CAST(? AS INTEGER)";

или

String selection = "CAST(" + TaskEntry.COLUMN_CATEGORY_ID  + " AS INTEGER)=?";
  • Использование любого из вышеперечисленных не требует воссоздания таблицы, но не является предпочтительным методом, так как это грязный .
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...