2012-04-24 28 views
-2

我試圖阻止用戶輸入日曆中預約創建應用中的「標題」字段的相同字符串值作爲作業。是否可以在沒有遊標的情況下檢查sqlite值? - Android

這是我認爲的迄今:

private static String[] CHECK = {TITLE}; 
    private Cursor addAppointment(String title, String time, String details){ 
     calendarData = new CalendarData(this); 
     SQLiteDatabase db1 = calendarData.getReadableDatabase(); 
     SQLiteDatabase db = calendarData.getWritableDatabase(); 
     ContentValues values = new ContentValues(); 
     values.put(DATE, calendar.getDate()); 
     values.put(TITLE, title); 
     values.put(TIME, time);  
     values.put(DETAILS, details); 
     db.insertOrThrow(TABLE_NAME, null, values); 
     Cursor titleCursor = db1.query(TABLE_NAME, CHECK, TITLE+" = "+appointmentTitle.getText().toString(), null, null, null, null); 
     if(titleCursor.getString(0) != null){//MEANING THERE IS A DUPLICATE 
      final AlertDialog alertDialog = new AlertDialog.Builder(this).create(); 
      alertDialog.setMessage("You've entered a duplicate title field, please rename."); 
      alertDialog.setButton("OK", new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 

        alertDialog.dismiss(); 

       } }); 
      alertDialog.show(); 
     } 
     return titleCursor; 
    } 

,但我不喜歡在我的addAppointments方法一切的想法,我寧願把它乾淨和簡單。

我試着做以下作爲替代:

private static String[] CHECK = {TITLE}; 
    private void addAppointment(String title, String time, String details){ 
     calendarData = new CalendarData(this); 
     SQLiteDatabase db1 = calendarData.getReadableDatabase(); 
     SQLiteDatabase db = calendarData.getWritableDatabase(); 
     ContentValues values = new ContentValues(); 
     values.put(DATE, calendar.getDate()); 
     values.put(TITLE, title); 
     values.put(TIME, time);  
     values.put(DETAILS, details); 
     db.insertOrThrow(TABLE_NAME, null, values); 
    } 

    private Cursor checkTitle(){ 
     calendarData = new CalendarData(this); 
     SQLiteDatabase db1 = calendarData.getReadableDatabase(); 

     Cursor titleCursor = db1.query(TABLE_NAME, CHECK, TITLE+" = "+appointmentTitle.getText().toString(), null, null, null, null); 

     startManagingCursor(titleCursor); 
     return titleCursor; 
    } 

    private void showTitleError(Cursor cursor){ 
     if(cursor.getString(0) != null){//MEANING THERE IS A DUPLICATE 
      final AlertDialog alertDialog = new AlertDialog.Builder(this).create(); 
      alertDialog.setMessage("You've entered a duplicate title field, please rename."); 
      alertDialog.setButton("OK", new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 

        alertDialog.dismiss(); 

       } }); 
      alertDialog.show(); 
     } 
    } 

,但我在這兩種情況下出現此錯誤:04-24 17:56:51.263:E/AndroidRuntime(17856):android.database.sqlite .SQLiteException:沒有這樣的列:你好:,在編譯時:SELECT標題FROM約會WHERE標題=你好

請如果你有什麼建議請分享,謝謝。

+0

*請仔細閱讀*錯誤信息。請注意它如何與標題無關。 -1(缺乏問題/問題細化和嚴重錯誤的標題)和「太本地化」。 – 2012-04-24 18:09:29

回答

1

您需要在單引號包裹appointmentTitle.getText().toString()

db1.query(TABLE_NAME, CHECK, TITLE+" = '"+appointmentTitle.getText().toString() + "'", null, null, null, null); 

這樣,你的組合查詢看起來像:

SELECT title FROM appointments WHERE title = 'hello' 

正如其他海報禮貌指出,然而,這可能會導致一個SQL注入問題,如果您的查詢在這裏需要用戶輸入。適應參數化方法是更好的方法。

+0

Android *真的*重新推出了SQL注入嗎?我留下了深刻的印象...但不是通過這個答案(-1 [見API](http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html)更好的方式)。 – 2012-04-24 18:04:59

+0

@pst顯然,更好的做法是將查詢參數化 - 但至於它爲什麼會中斷。我也會說,android可以幫助你避免SQL注入,但它不會讓你 – JRaymond 2012-04-24 18:08:19

+0

感謝指出 – a7omiton 2012-04-24 18:51:35

3

如果你想讓它注射安全使用它的方式

Cursor titleCursor = db1.query(TABLE_NAME, CHECK, TITLE+" = ?", 
     new String[]{ appointmentTitle.getText().toString() }, null, null, null); 

?' -quoted和轉義的數據從一個參數取代。

提示:如果你想強制一個獨特的標題,然後使數據庫列UNIQUE。這樣,當您的insert數據具有已存在的標題時,您將獲得SQLiteException。您也可以將列UNIQUE ON CONFLICT IGNORE這意味着它不會插入數據,也不會引發錯誤,而不是預期。

+0

that sense sense ,我會考慮讓這個列獨一無二,這樣我就不必實現一個警告對話框,因爲它會阻止用戶完全輸入相同的標題。謝謝 – a7omiton 2012-04-24 18:55:17

相關問題