Método SQLiteDatabase.query

121

Estoy usando el método de consulta de SQLiteDatabase. ¿Cómo uso el método de consulta?

Intenté esto:

Cursor cursor = sqLiteDatabase.query(
    tableName, tableColumns, whereClause, whereArgs, groupBy, having, orderBy);

tableColumns : el parámetro columnas se construye de la siguiente manera.

String[] columns = new String[]{KEY_ID, KEY_CONTENT};

Si necesitamos obtener todos los campos, ¿cómo debería construirse el parámetro de columna? ¿Necesitamos incluir todos los nombres de campo en la matriz de cadenas?

¿Cómo uso correctamente el método de consulta?

sree_iphonedev
fuente
1
Pruebe un enfoque simple como este
Imran Rana,
Conozco ese método Pero estoy tratando de aprender cómo implementar el método de consulta en lugar de rawQuery.
sree_iphonedev

Respuestas:

244

tablaColumnas

  • null para todas las columnas como en SELECT * FROM ...
  • new String[] { "column1", "column2", ... }para columnas específicas como en SELECT column1, column2 FROM ...- también puede poner expresiones complejas aquí:
    new String[] { "(SELECT max(column1) FROM table1) AS max" }le daría una columna llamada que maxcontiene el valor máximo decolumn1

dónde cláusula

  • la parte que pone después WHEREsin esa palabra clave, p. ej."column1 > 5"
  • debe incluir ?para cosas que son dinámicas, por ejemplo, "column1=?"-> verwhereArgs

whereArgs

  • especificar el contenido que llena cada uno ?en whereClauseel orden en que aparecen

los demás

  • al igual que whereClausela declaración después de la palabra clave o nullsi no la usa.

Ejemplo

String[] tableColumns = new String[] {
    "column1",
    "(SELECT max(column1) FROM table2) AS max"
};
String whereClause = "column1 = ? OR column1 = ?";
String[] whereArgs = new String[] {
    "value1",
    "value2"
};
String orderBy = "column1";
Cursor c = sqLiteDatabase.query("table1", tableColumns, whereClause, whereArgs,
        null, null, orderBy);

// since we have a named column we can do
int idx = c.getColumnIndex("max");

es equivalente a la siguiente consulta sin procesar

String queryString =
    "SELECT column1, (SELECT max(column1) FROM table1) AS max FROM table1 " +
    "WHERE column1 = ? OR column1 = ? ORDER BY column1";
sqLiteDatabase.rawQuery(queryString, whereArgs);

Al usar la versión Where / Bind -Args, obtienes valores de escape automáticamente y no tienes que preocuparte si contienen datos de entrada '.

Inseguro: String whereClause = "column1='" + value + "'";
Seguro:String whereClause = "column1=?";

porque si el valor contiene un 'enunciado, su declaración se rompe y obtiene excepciones o hace cosas no intencionadas, por ejemplo value = "XYZ'; DROP TABLE table1;--", incluso podría abandonar su tabla, ya que la declaración se convertiría en dos declaraciones y un comentario:

SELECT * FROM table1 where column1='XYZ'; DROP TABLE table1;--'

el uso de la versión args XYZ'; DROP TABLE table1;--se escaparía 'XYZ''; DROP TABLE table1;--'y solo se trataría como un valor. Incluso si 'no está destinado a hacer cosas malas, es bastante común que las personas lo tengan en sus nombres o lo usen en textos, nombres de archivos, contraseñas, etc. Así que siempre use la versión args. (Está bien construir inty otras primitivas directamente en whereClauseaunque)

zapl
fuente
¿Dónde cae el límite / compensación en este ... grupo por? ¿teniendo? orderby?
Lion789
3
@ Lion789 hay varias versiones que tienen un limitparámetro, por ejemplo developer.android.com/reference/android/database/sqlite/... que todo concatenación simplemente texto, al final lo que puede poner por ejemplo "some_column LIMIT 10"en orderByy aún funcionaría
zapl
¿Alguna opción aquí para unir 2 mesas?
Vijay Kumbhoje
2
@VijayKumbhoje deberías poder poner, por ejemplo table1 CROSS JOIN table2, el nombre de la tabla. Pero hay un punto donde miraría rawquery: stackoverflow.com/q/10598137/995891
zapl
3
@VijayKumbhoje con lo que te sientes más cómodo / se ve más limpio al final. Los querymétodos simplemente agregan algunas palabras clave como SELECTy FROMa los argumentos (ver fuente) y luego hacen una rawQuerycon la cadena de consulta resultante. Si su consulta no se ajusta bien a los argumentos disponibles de query, solo escriba la cadena de consulta usted mismo.
zapl
21

Esta es una respuesta más general que pretende ser una referencia rápida para futuros espectadores.

Ejemplo

SQLiteDatabase db = helper.getReadableDatabase();

String table = "table2";
String[] columns = {"column1", "column3"};
String selection = "column3 =?";
String[] selectionArgs = {"apple"};
String groupBy = null;
String having = null;
String orderBy = "column3 DESC";
String limit = "10";

Cursor cursor = db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit);

Explicación de la documentación.

  • table Cadena: el nombre de la tabla para compilar la consulta.
  • columns Cadena: una lista de las columnas a devolver. Pasar nulo devolverá todas las columnas, lo que se desaconseja para evitar la lectura de datos del almacenamiento que no se utilizará.
  • selection Cadena: un filtro que declara qué filas devolver, formateadas como una cláusula SQL WHERE (excluyendo WHERE). Pasar nulo devolverá todas las filas para la tabla dada.
  • selectionArgs Cadena: puede incluir? S en la selección, que se reemplazará por los valores de selectionArgs, para que aparezcan en la selección. Los valores se vincularán como cadenas.
  • groupBy Cadena: un filtro que declara cómo agrupar filas, formateadas como una cláusula SQL GROUP BY (excluyendo la propia GROUP BY). Pasar nulo hará que las filas no se agrupen.
  • having Cadena: un filtro declara qué grupos de filas incluir en el cursor, si se utiliza la agrupación de filas, formateada como una cláusula HAVING de SQL (excluyendo el propio HAVING). Pasar nulo hará que se incluyan todos los grupos de filas, y es obligatorio cuando no se utiliza la agrupación de filas.
  • orderBy Cadena: Cómo ordenar las filas, formateadas como una cláusula ORDER BY de SQL (excluyendo la ORDER BY). Pasar nulo utilizará el orden de clasificación predeterminado, que puede estar desordenado.
  • limit Cadena: limita el número de filas devueltas por la consulta, formateadas como cláusula LIMIT. Pasar nulo indica que no hay cláusula LIMIT.
Suragch
fuente
16

La cláusula where y los argumentos funcionan juntos para formar la instrucción WHERE de la consulta SQL. Entonces di que buscas expresar

WHERE Column1 = 'value1' AND Column2 = 'value2'

Entonces su whereClause y whereArgs serán los siguientes

String whereClause = "Column1 =? AND Column2 =?";
String[] whereArgs = new String[]{"value1", "value2"};

Si desea seleccionar todas las columnas de la tabla, creo que una cadena nula pasada a tableColumns será suficiente.

Ancantus
fuente
no incluir ?en 'el 'se añade de forma automática, si es necesario
zapl
1

si tu consulta SQL es así

SELECT col-1, col-2 FROM tableName WHERE col-1=apple,col-2=mango
GROUPBY col-3 HAVING Count(col-4) > 5  ORDERBY col-2 DESC LIMIT 15;

Luego, para el método query (), podemos hacer lo siguiente: -

String table = "tableName";
String[] columns = {"col-1", "col-2"};
String selection = "col-1 =? AND col-2=?";       
String[] selectionArgs = {"apple","mango"};
String groupBy =col-3;
String having =" COUNT(col-4) > 5";
String orderBy = "col-2 DESC";
String limit = "15";

query(tableName, columns, selection, selectionArgs, groupBy, having, orderBy, limit);
Puneet Verma
fuente
0
db.query(
        TABLE_NAME,
        new String[] { TABLE_ROW_ID, TABLE_ROW_ONE, TABLE_ROW_TWO },
        TABLE_ROW_ID + "=" + rowID,
        null, null, null, null, null
);

TABLE_ROW_ID + "=" + rowIDAquí =está la wherecláusula. Para seleccionar todos los valores, deberá proporcionar todos los nombres de columna:

or you can use a raw query like this 
db.rawQuery("SELECT * FROM permissions_table WHERE name = 'Comics' ", null);

y aquí hay un buen tutorial para la base de datos.

Avi Kumar Manku
fuente