我试图阻止用户为日历中的约会创建应用程序中的“标题”字段输入相同的字符串值作为家庭作业。
这是我到目前为止的想法:
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
如果您有任何建议,请分享,谢谢。
答案 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注入问题。适应参数化方法是更好的方法。