SQLiteデータベースのテーブルでクエリを実行する関数があります。定数を宣言します:public static final String CANADA_HISTORY = "Canada's History";
。これはString
変数に保存されます。たとえば、difficulty
、
1つのクエリがあります。
Cursor c = mDb.rawQuery("select * from Questions_answers where CHAPTERS = '"+difficulty+"'" , null);
アポストロフィの近くで例外をスローしています。
Logcatの出力:
I/Database( 1170): sqlite returned: error code = 1, msg = near "s": syntax error
D/AndroidRuntime( 1170): Shutting down VM
W/dalvikvm( 1170): threadid=1: thread exiting with uncaught exception (group=0x40015560)
E/AndroidRuntime( 1170): FATAL EXCEPTION: main
E/AndroidRuntime( 1170): Android.database.sqlite.SQLiteException: near "s": syntax error: , while compiling: select * from Questions_answers where CHAPTERS = 'Canada's History'
私も試しました:
1. difficulty=difficulty.replaceAll("'","''");
2. difficulty=difficulty.replaceAll("'","\'");
3. difficulty = DatabaseUtils.sqlEscapeString(difficulty);
それに追加するために、Canada History
、私は特別な文字Wordなしを意味します。
問題を解決するためのアドバイスをお願いしますありがとうございます。
最初にこれをcharに置き換えます
difficulty=difficulty.replaceAll("'","\\'");
それをクエリに渡します
"select * from Questions_answers where CHAPTERS='"+difficulty+"'";
編集:
q = "select * from Questions_answers where CHAPTERS = ?";
database.rawQuery(q, new String[] { difficulty});
SQL標準では、2つの単一引用符を連続して配置することで、文字列内の単一引用符をエスケープするように指定しています。 SQLは、点でPascalプログラミング言語のように機能します。 SQLiteはこの標準に従います。例:
INSERT INTO xyz VALUES('5 O''clock');
参照: SQLite FAQ
最適な方法は、まさにこの目的のために設計されたネイティブAndroidメソッドを使用することです。
DatabaseUtils.sqlEscapeString(String)
オンラインのドキュメントは次のとおりです。
私の意見では、このメソッドを使用する主な利点は、明確なメソッド名のための自己文書化です。
私のために働いたのは
if (columnvalue.contains("'")) {
columnvalue = columnvalue.replaceAll("'", "''");
}
Cursor c = mDb.rawQuery("select * from Questions_answers where CHAPTERS = \""+difficulty+"\"" , null);
を試すことができます
これは同じように機能します:
if (columnValue.contains("'"))
columnValue = columnValue.replaceAll("'", "[']");
または
if (columnValue.contains("'"))
columnValue = columnValue.replaceAll("'", "\\\'");
しかし、実際には次のシンボル%と_を使用します
DatabaseUtils.sqlEscapeString(s)
が本質的に行うことは、すべての単一引用符('
)2つの単一引用符(''
)そして、文字列の先頭と末尾に1つの単一引用符を追加します。
したがって、文字列をエスケープするだけの場合、この関数は機能します。
private static String escape(String s) {
return s != null ? s.replaceAll("\'", "\'\'") : null;
}
私の理解では、2つの承認キャッシュがあります。
文字列test = "Androidのバージョン" test = test.replace( "'"、 "' '");
このシナリオはまったく問題ありませんが、次のアプローチを使用することをお勧めします。
文字列test = "Androidのバージョン" test = test.replaceAll( "'"、 "\'");
この問題に直面したのは、 'でSQLiteテーブル値を更新および選択しようとしたときの最初のアプローチが原因でした。