-2

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

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

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: no such column: hello: , while compile: SELECT title FROMointments WHERE title =你好

如果有什么建议请分享,谢谢。

4

2 回答 2

3

如果你想让它注射安全,那就这样使用

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

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

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

于 2012-04-24T18:07:33.360 回答
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 注入问题。适应参数化方法是更好的方法。

于 2012-04-24T18:01:14.643 回答