none
Multiples consultas con DataReader

    Pregunta

  • Cordial Saludo

    Hace algunos dias estoy desarrollando una aplicacion que consulta un listado de IDs en una tabla, pero necesito almacenar los resultados de cada consulta hasta terminar la lista, para luego mostrarlos. Les comparto una parte del codigo.

    Alguien sabe como puedo mostrar todos los resultados que obtuve en la consulta ?

                    If listIds.Count < 40 Then
                        For index = 0 To listIds.Count
                            cmd.CommandText = "SELECT * FROM TABLA t1 WHERE NIT = " & listIds(index) & ""
                            Try
                                dataReader = cmd.ExecuteReader
    
                                If dataReader.HasRows Then
                                    While dataReader.Read
                                        GridView1.DataSource = dataReader
                                        GridView1.DataBind()
    
                                         Catch ex As Exception
                            End Try


    • Editado fipoha martes, 17 de enero de 2017 20:19
    martes, 17 de enero de 2017 19:58

Respuestas

  • Basicamente lo que quiero es recorrer toda la lista de IDs que tengo (por ello utilizo el FOR), buscar cada uno en la tabla, y los que encuentre encuentre, mostrarlos en el Grid View

    Bien, pues eso no funcionará con el código tal como lo tienes ahora, así que hay que hacer algún cambio. Una primera opción es la que yo te comentaba en el mensaje anterior: En lugar de hacer un Select como este:

    "SELECT * FROM TABLA t1 WHERE NIT = " & listIds(index) & ""

    Cámbialo por

    "SELECT * FROM TABLA t1 WHERE NIT IN (" & listaDeNits & ")"

    Siendo listaDeNits una variable de tipo String que previamente habrás cargado con la lista de NITs separándolos por comas tal como "23,67,82,45". Evidentemente, para esto utilizarás un bucle FOR como el que ya tienes, iterando sobre listIds y concatenando los valores en el String.

    Otra posible opción para conseguir lo que quieres sin cambiar el Select consiste en cargar los dats en un DataTable usando un DataAdapter (en lugar de usar el DataReader). El DataAdapter tiene una opción que permite añadir los datos al DataTable en lugar de sustituir los datos (que es lo que hace por defecto). En consecuencia, podrías llamarlo dentro de tu bucle y cargaría el DataTable con toda la información que deseas. Después, una vez terminado el bucle, puedes asignar el DataTable al DataSource del grid, y eso mostraría los datos.

    miércoles, 18 de enero de 2017 18:28

Todas las respuestas

  • El fragmento de código que has mostrado tiene varios problemas. Está mezclando en el mismo código varias técnicas distintas que son incompatibles entre sí. Para empezar, lo de "if dataReader.HasRows" se usa cuando solo quieres extraer una única fila, y usas esa instrucción para saber si el DataReader ha conseguido leer una fila o no. En cambio, el "While dataReader.Read" se usa cuando quieres leer varias filas una por una. El While ya se salta por completo si no hay ninguna, por lo que no es necesario usar el "If dataReader.HasRows" cuando usas el "While".

    Y luego la otra técnica que existe es "GridView1.DataSource = dataReader". Cuando haces esto, el DataSource por dentro hace un While sobre el DataReader y lee todos sus registros. Funcionará francamente mal si lo pones dentro de un "While dataReader.Read", porque los dos Read (el que escribes y el que usa por dentro el DataSource) se "pelearán" entre sí y no obtendrás todos los registros.

    En resumidas cuentas, únicamente debes usar una (y solo una) de las tres técnicas que has mezclado en tu código. En este caso, la más simple es la del DataSource, que querará así:

    cmd.CommandText = "SELECT * FROM TABLA t1 WHERE NIT = " & listIds(index) & ""
    dataReader = cmd.ExecuteReader
    GridView1.DataSource = dataReader
    GridView1.DataBind()
    dataReader.Dispose()

    Ojo, esto a su vez lo tienes metido dentro de un "For". A cada vuelta del For, se machacarán los datos del GridView1, no se añadirán los nuevos datos. No está claro lo que quieres hacer, pero si se trata de traer varios NITs de la tabla, simplemente ponle un OR (o un IN) en el Where, en lugar de ejecutar un Select por cada NIT.

    martes, 17 de enero de 2017 21:23
  • Hola

    Muchas gracias por tus comentarios, los tomare en cuenta para mejorar el codigo, apenas estoy iniciando a programar en el lenguaje y todo eso es un gran aporte.

    Basicamente lo que quiero es recorrer toda la lista de IDs que tengo (por ello utilizo el FOR), buscar cada uno en la tabla, y los que encuentre encuentre, mostrarlos en el Grid View

    No se si me hago entender ahora?

    miércoles, 18 de enero de 2017 13:29
  • Hola:

    Si lo que quieres saber es los ID que tienes en la tabla, porque no haces una consulta de este tipo.
    SELECT id FROM tu_tabla ORDER BY  id.
    El resultado de la consulta (datatable) se lo asignas como origen de datos del DataGridView

    Un saludo desde Bilbo
    Carlos
    miércoles, 18 de enero de 2017 17:31
  • Basicamente lo que quiero es recorrer toda la lista de IDs que tengo (por ello utilizo el FOR), buscar cada uno en la tabla, y los que encuentre encuentre, mostrarlos en el Grid View

    Bien, pues eso no funcionará con el código tal como lo tienes ahora, así que hay que hacer algún cambio. Una primera opción es la que yo te comentaba en el mensaje anterior: En lugar de hacer un Select como este:

    "SELECT * FROM TABLA t1 WHERE NIT = " & listIds(index) & ""

    Cámbialo por

    "SELECT * FROM TABLA t1 WHERE NIT IN (" & listaDeNits & ")"

    Siendo listaDeNits una variable de tipo String que previamente habrás cargado con la lista de NITs separándolos por comas tal como "23,67,82,45". Evidentemente, para esto utilizarás un bucle FOR como el que ya tienes, iterando sobre listIds y concatenando los valores en el String.

    Otra posible opción para conseguir lo que quieres sin cambiar el Select consiste en cargar los dats en un DataTable usando un DataAdapter (en lugar de usar el DataReader). El DataAdapter tiene una opción que permite añadir los datos al DataTable en lugar de sustituir los datos (que es lo que hace por defecto). En consecuencia, podrías llamarlo dentro de tu bucle y cargaría el DataTable con toda la información que deseas. Después, una vez terminado el bucle, puedes asignar el DataTable al DataSource del grid, y eso mostraría los datos.

    miércoles, 18 de enero de 2017 18:28
  • Muchas gracias por tu ayuda!!

    Me sirvió muchísimo, realice la consulta con WHERE IN y con un GridView pude mostrar lo que necesitaba.

    viernes, 24 de febrero de 2017 11:24