Inicio Android Bases de Datos en Android (III): Consultar/Recuperar registros

Bases de Datos en Android (III): Consultar/Recuperar registros

por sgoliver

En el anterior artículo del curso vimos todas las opciones disponibles a la hora de insertar, actualizar y eliminar datos de una base de datos SQLite en Android. En esta nueva entrega vamos a describir la última de las tareas importantes de tratamiento de datos que nos queda por ver, la selección y recuperación de datos.

De forma análoga a lo que vimos para las sentencias de modificación de datos, vamos a tener dos opciones principales para recuperar registros de una base de datos SQLite en Android. La primera de ellas utilizando directamente un comando de selección SQL, y como segunda opción utilizando un método específico donde parametrizaremos la consulta a la base de datos.

Para la primera opción utilizaremos el método rawQuery() de la clase SQLiteDatabase. Este método recibe directamente como parámetro un comando SQL completo, donde indicamos los campos a recuperar y los criterios de selección. El resultado de la consulta lo obtendremos en forma de cursor, que posteriormente podremos recorrer para procesar los registros recuperados. Sirva la siguiente consulta a modo de ejemplo:

Cursor c = db.rawQuery(" SELECT codigo,nombre FROM Usuarios WHERE nombre='usu1' ", null);

Como en el caso de los métodos de modificación de datos, también podemos añadir a este método una lista de argumentos variables que hayamos indicado en el comando SQL con el símbolo ‘?‘, por ejemplo así:

String[] args = new String[] {"usu1"};
Cursor c = db.rawQuery(" SELECT codigo,nombre FROM Usuarios WHERE nombre=? ", args);

Más adelante en este artículo veremos cómo podemos manipular el objeto Cursor para recuperar los datos obtenidos.

Como segunda opción para recuperar datos podemos utilizar el método query() de la clase SQLiteDatabase. Este método recibe varios parámetros: el nombre de la tabla, un array con los nombre de campos a recuperar, la cláusula WHERE, un array con los argumentos variables incluidos en el WHERE (si los hay, null en caso contrario), la cláusula GROUP BY si existe, la cláusula HAVING si existe, y por último la cláusula ORDER BY si existe. Opcionalmente, se puede incluir un parámetro al final más indicando el número máximo de registros que queremos que nos devuelva la consulta. Veamos el mismo ejemplo anterior utilizando el método query():

String[] campos = new String[] {"codigo", "nombre"};
String[] args = new String[] {"usu1"};

Cursor c = db.query("Usuarios", campos, "usuario=?", args, null, null, null);

Como vemos, los resultados se devuelven nuevamente en un objeto Cursor que deberemos recorrer para procesar los datos obtenidos.

Para recorrer y manipular el cursor devuelto por cualquiera de los dos métodos mencionados tenemos a nuestra disposición varios métodos de la clase Cursor, entre los que destacamos dos de los dedicados a recorrer el cursor de forma secuencial y en orden natural:

  • moveToFirst(): mueve el puntero del cursor al primer registro devuelto.
  • moveToNext(): mueve el puntero del cursor al siguiente registro devuelto.

Los métodos moveToFirst() y moveToNext() devuelven TRUE en caso de haber realizado el movimiento correspondiente del puntero sin errores, es decir, siempre que exista un primer registro o un registro siguiente, respectivamente.

Una vez posicionados en cada registro podremos utilizar cualquiera de los métodos getXXX(índice_columna) existentes para cada tipo de dato para recuperar el dato de cada campo del registro actual del cursor. Así, si queremos recuperar por ejemplo la segunda columna del registro actual, y ésta contiene un campo alfanumérico, haremos la llamada getString(1) [NOTA: los índices comienzan por 0 (cero), por lo que la segunda columna tiene índice 1], en caso de contener un dato de tipo real llamaríamos a getDouble(1), y de forma análoga para todos los tipos de datos existentes.

Con todo esto en cuenta, veamos cómo podríamos recorrer el cursor devuelto por el ejemplo anterior:

String[] campos = new String[] {"codigo", "nombre"};
String[] args = new String[] {"usu1"};

Cursor c = db.query("Usuarios", campos, "nombre=?", args, null, null, null);

//Nos aseguramos de que existe al menos un registro
if (c.moveToFirst()) {
     //Recorremos el cursor hasta que no haya más registros
     do {
          String codigo= c.getString(0);
          String nombre = c.getString(1);
     } while(c.moveToNext());
}

Además de los métodos comentados de la clase Cursor existen muchos más que nos pueden ser útiles en muchas ocasiones. Por ejemplo, getCount() te dirá el número total de registros devueltos en el cursor, getColumnName(i) devuelve el nombre de la columna con índice i, moveToPosition(i) mueve el puntero del cursor al registro con índice i, etc. Podéis consultar la lista completa de métodos disponibles en la clase Cursor en la documentación oficial de Android.

En este apartado he seguido ampliando la aplicación de ejemplo anterior para añadir la posibilidad de recuperar todos los registros de la tabla Usuarios pulsando un nuevo botón de consulta.

demo_app_3

Puedes consultar y/o descargar el código completo de los ejemplos desarrollados en este artículo accediendo a la página del curso en GitHub.

Con esto, terminamos la serie de artículos básicos dedicados a las tareas de mantenimiento de datos en aplicaciones Android mediante bases de datos SQLite. Soy consciente de que dejamos en el tintero algunos temas algo más avanzados (como por ejemplo el uso de transacciones, que intentaré tratar más adelante), pero con los métodos descritos podremos realizar un porcentaje bastante alto de todas las tareas necesarias relativas al tratamiento de datos estructurados en aplicaciones Android.

Curso de Programación Android en PDF

Este curso también está disponible en PDF. Descubre cómo conseguirlo…

¿Te ha sido de utilidad el Curso de Programación Android? ¿Quieres colaborar de forma económica con el proyecto? Puedes contribuir con cualquier cantidad, unos céntimos, unos euros, cualquier aportación será bienvenida. Además, si tu aportación es superior a una pequeña cantidad simbólica recibirás como agradecimiento un documento con la última versión del curso disponible en formato PDF. Sea como sea, muchas gracias por colaborar!

Más información:

También te puede interesar

40 comentarios

Desarrollo en Android | sgoliver.net blog 10/02/2011 - 11:44

[…] Bases de datos en Android (III): Consulta y recuperación de registros […]

Responder
Richard 21/02/2011 - 3:44

Muy interesante, pero, ¿cómo entonces excribiría por ejemplo un registro de la primera fila en TextView’s separados? Por ejemplo, tabla ‘persona’, campos ‘nombre’, ‘apellido’; hay varios registros pero quiero escribir nada más la primera fila, el ‘nombre’ en «@+id/Nombre» y el ‘apellido’ en «@+id/Apellido»…

Saludos.

Responder
Antonio 11/03/2011 - 10:55

Este magnífico tutorial me ha facilitado la vida un montón en mi iniciación con Android.

Felicidades

Responder
Joan Jesus 11/03/2011 - 18:21

Muchas gracias por publicar este blog. Una duda por favor.

En mi BBDD tengo descripciones con acentos, ñ y demás carácteres «normales». Cuando los recupero, ya sea con rawQuery o con query y los pongo en en String o en un array de strings me cambia los carácteres por carácteres extraños.

¿Cómo lo puedo resolver?

Mil gracias

Responder
Raquel 30/03/2011 - 12:47

¿Es posible trabajr con otras bases de datos que no sea SQLite? Tipo MySQL o PostgreSQL…

Un saludo!

Responder
William Velandia 26/05/2011 - 17:16

Como puedo realizar una consulta de varias tablas, si se utiliza JOIN en la instrucción de query como se define?

Responder
Jose Luis 25/06/2011 - 16:36

Estupendo el Curso que estás desarrollando. Me lo pido. Tanto los capítulos de los controles como los de SQL son muy buenos, pero ahora estoy intentando llenar un ListView con un cursor con una consulta SQL ¿Podrías poner un ejemplo sobre esto? Un saludo.

Responder
patispawn 24/07/2011 - 3:34

Estos tutoriales estan geniales esa era la informacion que necesitaba pero si no es mucho pedir un ejemplo con formularios..
De antemano gracias….

Responder
Content Providers en Android (I): Construcción | sgoliver.net blog 28/08/2011 - 12:01

[…] un criterio de ordenación. Todos estos datos son análogos a los que comentamos cuando tratamos la consulta de datos en SQLite para Android, artículo que recomiendo releer si no tenéis muy frescos estos conocimientos. El método query […]

Responder
Content Providers en Android (II): Utilización | sgoliver.net blog 31/08/2011 - 13:42

[…] consultar los artículos del curso dedicados al tratamiento de bases de datos SQLite, por ejemplo éste. Veamos cómo quedaría el […]

Responder
RafaAlbert 04/09/2011 - 8:12

Que tal, quisiera saber si la recuperacion de datos se puede hacer en forma de sincronizacion con la pc, de tal manera que si actualizo la base de datos en el dispositivo, pueda conectarlo a la pc y actualizar la bd en la pc tambien. grax

Responder
Eloy 29/11/2011 - 2:01

En esta parte de tratamiento de SQLite he echado de menos alguna mención a las claves primarias y a campos autogenerados (pk). Por lo demás bien en general.

Responder
car64 27/12/2011 - 2:05

Hola, es estado intentando lo del db.query pero parese ser que no me esta tomando encuenta el «?».

ya que si lo hago haci:
db.query(«Usuarios», campos, null, null, null, null, null);
si me lo toma pero encuando aañado el where y los paramentro me marca error:

db.query(«Usuarios», campos, «usuario=?», args, null, null, null);

Responder
sgoliver 27/12/2011 - 10:11

Hola Carlos, no indicas cuál es el error que te aparece, por lo que me resulta dificil responder a tu pregunta. En cualquier caso, te animo a que expongas tu consulta en el foro de la web de forma que puedan ayudarte también otros usuarios. Saludos.

Responder
cristian 15/01/2012 - 16:44

felicitaciones y gracias por este turotial de Base de Datos
muy bueno

Responder
Jesus 02/02/2012 - 19:10

Genial Bro, bien por ti gracias por compartir el conocimiento….

Responder
erick Gaillard 17/02/2012 - 1:39

buenas tardes estoy tratando de hacer esto mismo pero desde una base de datos no se si me puedas ayudar me marca error y no me permite cargar los datos este es el codigo me urge:

//Abrimos la base de datos ‘DBUsuarios’ en modo escritura
UsuariosSQLiteHelper usdbh =
new UsuariosSQLiteHelper(this, «DBUsuarios», null, 1);

SQLiteDatabase db = usdbh.getWritableDatabase();

//Si hemos abierto correctamente la base de datos
if(db != null)
{
//String[] campos = new String[] {«nombre», «monto», «direccion»};
//String[] args = new String[] {«Usuario»};
//Cursor c = db.query(«Usuarios», campos «nombre=?», null, null, null, null);
String[] args = new String[] {«Erick Gaillard»};
Cursor c = db.rawQuery(» SELECT _id,nombre,monto,direccion FROM Usuarios WHERE usuario=? «, args);
//Nos aseguramos de que existe al menos un registro
if (c.moveToFirst()) {
//Recorremos el cursor hasta que no haya más registros
// datos =
// new Titular[]{
// new Titular(«Título 1», «Subtítulo»,»Título 6″, «Subtítulo»),
// new Titular(«Título 2», «Subtítulo»,»Título 7″, «Subtítulo»),
// new Titular(«Título 3», «Subtítulo»,»Título 8″, «Subtítulo»),
// new Titular(«Título 4», «Subtítulo»,»Título 9″, «Subtítulo»),
// new Titular(«Título 5», «Subtítulo»,»Título «, «Subtítulo»)};

do {
String nombre = c.getString(0);
String monto = c.getString(1);
String direccion = c.getString(2);
//datos = new String[5];
//datos[1] = codigo;
//datos[2] = nombre;
//datos[2] = monto;
//datos[3] = direccion;

datos = new Titular[]{new Titular(nombre,monto, direccion,»test»)};

} while(c.moveToNext());

}

//Cerramos la base de datos
db.close();
}

Responder
principiante 27/03/2012 - 10:06

Simplemente gracias,

Responder
sSAS 28/03/2012 - 9:28

estaria bien que pusieras los ejemplos en un .rar o asi para poder descargarlos
muchas gracias pos los tutoriales

Responder
DanielL 01/04/2012 - 0:50

Hola, muchas gracias x los tutoriales. Aprendo muchisimo de ellos.

Hago y repito una consulta que vi mas arriba sobre los caracteres especiales.
Tengo un xml y lo parseo con una clase, alcanzo a crear la base de datos, la tabla y colocar los registros pero en aquellos donde existen caracteres especiales no los reconoce. Y coloca en su lugar otros caracteres extraños.

Mi consulta tal vez es mas sobre uso práctico y no tan técnico. Cúal es la mejor forma de cargar en una base de datos en Android desde un archivo externo xml y que reconozca los caracteres especiales??

Responder
jaime 03/05/2012 - 19:50

Hola un saludo yo quisiera saber como se haria un login en sqlite alguna idea
mi correo es jarol2340@hotmail.com
de antemano gracias

Responder
Oscar 25/07/2012 - 11:01

fantástico tutorial. Enhorabuena y muchas gracias!!!!!!!

Responder
Álvaro 22/08/2012 - 19:21

Un magnífico tutorial.

He echado en falta en estas tres secciones de base de datos el código fuente.

Muchas gracias

Responder
Joel 25/01/2013 - 21:54

Hola.. :)

Bueno mi problema es el siguiente al querer recuperar los datos me muestra el siguiente error.

cursorindexoutofboundsexception index 14 requested with a size of 14

al recuperar los datos usando cursor.moveToNext()

por favor ayudenme

Responder
Os 26/01/2013 - 1:26

Hola muchas gracias por este gran tutorial me ayudo mucho.
Tengo una gran pregunta puedo cambiar la direccion de donde se guarda la base de datos es decir que no se guarde en data/data/app_name/databases/nombre.db sino en otra direccion

Responder
Joel 26/01/2013 - 22:47

Bueno gracias a Dios logre arreglar el problema que tenia, era debido a los moveToNext()

Responder
Camilo 13/02/2013 - 23:38

Buenas tardes, tengo una base de datos ya creada la coloco en el emulador en la ruta:
mipaquete/data/data/databases/ y en el emulador funciona bien.Pero cuando la instalo la aplicacion en el dispositivo no me funciona.
Alguien sabe como soluciono esto?
Gracias

Responder
Hugo 04/03/2013 - 19:18

Hola. No tenés un ejemplo subido al Repositorio???

Responder
jose diaz 27/03/2013 - 19:18

Alguien sabe la solucion para lo que le paso a Joan?

Muchas gracias por publicar este blog. Una duda por favor.

En mi BBDD tengo descripciones con acentos, ñ y demás carácteres “normales”. Cuando los recupero, ya sea con rawQuery o con query y los pongo en en String o en un array de strings me cambia los carácteres por carácteres extraños.

¿Cómo lo puedo resolver?

Mil gracias

Responder
PilarR 18/06/2013 - 11:53

Buenas,

primero gracias por los tutoriales, son muy buenos, ahora me gustaría saber si hay alguna manera de sincronizar una base de datos del teléfono con otra que estaría almacenada en el ordenador.

Gracias

Responder
Mari 09/11/2013 - 0:59

Oye muchas gracias! tu tuto me ha servido un montón, como no tienes idea. Tengo una duda con este capítulo para las consultas, si la columna que estoy comparando en el «where» es del tipo booleano? en los argumentos pondría la palabra «false»?

mira estoy en algo así:
String[] campos = new String[] {«codigo», «nombre»,»activo»};
String[] args = new String[] {«false»};

Cursor c = db.query(«Usuarios», campos, «activo=?», args, null, null, null);

Responder
Gerardo 19/02/2014 - 14:42

Gracias mil por éste tema y todos los demás.

Responder
Eloy 28/02/2014 - 10:57

Hola… dos cosas:
Primero-> cuando haces esto:

if (c.moveToFirst()) {
     //Recorremos el cursor hasta que no haya más registros
     do {
          String codigo= c.getString(0);
          String nombre = c.getString(1);
     } while(c.moveToNext());
}

No se podría hacer también así:

while(c.moveToNext())
{
          String codigo= c.getString(0);
          String nombre = c.getString(1);
}

Segundo-> ¿se pueden utilizar arrays para almacenar datos en SQLite? O sea,,, ¿existe un tipo de datos array para SQLite? Tengo que almacenar en cada entrada de una tabla (además de otros datos) 4 campos de tipo string que tienen muchas cosas en común, tantas cosas tienen en común que si no puedo utilizar un array para estos campos sus etiquetas sería question1, question2, question3, question4…. Lo que pretendo es hacer un único campo question y meter un array de Strings.

Responder
Antonio 22/09/2014 - 15:33

Una consulta:

Estoy intentando actualizar la BD a través de internet, pero no sé como hacerlo. Mi idea es si hay conexión y contenido nuevo se actualiza y si no se queda como está.

La BD debe guardar imagen y link. Cosa que tampoco sé muy bien como hacer.

Pero lo primordial es ¿como actualizar a través de internet la BD?

Responder
alex 04/01/2015 - 0:20

una duda, necesito ejecutar varios metodos en el momento de iniciar mi aplicacion. Verificar si en mi BBDD hay registros si los hay mostrar el activity1 si no los hay entonces mostrar el activity2. Lo que busco es la equivalencia al evento LOAD de .NET…
he vista ya varios tutoriales y no ecuentro el bendito evento, lo que he encontrado es manipulado por botones.

Responder
Curso Programación Android por Salvador Gómez – Indice de Contenidos | Miguel Moyetones 17/06/2015 - 17:53

[…] Bases de datos en Android (III): Consulta y recuperación de registros [v3] […]

Responder
Mario German 14/03/2016 - 20:31

Hola: muchas gracias por compartir tu conocimiento: como se haría cuando los datos los quiero obtener desde una base de datos, es decir el número está almacenado en la base de datos y quiero obtener el número desde un botón en android y realizar la llamada, Me podrías ayudar gracias.

Responder
alejandro 13/06/2016 - 3:41

gracias por la data!!!, me di cuenta gracias a ver esto que me faltaba una ‘ (comilla simple) para que me funciones estuve varios dias para darme cuenta que el no such column de android era un error mio y era por la comilla!!!

Responder
Mario German 25/08/2016 - 16:36

Hola agradezco su aporte es de gran ayuda para los que estamos empezando en este medio, tengo la siguiente duda tengo 5 registros, id, nombre, telefono, correo, spinner como puedo guardar el valor del spinner dentro de una base de datos y posteriormente mostrar el dato guardado. Agradezco toda el ayuda que me puedas brindar es de gran ayuda para mi.

Responder
Sergio 21/11/2017 - 19:46

Sigo el blog desde hace no mucho. Lo encuentro estupendo, muy útil y se agradecen mucho esos ejemplos en el repositorio.
¡Mil gracias!

Responder

Dejar un comentario

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información. Aceptar Más Información

Política de Privacidad y Cookies