ORMLite 带引号查询,Android

Posted

技术标签:

【中文标题】ORMLite 带引号查询,Android【英文标题】:ORMLite query with quote, Android 【发布时间】:2011-11-21 11:19:17 【问题描述】:

我正在使用 ORMLite,带有 Table RecentSearch:

@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)

【问题讨论】:

与***.com/questions/5280227/…和***.com/questions/6400782/…相关 【参考方案1】:

当我发现字符串中包含 '(单引号)的情况时,这似乎是个问题。

在ORMLite 中,当您尝试使用引号构建查询时,您应该使用SelectArg 功能,该功能将生成带有SQL ? 参数的查询,然后将字符串直接传递给准备好的语句。这解决了特殊字符转义的任何问题,并保护您免受 SQL 注入安全问题的影响。见documentation on 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());
...

【讨论】:

首先,感谢您的解释,每次我对ORMLite有疑问时,您已经在这里回答了。我想知道,之间有什么区别:recentsDao.delete(deleteBuilder.prepare());和 deleteBuilder.delete(); ? 没有不同的@AlvaroSantisteban。 .delete() 只是一个调用,使它更容易。它在 javadocs 中这样说:ormlite.com/javadoc/ormlite-core/com/j256/ormlite/stmt/…【参考方案2】:

您可以在绑定到查询时使用SelectArg 对象,因为这将转义任何引号,因此它们不会生成无效的 sql。

【讨论】:

以上是关于ORMLite 带引号查询,Android的主要内容,如果未能解决你的问题,请参考以下文章

c++ mysql查询字符串解析带引号和变量

在所有 oracle 包中查找带引号和双引号的字符串

使用for循环生成条件时如何在ormlite中编写查询

如何修改 ServiceStack.OrmLite 生成的 SQL?

ORMLite 对字段子字符串的原始查询

在使用原始查询时选择比较 ormlite 中的两列值的行