SQLiteException при установке параметра в rawQuery - PullRequest
0 голосов
/ 03 сентября 2018

Я получил отчет о сбое в консоли Google Play, который не могу воспроизвести:

java.lang.RuntimeException: 
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2422)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2482)
  at android.app.ActivityThread.access$900 (ActivityThread.java:150)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1344)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:148)
  at android.app.ActivityThread.main (ActivityThread.java:5423)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:726)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:616)
Caused by: android.database.sqlite.SQLiteException: 
  at android.database.sqlite.SQLiteConnection.nativePrepareStatement (SQLiteConnection.java)
  at android.database.sqlite.SQLiteConnection.acquirePreparedStatement (SQLiteConnection.java:887)
  at android.database.sqlite.SQLiteConnection.prepare (SQLiteConnection.java:498)
  at android.database.sqlite.SQLiteSession.prepare (SQLiteSession.java:588)
  at android.database.sqlite.SQLiteProgram.<init> (SQLiteProgram.java:58)
  at android.database.sqlite.SQLiteQuery.<init> (SQLiteQuery.java:37)
  at android.database.sqlite.SQLiteDirectCursorDriver.query (SQLiteDirectCursorDriver.java:44)
  at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory (SQLiteDatabase.java:1316)
  at android.database.sqlite.SQLiteDatabase.rawQuery (SQLiteDatabase.java:1255)
  at .StatDB.getExercise (StatDB.java)
  at .ExerciseList.onCreate (ExerciseList.java)
  at android.app.Activity.performCreate (Activity.java:6294)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1108)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2375)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2482)
  at android.app.ActivityThread.access$900 (ActivityThread.java:150)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1344)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:148)
  at android.app.ActivityThread.main (ActivityThread.java:5423)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:726)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:616)

Это мой getExercise метод:

public List<Bean> getExercise(String sub) {
        SQLiteDatabase db = initializer.getReadableDatabase();

        String sql = "SELECT * FROM " + sub;

        Cursor cursor = db.rawQuery(sql, null);

        List<Bean> exeList = new ArrayList<Bean>();
        while(cursor.moveToNext()) {
            String code = cursor.getString(1);
            String mark = cursor.getString(2);
            exeList.add(new Bean(code, mark));
        }

        cursor.close();
        db.close();
        return exeList;
    }

По моему ExerciseList.onCreate:

Intent i = getIntent();
        subCode = i.getExtras().getString("sub");
List<Bean> exeList = statDB.getExercise(subCode);

Ранее я уже упоминал: «Может ли сбой случиться из-за того, что subCode равен нулю? Однако после того, как я провел тестирование, я исключил эту причину. Потому что до List<Bean> exeList = statDB.getExercise(subCode); фактически я установил TextView, используя это:

if (subCode.equals("bd")) {
            passTv.setText("Some Text");
        } else {
            passTv.setText("Another Text");
        }

Итак, более полный код:

Intent i = getIntent();
        subCode = i.getExtras().getString("sub");
if (subCode.equals("bd")) {
                passTv.setText("Some Text");
            } else {
                passTv.setText("Another Text");
            }
List<Bean> exeList = statDB.getExercise(subCode);

Если мой subcode равен нулю, мой TextView будет аварийно завершаться первым. Так что проблема подозрительна в моем getExercise методе, особенно String sql = "SELECT * FROM " + sub;. Это потому, что параметр sub не передан?

1 Ответ

0 голосов
/ 03 сентября 2018

По вашему вопросу:

Может ли произойти сбой, поскольку подкод имеет значение null?

Если вы не знаете, что произойдет, если sub здесь null:

String sql = "SELECT * FROM " + sub;

Ну, это просто проверить:

String sub = null;
String sql = "SELECT * FROM " + sub;
System.out.println(sql);

ВЫБРАТЬ * ОТ нуля

Просто проверьте значения null, чтобы предотвратить отправку неправильного запроса.

if(sub != null){
    throw new Exception("no table provided")
}
String sql = "SELECT * FROM " + sub;

Возможно, это не лучший подход для создания запроса, подобного этому.
Во-первых, посмотрите на SQL Injection.
Что произойдет, если в вашей таблице нет 2 полей TEXT? Вы должны использовать шаблон DAO для создания одного класса для каждой таблицы вместо того, чтобы надеяться на лучшее.

...