尝试将参数添加到 android 应用程序的 sqlite 准备语句中失败

getting failure trying to add parameters into sqlite prepared statements for android app

我正在使用 Android studio 1.3.1 并试图获取要插入到 select 查询中的字符串参数,以避免注入攻击的风险。在下面的代码中,如果我将 patientID 编号硬编码到查询中,它可以正常工作,但在当前形式下它会失败,我只能猜测其中存在我看不到的语法错误。我也包含了错误堆栈跟踪

    public void getPatientRecords(int patientID){
    // do db query to retrieve all recs for this patient
    Log.d(MainActivity.DEBUGTAG, " ---->>>>> IN DATABASE HANDLER GET PATIENT RECORDS FOR THIS  PATIENT id = " +  patientID);

    SQLiteDatabase db = null;
    Cursor resultSet = null;

        db = this.getReadableDatabase();
        String selectQuery = " SELECT  TITLE, SURNAME, FIRSTNAME, SEX, DATEOFBIRTH, CREATIONDATE,"+
                " ADDRESSLINE1, ADDRESSLINE2, ADDRESSLINE3, POSTCODE, TELEPHONENUMBER, "+
                " MOBILENUMBER, OCCUPATION, DATESTAMP"+
                " FROM PATIENTDETAILS, ADDRESSDETAILS  "+
                " WHERE PATIENTDETAILS.PATIENTID=ADDRESSDETAILS.PATIENTID"+
                " AND PATIENTDETAILS.PATIENTID  = ? " +
                " AND ADDRESSID     IN" +
                " ( SELECT MAX (DISTINCT ADDRESSID) FROM ADDRESSDETAILS WHERE  PATIENTID = ?), "   +
                 " new String[]{Integer.toString(patientID), Integer.toString(patientID)} " ;     // remove this line for hard coded value

        resultSet = db.rawQuery(selectQuery, null);


        while (resultSet.moveToNext()){
        if (resultSet !=null){
             String eTitle = resultSet.getString(0);
            Log.d(MainActivity.DEBUGTAG, "the returned title is = " + eTitle);
            }
        }
        resultSet.close();
    db.close();

这里是堆栈错误

e11-10 20:09:56.911  16014-16014/com.example.martin.ph_program_test3 E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.martin.ph_program_test3, PID: 16014
java.lang.IllegalStateException: Could not execute method of the activity
        at android.view.View.onClick(View.java:3823)
        at android.view.View.performClick(View.java:4438)
        at android.view.View$PerformClick.run(View.java:18422)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5001)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at android.view.View.onClick(View.java:3818)
            at android.view.View.performClick(View.java:4438)
            at android.view.View$PerformClick.run(View.java:18422)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)
 Caused by: android.database.sqlite.SQLiteException: near ",": syntax error (code 1): , while compiling: SELECT  TITLE, SURNAME, FIRSTNAME, SEX, DATEOFBIRTH, CREATIONDATE, ADDRESSLINE1, ADDRESSLINE2, ADDRESSLINE3, POSTCODE, TELEPHONENUMBER,  MOBILENUMBER, OCCUPATION, DATESTAMP FROM PATIENTDETAILS, ADDRESSDETAILS   WHERE PATIENTDETAILS.PATIENTID=ADDRESSDETAILS.PATIENTID AND PATIENTDETAILS.PATIENTID  = ?  AND ADDRESSID        IN ( SELECT MAX (DISTINCT ADDRESSID) FROM ADDRESSDETAILS WHERE  PATIENTID = ?),  new String[]{Integer.toString(patientID), Integer.toString(patientID)}
        at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
        at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
        at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
        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:1314)
        at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1253)
        at com.example.martin.ph_program_test3.DatabaseHandler.getPatientRecords(DatabaseHandler.java:81)
        at com.example.martin.ph_program_test3.MainActivity.RetrievePatientRecord(MainActivity.java:371)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at android.view.View.onClick(View.java:3818)
            at android.view.View.performClick(View.java:4438)
            at android.view.View$PerformClick.run(View.java:18422)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5001)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
            at dalvik.system.NativeStart.main(Native Method)nter code here

必须是这样的:

String selectQuery = " SELECT  TITLE, SURNAME, FIRSTNAME, SEX, DATEOFBIRTH, CREATIONDATE,"+
            " ADDRESSLINE1, ADDRESSLINE2, ADDRESSLINE3, POSTCODE, TELEPHONENUMBER, "+
            " MOBILENUMBER, OCCUPATION, DATESTAMP"+
            " FROM PATIENTDETAILS, ADDRESSDETAILS  "+
            " WHERE PATIENTDETAILS.PATIENTID=ADDRESSDETAILS.PATIENTID"+
            " AND PATIENTDETAILS.PATIENTID  = ? " +
            " AND ADDRESSID     IN" +
            " ( SELECT MAX (DISTINCT ADDRESSID) FROM ADDRESSDETAILS WHERE  PATIENTID = ?)";

    resultSet = db.rawQuery(selectQuery, new String[]{Integer.toString(patientID), Integer.toString(patientID)});