none
Numerar los resultados de una busqueda en la base de datos (acces) en un label RRS feed

  • Pregunta

  • Hola, posiblemente esta pregunta se haya respondido ya, pero no la encuentro o tal vez no realizo bien la búsqueda en el foro.

    Estoy haciendo una opción de envió de notas entre los usuarios de la aplicación. Las notas que se envían se guardan en una base de datos acces.

    En el form principal tengo un timer que realiza la búsqueda en la base de datos por el nombre de usuario y el estatus del mensaje, si coinciden en un label aparece un mensaje indicando que tiene mensajes sin leer.

    Hasta aquí todo bien, ahora lo que pretendo que cuando realice la búsqueda en el label indique también el numero de los registros encontrados, algo así "tiene (5) mensajes".

    este es el código que uso para realizar la búsqueda:

    Dim consulta As String
            Dim conexion As New OleDbConnection
            Dim comandos As New OleDbCommand
            Dim adaptador As New OleDbDataAdapter
            Dim lector As OleDb.OleDbDataReader
            Dim a As String
            a = "no"
            conexion.ConnectionString = My.Settings.ChatConnectionString
            conexion.Open()
            consulta = "SELECT * FROM mensaje WHERE AUsuario = '" & My.Settings.user & "' and status = '" & a & "'"
            comandos = New OleDb.OleDbCommand(consulta, conexion)
            adaptador.SelectCommand = comandos
            lector = comandos.ExecuteReader
    
            If lector.Read = True Then
                Label1.ForeColor = Color.Red
                Label1.Text = "Tiene nuevas notas pendientes de leer"
    
            Else
                Label1.ForeColor = Color.Black
                Label1.Text = "No tiene notas pendientes de leer"
            End If

    Gracias y un saludo.

    domingo, 14 de febrero de 2016 9:30

Respuestas

  • Veo varias cosas en tu código:

    - en el código creas dos instancias de OleDbCommand, una al declarar la variable (instancia que no utilizas) y otra la que creas con la consulta y la conexión

    - creas un OleDbDataAdapter que en realidad no utilizas

    - por múltiples razones (seguridad, claridad, rendimiento) es conveniente utilizar siempre parámetros en tus consultas en lugar de concatenar los valores directamente en ellas

    - en la consulta recuperas todos los campos de la tabla mensaje cuando realmente sólo necesitas que te devuelva si existen o no registros

    En cuanto a lo que realmente preguntas: cómo saber el número de registros devueltos, puedes modificar la sentencia para realizar un SELECT COUNT(*) de forma que te devuelva el número de registros que cumplen las condiciones de la cláusula WHERE.

    Luego no tienes más que utilizar el método ExecuteScalar del objeto OleDbCommand para recuperar ese valor:

            Dim consulta As String
            Dim conexion As New OleDbConnection
            Dim comandos As OleDbCommand
            Dim a = "no"
            conexion.ConnectionString = My.Settings.ChatConnectionString
            conexion.Open()
            consulta = "SELECT COUNT(*) FROM mensaje WHERE AUsuario = ? and status = ?"
            comandos = New OleDb.OleDbCommand(consulta, conexion)
            comandos.Parameters.AddWithValue("?usuario", My.Settings.user)
            comandos.Parameters.AddWithValue("?status", a)
            Dim numeroRegistros = comandos.ExecuteScalar()
    
            If numeroRegistros > 0 Then
                Label1.ForeColor = Color.Red
                Label1.Text = String.Format("Tiene {0} nuevas notas pendientes de leer", numeroRegistros)
    
            Else
                Label1.ForeColor = Color.Black
                Label1.Text = "No tiene notas pendientes de leer"
            End If
    


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    • Marcado como respuesta nigoman domingo, 14 de febrero de 2016 10:30
    domingo, 14 de febrero de 2016 9:48
  • En general deberías cerrar la conexión con tu base de datos una vez recuperados los datos.

    Puedes realizar esto de manera sencilla utilizando la instrucción Using que se encargará de cerrar y destruir el objeto Connection:

            Dim numeroRegistros As Integer = 0
            Using conexion As New OleDbConnection(My.Settings.ChatConnectionString)
                Dim consulta As String
                Dim comandos As OleDbCommand
                Dim a = "no"
                conexion.Open()
                consulta = "SELECT COUNT(*) FROM mensaje WHERE AUsuario = ? and status = ?"
                comandos = New OleDb.OleDbCommand(consulta, conexion)
                comandos.Parameters.AddWithValue("?usuario", My.Settings.user)
                comandos.Parameters.AddWithValue("?status", a)
                numeroRegistros = comandos.ExecuteScalar()
            End Using
    
            If numeroRegistros > 0 Then
                Label1.ForeColor = Color.Red
                Label1.Text = String.Format("Tiene {0} nuevas notas pendientes de leer", numeroRegistros)
            Else
                Label1.ForeColor = Color.Black
                Label1.Text = "No tiene notas pendientes de leer"
            End If


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...


    • Editado Asier Villanueva domingo, 14 de febrero de 2016 12:15
    • Marcado como respuesta nigoman domingo, 14 de febrero de 2016 16:43
    domingo, 14 de febrero de 2016 12:15

Todas las respuestas

  • Veo varias cosas en tu código:

    - en el código creas dos instancias de OleDbCommand, una al declarar la variable (instancia que no utilizas) y otra la que creas con la consulta y la conexión

    - creas un OleDbDataAdapter que en realidad no utilizas

    - por múltiples razones (seguridad, claridad, rendimiento) es conveniente utilizar siempre parámetros en tus consultas en lugar de concatenar los valores directamente en ellas

    - en la consulta recuperas todos los campos de la tabla mensaje cuando realmente sólo necesitas que te devuelva si existen o no registros

    En cuanto a lo que realmente preguntas: cómo saber el número de registros devueltos, puedes modificar la sentencia para realizar un SELECT COUNT(*) de forma que te devuelva el número de registros que cumplen las condiciones de la cláusula WHERE.

    Luego no tienes más que utilizar el método ExecuteScalar del objeto OleDbCommand para recuperar ese valor:

            Dim consulta As String
            Dim conexion As New OleDbConnection
            Dim comandos As OleDbCommand
            Dim a = "no"
            conexion.ConnectionString = My.Settings.ChatConnectionString
            conexion.Open()
            consulta = "SELECT COUNT(*) FROM mensaje WHERE AUsuario = ? and status = ?"
            comandos = New OleDb.OleDbCommand(consulta, conexion)
            comandos.Parameters.AddWithValue("?usuario", My.Settings.user)
            comandos.Parameters.AddWithValue("?status", a)
            Dim numeroRegistros = comandos.ExecuteScalar()
    
            If numeroRegistros > 0 Then
                Label1.ForeColor = Color.Red
                Label1.Text = String.Format("Tiene {0} nuevas notas pendientes de leer", numeroRegistros)
    
            Else
                Label1.ForeColor = Color.Black
                Label1.Text = "No tiene notas pendientes de leer"
            End If
    


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    • Marcado como respuesta nigoman domingo, 14 de febrero de 2016 10:30
    domingo, 14 de febrero de 2016 9:48
  • Hola Asier, muchas gracias por responder. He probado el código,  al arrancar el form funciona correctamente, pero como esta metido en un timer para comprobar cada cierto tiempo si hay mensajes, cuando el timer vuelve a realizar la consulta me tira un error en el "conexion.Open()" , me dice que no se controló OleDbException "error no especificado"

    ¿Me podrías ayudar de nuevo?

    Gracias

    domingo, 14 de febrero de 2016 12:06
  • En general deberías cerrar la conexión con tu base de datos una vez recuperados los datos.

    Puedes realizar esto de manera sencilla utilizando la instrucción Using que se encargará de cerrar y destruir el objeto Connection:

            Dim numeroRegistros As Integer = 0
            Using conexion As New OleDbConnection(My.Settings.ChatConnectionString)
                Dim consulta As String
                Dim comandos As OleDbCommand
                Dim a = "no"
                conexion.Open()
                consulta = "SELECT COUNT(*) FROM mensaje WHERE AUsuario = ? and status = ?"
                comandos = New OleDb.OleDbCommand(consulta, conexion)
                comandos.Parameters.AddWithValue("?usuario", My.Settings.user)
                comandos.Parameters.AddWithValue("?status", a)
                numeroRegistros = comandos.ExecuteScalar()
            End Using
    
            If numeroRegistros > 0 Then
                Label1.ForeColor = Color.Red
                Label1.Text = String.Format("Tiene {0} nuevas notas pendientes de leer", numeroRegistros)
            Else
                Label1.ForeColor = Color.Black
                Label1.Text = "No tiene notas pendientes de leer"
            End If


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...


    • Editado Asier Villanueva domingo, 14 de febrero de 2016 12:15
    • Marcado como respuesta nigoman domingo, 14 de febrero de 2016 16:43
    domingo, 14 de febrero de 2016 12:15
  • Gracias de nuevo Asier por responder. Cuando he empezado a leer tu comentario me he dado cuenta que no cerraba la conexión. 

    ¿Es mas recomendable usar using que cerrar la conexión con un conexion.close()?

    Un saludo.

    domingo, 14 de febrero de 2016 16:42
  • Al utilizar Using .NET se encargará de llamar al método Dispose del objeto por lo que no sólo cierra la conexión si no que libera cualquier otro recurso que haya utilizado.

    De esta forma puedes despreocuparte de qué recursos tienes que liberar al dejar de utilizar el objeto, .NET lo hace por ti.


    Píldoras .NET
    Artículos, tutoriales y ejemplos de código .NET

    Píldoras JS
    Artículos, tutoriales y ejemplos de código JavaScript, HTML5, CSS3, ...

    domingo, 14 de febrero de 2016 20:14
  • Asier, gracias por tu respuesta nuevamente.

    Un saludo.

    domingo, 14 de febrero de 2016 23:25