2011-08-26 5 views
20

ho lottato per ore cercando di eseguire il debug il motivo per cui la seguente query di eliminazione in realtà non ha cancellato nulla, anche se la stessa interrogazione sullo stesso identico base di dati ha funzionato bene in Firefox' SQLite Manager:Perché una cancellazione rawQuery ha bisogno di moveToFirst per eliminare effettivamente le righe?

String deleteSql = "DELETE FROM showsummary WHERE url IN (SELECT url FROM showsummary JOIN article_categories USING (url) WHERE categoryid=20 AND title LIKE 'page=%')"; 
mDb.rawQuery(deleteSql, null); 

Dal momento che è un po 'complicato sia con un JOIN che con una sottoquestione, i miei pensieri cerchiavano alcune limitazioni nell'implementazione sqlite di Android per quanto riguarda le sottoquery, quindi ho provato a semplificare la query. Ma ancora non ha cancellato nulla.

Poi ho cambiato in una query di selezione (appena sostituito CANCELLA con SELECT *) e che ha funzionato. Quindi, probabilmente, non era il join o la query secondaria a essere il colpevole, dopotutto.

Al fine di testare la query di selezione che avevo aggiunto un moveToFirst() al cursore tornato:

mDb.rawQuery(deleteSql, null).moveToFirst(); 

Quando più tardi ho cambiato di nuovo a una query di eliminazione di nuovo, ho dimenticato di togliere il moveToFirst()e poi lavorato!

È bello che funzioni ora, ma sono molto confuso perché è necessario spostare il cursore per eliminare effettivamente qualsiasi cosa. È questo di progettazione o è un bug?

+0

ho appena ucciso 4 ore su questo muto un problema **, si dovrebbe avere questo chiaramente indicato nella documentazione, che spreco di tempo. – LuckyMe

+0

Mi piace come la tua domanda contenga una risposta ai miei problemi di cancellazione, molto efficiente! – Noumenon

+0

Grazie per aver trovato questo. Questo dovrebbe essere sicuramente documentato! Non dovrebbe essere così, penso, ma almeno funziona ora. – kgrevehagen

risposta

10

Non posso rispondere il perché, ma un'altra soluzione è quella di utilizzare .execSQL (String) come pubblicato here

5

Un rawQuery restituisce un cursore di un set di risultati, che è solo un riferimento ai risultati della query. Dovresti semplicemente usare una chiamata straight delete(). Date un'occhiata alla documentazione:

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

o uno SQLiteStatement:

http://developer.android.com/reference/android/database/sqlite/SQLiteStatement.html

+0

Avrei usato una query di eliminazione diretta se fosse possibile, ma non supporta un'istruzione sql così complicata. Non può operare su join e sottocategorie, almeno per quanto ne so. – marlar

+0

Quindi utilizzare la seconda opzione che ho suggerito. – SBerg413

+0

Certamente guarderò a questa opzione, ma sono comunque curioso del perché sia ​​necessario spostare moveToFirst. Ho visto molti esempi di eseguire query di eliminazione con rawQuery e nessuno di loro ha utilizzato moveToFirst. – marlar

4

Nel mio caso anche, la stessa cosa è accaduta per DELETE, E ha funzionato con successo dopo aver chiamato "cursor.moveToFirst()". Lo stesso vale per le query INSERT e UPDATE. Ho anche osservato che chiamando qualsiasi metodo sul cursore per le query sopra menzionate ho ottenuto correttamente i risultati. Senza chiamare alcun metodo del cursore, l'effetto desiderato si sta verificando. Quindi, penso che la risposta alla tua domanda sia: la query viene eseguita solo quando chiamiamo qualche metodo sul cursore.

3

La risposta perché è perché rawQuery in realtà non esegue til u chiamata qualche metodo sul cursore restituito. moveToFirst, isAfterLast ..

+0

Com'è diverso dalle risposte precedenti? Hai appena copiato le parole di @mopurizwarriors. – Androiderson

+0

Leggere di nuovo attentamente ... non si tratta di eseguire correttamente o meno. Si tratta di non funzionare affatto, ma di preparare la query prima che vengano eseguiti alcuni dei metodi sul cursore. Inoltre questo non era il metodo try/fail di capire la risposta, ma dire che significava lavorare in quel modo. – Ewoks

+1

Quindi dovresti approfondire la tua risposta, perché ** Query viene eseguita solo quando chiamiamo qualche metodo sul cursore ** e ** rawQuery in realtà non viene eseguito per chiamare qualche metodo sul cursore restituito ** leggere lo stesso tizio. Qualcuno dirà che l'hai appena copiato dal momento che la tua risposta ha 2 anni. – Androiderson

Problemi correlati