将参数设置为rawQuery时出现SQLiteException

时间:2018-09-03 09:47:02

标签: java android android-sqlite

我在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);之前,我实际上设置了{{1 }}使用

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;吗?

1 个答案:

答案 0 :(得分:1)

根据您的问题:

  

是否可能因为subCode为null而导致崩溃?

如果您不知道如果subnull会发生什么,

String sql = "SELECT * FROM " + sub;

好吧,检查很简单:

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

SELECT * FROM null

只需检查null值即可防止发送错误的查询。

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

这可能不是创建这样的查询的最佳方法。
首先,请参阅SQL注入。
然后,当您的表没有2个TEXT字段时会发生什么?您应该使用DAO模式为每个表创建一个类,而不是希望达到最佳效果。