是否可以在没有游标的情况下检查sqlite值? - Android

时间:2012-04-24 17:59:25

标签: android sqlite cursor

我试图阻止用户为日历中的约会创建应用程序中的“标题”字段输入相同的字符串值作为家庭作业。

这是我到目前为止的想法:

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:没有这样的列:hello :,编译时:SELECT title FROM appointmentments WHERE title = hello

如果您有任何建议,请分享,谢谢。

2 个答案:

答案 0 :(得分:3)

如果您希望注射安全,请使用它

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

?'替换 - 来自下一个参数的引用和转义数据。

提示:如果要强制使用唯一标题,请创建数据库列UNIQUE。这样,当SQLiteException数据具有已存在的标题时,您将获得insert。除了预期之外,您还可以创建列UNIQUE ON CONFLICT IGNORE,这意味着它不会插入数据并且不会抛出错误。

答案 1 :(得分: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注入问题。适应参数化方法是更好的方法。