8

Table RecentSearch で ORMLite を使用しています。

@DatabaseTable(tableName = LocalStorageConfig.SQL_RECENTS_TABLE_NAME)
public class RecentSearch {

    @DatabaseField
    public String search_text;
    public static String SQL_SEARCH_FIELD = "search_text";

    @DatabaseField
    public String location_text;
    public static String SQL_LOCATION_FIELD = "location_text";

    @DatabaseField
    public Date creation_date = new Date();
    public static String SQL_CREATION_DATE_FIELD = "creation_date";

ほとんど常に機能していますが、' を含む文字列のケースを発見すると、問題があるように見えます。これを解決する方法を知っていますか?探していたものが見つかりませんでした。

これが最近のを削除する私の機能です

public boolean deleteRecent(RecentSearch search) {
    try {
        Dao<RecentSearch, Integer> recentsDao = recentsSqlManager.getRecentsDao();
        DeleteBuilder<RecentSearch, Integer> deleteBuilder = recentsDao.deleteBuilder();

        deleteBuilder.where().eq(RecentSearch.SQL_SEARCH_FIELD, search.getSearch_text()).and().eq(RecentSearch.SQL_LOCATION_FIELD, search.location_text);
        recentsDao.delete(deleteBuilder.prepare());
        return true;
    } catch (Exception e) {
        Log.e(TAG, "Database exception", e);
        return false;
    }
}

これが私が得る例外です:

java.sql.SQLException: Problems executing Android statement: DELETE FROM `recent_searches` WHERE (`search_text` = '' AND `location_text` = 'Villefranche-d'Allier, Allier' ) 
    at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
    at com.j256.ormlite.android.AndroidCompiledStatement.runUpdate(AndroidCompiledStatement.java:66)
    at com.j256.ormlite.stmt.StatementExecutor.delete(StatementExecutor.java:425)
    at com.j256.ormlite.dao.BaseDaoImpl.delete(BaseDaoImpl.java:347)
...
Caused by: android.database.sqlite.SQLiteException: near "Allier": syntax error: , while compiling: DELETE FROM `recent_searches` WHERE (`search_text` = '' AND `location_text` = 'Villefranche-d'Allier, Allier' ) 
    at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
    at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
    at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:65)
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:83)
    at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:41)
    at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1149)
4

2 に答える 2

22

' (一重引用符) を含む文字列のケースを発見すると、問題があるように見えます。

ORMLiteでは、引用符を使用してクエリを作成しようとする場合、SelectArgSQL?引数を使用してクエリを生成し、その文字列を準備済みステートメントに直接渡す機能を使用する必要があります。これにより、特殊文字のエスケープに関する問題が回避され、SQL インジェクションのセキュリティ問題から保護されます。のドキュメントをSelectArg参照してください。

を使用SelectArgすると、次のようになります。

DeleteBuilder<RecentSearch, Integer> deleteBuilder = recentsDao.deleteBuilder();

// create our argument which uses a SQL ?
SelectArg locationArg = new SelectArg(search.location_text);
deleteBuilder.where().eq(RecentSearch.SQL_SEARCH_FIELD, search.getSearch_text())
    .and().eq(RecentSearch.SQL_LOCATION_FIELD, locationArg);
recentsDao.delete(deleteBuilder.prepare());
...
于 2011-11-21T14:02:30.263 に答える
2

クエリにバインドするときにSelectArgオブジェクトを使用できます。これにより、引用符がエスケープされ、無効な SQL が生成されなくなります。

于 2011-11-21T14:02:47.777 に答える