none
Que le falta a mi procedimiento para que funcione ? RRS feed

  • Pregunta

  • saludos amigos del foro, estoy que doy vueltas pues no se que le falta a mi procedimiento para que funcione, me vota un error en el SqlDataReader, mi procedimiento es:

            //Funcion que valida un valor bit y devuelve un valor int 1 ó 0
            //Parametros: double pvalor : valor double
            private static int Valida_Bit(double pvalor)
            {
                if (pvalor == -1)
                {
                    return 1;
                }
                else 
                {
                    return 0;
                }
            }

            //Funcion que valida el acceso a los programas y reportes
            //Parametros: string idtabla : id de la tabla
            //            string Opcion  : Si es nuevo editar eliminar imprimir 
            public static double Acceso(string idtabla, string Opcion)
            {
                double Nuevo = 0, Editar= 0, Eliminar= 0, Imprimir = 0;
                
                using (SqlConnection con = new SqlConnection(conexion.CadenaConexion()))
                {
            
                    var cmd = new SqlCommand("SELECT * FROM usuarios INNER JOIN usuarios_priv ON usuarios.id = usuarios_priv.id WHERE" + 
                        " usuarios.nombre = @nomusuario AND usuarios_priv.idtabla = @idtabla", con);

                    try
                    {
                        cmd.Parameters.Add("@nomusuario", SqlDbType.VarChar).Value = Program.Sys_Usuario;
                        cmd.Parameters.Add("@idtabla", SqlDbType.VarChar).Value = idtabla;
                        con.Open();

                        SqlDataReader dr = cmd.ExecuteReader();

                        if (dr.HasRows)
                        {  
                            while (dr.Read())
                                Nuevo = Valida_Bit(Convert.ToDouble("nuevo"));
                                Editar = Valida_Bit(Convert.ToDouble("editar"));
                                Eliminar = Valida_Bit(Convert.ToDouble("eliminar"));
                                Imprimir = Valida_Bit(Convert.ToDouble("imprimir"));
                            }
                            
                            dr.Close();
                        }
                        
                    catch (Exception error)
                    {
                        MessageBox.Show(error.Message, "Login", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
                    }

                }

                if (Opcion == "Nuevo")
                    return Nuevo;
                else if (Opcion == "Editar")
                    return Editar;
                else if (Opcion == "Eliminar")
                    return Eliminar;
                else if (Opcion == "Imprimir")
                    return Imprimir;
                else
                    return 0;
            }

    y el error es:

    sábado, 16 de diciembre de 2017 7:03

Respuestas

  • sera que le falta algo para leer los registros

    Sí, falta llamar al dr:

       while (dr.Read())
       {
              Nuevo = Valida_Bit(Convert.ToDouble(dr["nuevo"]));
              Editar = Valida_Bit(Convert.ToDouble(dr["editar"]));
              Eliminar = Valida_Bit(Convert.ToDouble(dr["eliminar"]));
              Imprimir = Valida_Bit(Convert.ToDouble(dr["imprimir"]));
        }
    

    Esto presume que "nuevo", "editar", etc., son los nombres de los campos que quieres leer. También presume que su contenido es algo que se puede convertir a Double, de lo contrario dará un error al ejecutar el Convert.ToDouble.

    Pero nada de todo eso tiene nada que ver con el error que te salía acerca de que el SqlDataReader no tiene un constructor. Eso es un tema completamente distinto.

    Más cosas raras que observo:

    - Es inútil poner el if dr.HasRows si a continuación metes un bucle que hace el Read. El bucle ya se salta si el Read no encuentra nada, no hay necesidad de poner el HasRows. Pero esto no ocasionará ningún error, simplemente es redundante y superfluo.

    - A todas las vueltas del Read vuelves a machacar el valor de las mismas variables, con lo que solo te quedarás con el último de los registros que se lean desde la base de datos. Esto no tiene importancia si sabes con seguridad que solo va a existir un único registro, pero en ese caso lo que sobra es el while. Esto tampoco ocasionará ningún error, simplemente es algo que merece la pena tener en cuenta porque a lo mejor no es lo que esperabas que sucediese.

    - Lees una serie de campos, los conviertes a Double, después los pasas por una función que los convierte a int y después esos int los guardas en variables de tipo Double, y las variables tienen toda la pinta de que las vas a usar como si fueran bool. Todo esto es legítimo y se puede hacer sin que ocasione errores, pero da la sensación de que tienes un lío inmenso con los tipos de datos y no has dedicado ni un momento a pensar cuál es el tipo que realmente deberías estar manejando.

    • Marcado como respuesta Rudolf Heiner sábado, 16 de diciembre de 2017 20:34
    sábado, 16 de diciembre de 2017 20:02
    Moderador
  • Saludos Alberto gracias por la explicación, ahora si funciona mi procedimiento lo raro es que cargue el proyecto compile y funcionaba, no habia mas problema con el SqlDataReader, muchas gracias y saludos.
    • Marcado como respuesta Rudolf Heiner sábado, 16 de diciembre de 2017 20:36
    sábado, 16 de diciembre de 2017 20:36

Todas las respuestas

  • Algo falla que no se ve en el código aportado. El error que dice que "el SqlDataReader no tiene un constructor definido" ocurre cuando haces "new SqlDataReader" en lugar de llamar al SqlCommand para que éste construya el SqlDataReader. Pero no es tu caso, según el código presentado estás obteniendo el SqlDataReader en la manera correcta.

    Esto lleva a pensar que el error ocurre en otro sitio, o que es el resultado de una compilación anterior, o que Visual Studio se ha hecho un lío y está compilando alguna otra versión anterior del código. En cualquier caso, no es algo que se pueda apreciar examinando el código presentado, que parece ser correcto desde el punto de vista de este error en particular. De hecho, lo he copiado y pegado en Visual Studio y compila sin problemas. Tu problema tiene que estar en algún otro sitio.

    sábado, 16 de diciembre de 2017 8:52
    Moderador
  • Saludos Alberto y gracias por responder, sera que le falta algo para leer los registros aqui:

        while (dr.Read())

       {
              Nuevo = Valida_Bit(Convert.ToDouble("nuevo"));
              Editar = Valida_Bit(Convert.ToDouble("editar"));
              Eliminar = Valida_Bit(Convert.ToDouble("eliminar"));
              Imprimir = Valida_Bit(Convert.ToDouble("imprimir"));
        }

    quedo de ti y saludos.

    sábado, 16 de diciembre de 2017 18:21
  • sera que le falta algo para leer los registros

    Sí, falta llamar al dr:

       while (dr.Read())
       {
              Nuevo = Valida_Bit(Convert.ToDouble(dr["nuevo"]));
              Editar = Valida_Bit(Convert.ToDouble(dr["editar"]));
              Eliminar = Valida_Bit(Convert.ToDouble(dr["eliminar"]));
              Imprimir = Valida_Bit(Convert.ToDouble(dr["imprimir"]));
        }
    

    Esto presume que "nuevo", "editar", etc., son los nombres de los campos que quieres leer. También presume que su contenido es algo que se puede convertir a Double, de lo contrario dará un error al ejecutar el Convert.ToDouble.

    Pero nada de todo eso tiene nada que ver con el error que te salía acerca de que el SqlDataReader no tiene un constructor. Eso es un tema completamente distinto.

    Más cosas raras que observo:

    - Es inútil poner el if dr.HasRows si a continuación metes un bucle que hace el Read. El bucle ya se salta si el Read no encuentra nada, no hay necesidad de poner el HasRows. Pero esto no ocasionará ningún error, simplemente es redundante y superfluo.

    - A todas las vueltas del Read vuelves a machacar el valor de las mismas variables, con lo que solo te quedarás con el último de los registros que se lean desde la base de datos. Esto no tiene importancia si sabes con seguridad que solo va a existir un único registro, pero en ese caso lo que sobra es el while. Esto tampoco ocasionará ningún error, simplemente es algo que merece la pena tener en cuenta porque a lo mejor no es lo que esperabas que sucediese.

    - Lees una serie de campos, los conviertes a Double, después los pasas por una función que los convierte a int y después esos int los guardas en variables de tipo Double, y las variables tienen toda la pinta de que las vas a usar como si fueran bool. Todo esto es legítimo y se puede hacer sin que ocasione errores, pero da la sensación de que tienes un lío inmenso con los tipos de datos y no has dedicado ni un momento a pensar cuál es el tipo que realmente deberías estar manejando.

    • Marcado como respuesta Rudolf Heiner sábado, 16 de diciembre de 2017 20:34
    sábado, 16 de diciembre de 2017 20:02
    Moderador
  • Saludos Alberto gracias por la explicación, ahora si funciona mi procedimiento lo raro es que cargue el proyecto compile y funcionaba, no habia mas problema con el SqlDataReader, muchas gracias y saludos.
    • Marcado como respuesta Rudolf Heiner sábado, 16 de diciembre de 2017 20:36
    sábado, 16 de diciembre de 2017 20:36