2012-01-26 4 views
5

Estoy portando código de iOS que funciona perfectamente con el sistema operativo Android. Realizo un montón de consultas, insertando los resultados de las consultas en una tabla temporal. Cuando todas las consultas se completan, tomo todos los resultados de la tabla temporal en una colección de objetos de mi propia creación. Estoy utilizando una tabla temporal en lugar de seleccionar directamente en la colección porque creo que se ejecuta más rápido, o al menos lo hace en el lado de iOS de todos modos. Mi problema es que execSQL() no está funcionando lo que cabe esperar, aquí está el código:SQLiteDatabase.execSQL no funciona como se esperaba para la consulta INSERT INTO

db.execSQL("CREATE TEMPORARY TABLE SearchResults(Name text);"); 
db.execSQL("INSERT INTO SearchResults (Name) SELECT Name FROM ProductNames WHERE NameLower MATCH '" + termLowerCase + "*';"); 
db.execSQL("INSERT INTO SearchResults (Name) SELECT Name FROM BrandNames WHERE NameLower MATCH '" + termLowerCase + "*';"); 

Cuando ejecuto el código que sólo alguna vez una fila desde el primer execSQL() con la inserción. Sé que hay más de un resultado en la tabla ProductNames que debe coincidir con mi término, y sé que hay cientos de filas en la tabla de BrandNames que deben coincidir con mi término. Si cambio el código a este:

Cursor cursor = db.rawQuery("SELECT Name FROM ProductNames WHERE NameLower MATCH '" + termLowerCase + "*'", null); 
cursor.moveToFirst(); 
while (!cursor.isAfterLast()) 
{ 
    resultSet.add(cursor.getString(0)); 
    cursor.moveToNext(); 
} 
cursor.close(); 
cursor = db.rawQuery("SELECT Name FROM BrandNames WHERE NameLower MATCH '" + termLowerCase + "*'", null); 
cursor.moveToFirst(); 
while (!cursor.isAfterLast()) 
{ 
    resultSet.add(cursor.getString(0)); 
    cursor.moveToNext(); 
} 

Obtengo todos los resultados que estoy esperando.

¿Alguien podría decirme qué estoy haciendo mal? ¿Estoy usando execSQL() de una manera inapropiada? Supuse que simplemente pasaría la consulta a sqlite3_exec() que es lo que uso en iOS. Si estoy utilizando execSQL() inapropiadamente, ¿cuáles son sus limitaciones y cuál es la alternativa más rápida a lo que quiero hacer? ¡Muchas gracias por la ayuda!

Respuesta

0

De acuerdo con la documentación SQLiteDatabase no se puede usar execSQL en este caso. Intenta hacer esa declaración con rawQuery en su lugar.

+0

Creo que la documentación indica que no la use si necesita datos devueltos de la consulta. Usar rawQuery no parece factible en mi escenario, el código de consulta sin procesar anterior toma una cantidad extremadamente larga de tiempo para ejecutarse en mi ADP2. También cabe destacar que he probado la migración de algunas otras consultas mías desde la versión de iOS en un método separado que también usa INSERT INTO con SELECT usando fts3 MATCH y parece que funcionan bien. Este problema sigue siendo un misterio. –

+0

La forma en que entiendo la documentación dice que ejecutará UNA declaración que NO es SELECCIONADA. Es decir, INSERT + SELECT viola ambas restricciones de esa documentación. ¿Funciona cuando usas rawQuery? Mientras lento, considere la operación que está haciendo sobre el tamaño de sus datos. No es una operación trivial. – jlindenbaum

+0

Sí, entiendo lo que dices aquí, sin embargo, tengo que ejecutar las llamadas execSQL() con las instrucciones INSERT INTO y SELECT en la consulta. Aquí hay un ejemplo de uno que funciona: sql = "INSERT INTO SearchResults (SearchOrder, PID, ProductName, DBTable)" + "SELECT 3, P.ProductID, P.Name, 0" + "FROM Ingredients I" + "INNER JOIN ProductAltNames A ON (I.IngredientsID = A.IngredientID)" + "INNER JOIN ProductNames P ON (A.IDProducto = P.ProductID)" + "DÓNDE I.DescriptionLower MATCH '" + termLowerCase + "*' "; db.execSQL (sql); –

Cuestiones relacionadas