2012-04-24 62 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

相关问题