2011-11-21 11 views
7

sto usando ORMLite, con la tabella delle RecentSearch:interrogazione ORMLite citando, Android

@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"; 

E 'di lavoro quasi tutto il tempo, ma quando scopro il caso con una stringa contenente un', poi appare essere un problema Sai come risolvere questo? Non riuscivo a trovare quello che stavo cercando.

Qui è la mia funzione per eliminare una recente

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; 
    } 
} 

Qui è l'eccezione ottengo:

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) 
+0

correlati a http://stackoverflow.com/questions/5280227/sql-exception-preparing-query-with-ormlite e http://stackoverflow.com/questions/6400782/ormlite-escape-string-method – Gray

risposta

20

In ORMLite, quando si sta cercando di costruire una query con le citazioni, è necessario utilizzare la funzione SelectArg che genererà una query con SQL? argomenti e quindi passare direttamente la stringa all'istruzione preparata. Questo risolve qualsiasi problema con l'escape di caratteri speciali e ti protegge dai problemi di sicurezza di SQL injection. Vedi lo documentation on SelectArg.

Con SelectArg, devi fare qualcosa di simile:

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()); 
... 
+0

Primo , grazie per le tue spiegazioni, ogni volta che ho un dubbio legato a ORMLite, hai già risposto qui. Mi stavo chiedendo, c'è qualche differenza tra: recentsDao.delete (deleteBuilder.prepare()); e deleteBuilder.delete(); ? – AlvaroSantisteban

+1

Non diverso @AlvaroSantisteban. Il .delete() è solo una chiamata per renderlo più facile. Lo dice in javadocs: http://ormlite.com/javadoc/ormlite-core/com/j256/ormlite/stmt/DeleteBuilder.html#delete() – Gray

1

È possibile utilizzare l'oggetto SelectArg durante l'associazione alla tua richiesta in quanto ciò sfuggire eventuali citazioni in modo che non generano SQL non valido.