2012-04-24 7 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(); 
     } 
    } 

が、私は両方のケースで、このエラーを取得する:4月24日17:56:51.263:E/AndroidRuntime(17856):android.database.sqlite .SQLiteException:そのような列はありません:hello:、コンパイル中:SELECT title FROM appointments WHERE title = hello

あなたに助言がありましたら教えてください。ありがとうございます。

+0

*エラーメッセージをよく読んでください。タイトルとは何も関係がないことに注意してください。 -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インジェクションの問題パラメータ化されたアプローチに適応する方が良い方法です。

+0

Android *は本当に* SQLインジェクションを再導入しましたか?私は感心しています...しかし、この答えではありません(-1)(より良い方法については、-1 [API参照](http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html))。 –

+0

@pstよく分かりやすいのは、代わりにクエリをパラメータ化することですが、なぜそれが壊れていたのかについてです。私はまた、アンドロイドがSQLインジェクションを回避するのに役立つと言いますが、それはあなたを – JRaymond

+0

に指摘してくれてありがとう – a7omiton

3

あなたはそれが注入安全な使用それを

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

?は、次の引数から' -quotedとエスケープされたデータで置き換えられ、そのようにしたい場合。

ヒント:一意のタイトルを適用する場合は、データベースの列をUNIQUEにします。そうすれば、既に存在するタイトルを持つinsertデータがあるときにSQLiteExceptionが得られます。 expectionの代わりに、列UNIQUE ON CONFLICT IGNOREを作成することもできます。つまり、単にデータを挿入せず、エラーをスローしません。

+0

意味があります私は列をユニークにすることを検討します。つまり、ユーザーが同じタイトルを完全に入力するのを止めるため、警告ダイアログを実装する必要はありません。ありがとう – a7omiton

関連する問題