none
Resultado de una query en un label RRS feed

  • Pregunta

  • Buenas , tengo una consulta SQL que me devuelve un valor y me gustaría ponerlo en la propiedad text de un label pero no se como , el código que tengo es este , la verdad que no tengo claro de como podría hacerlo.

            private void cargarMovimientosArticulo(int idArticulo,int tiendaArticulo)
            {
                using (SqlConnection Conn = Conexion.obtenerConexion())
                {
                    DataTable dt2 = new DataTable();
                    string query2 = "SELECT sum(uds) from Stock where idArticulo = " + idArticulo + " and tiendaArticulo=" + tiendaArticulo + " ";
                    SqlCommand cmd2 = new SqlCommand(query2, Conn);
                    SqlDataAdapter adap2 = new SqlDataAdapter(cmd2);
                    adap.Fill(dt2);
    
                    lblStockArticulo.Text = dt2;
     
                }
            }

    Gracias
    • Editado golfgti6 domingo, 21 de diciembre de 2014 18:14
    domingo, 21 de diciembre de 2014 18:13

Respuestas

  • podrias usar

    private void cargarMovimientosArticulo(int idArticulo,int tiendaArticulo) { using (SqlConnection Conn = Conexion.obtenerConexion()) { string query2 = "SELECT sum(uds) from Stock where idArticulo = @idArticulo and tiendaArticulo= @tiendaArticulo "; SqlCommand cmd2 = new SqlCommand(query2, Conn);

    cmd2.Parameters.AddWithValue("@idArticulo", idArticulo); cmd2.Parameters.AddWithValue("@tiendaArticulo", tiendaArticulo);

    lblStockArticulo.Text = Convert.ToString(cmd2.ExecuteScalar()); } }

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Propuesto como respuesta Jesús López lunes, 22 de diciembre de 2014 11:53
    • Marcado como respuesta golfgti6 lunes, 22 de diciembre de 2014 14:11
    lunes, 22 de diciembre de 2014 4:47
  •          Que tal amigo puedes retornar un scalar. Mira el ejemplo


    private void cargarMovimientosArticulo(int idArticulo,int tiendaArticulo) { using (SqlConnection Conn = Conexion.obtenerConexion()) { string query2 = "SELECT sum(uds) from Stock where idArticulo =@idArticulo and tiendaArticulo=@tiendaArticulo"; SqlCommand cmd2 = new SqlCommand(query2, Conn); cmd2.Open(); cmd.CommandType=CommandType.Text; cmd2.Parameters.AddWithValue("@idArticulo",idArticulo) cmd2.Parameters.AddWithValue("@tiendaArticulo",tiendaArticulo); lblStockArticulo.Text=cmd2.ExecuteScalar().ToString();

    cmd2.Close(); } }





    OBS: Favor vota si te es útil la información.
    Saludos 
    BEMO- Paraguay 
    https://tcsystems.wordpress.com/







    • Editado Bader Molinas lunes, 22 de diciembre de 2014 12:33
    • Marcado como respuesta golfgti6 lunes, 22 de diciembre de 2014 14:11
    lunes, 22 de diciembre de 2014 12:23

Todas las respuestas

  • Hola, mira lo encontré por internet, guíate por acá

    Fuente: CLICK PARA ABRIR FUENTE

    using System;
    using System.Windows.Forms;
    using System.Data;
    using System.Data.SqlClient; 
    
    namespace WindowsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                string connetionString = null;
                SqlConnection sqlCnn ;
                SqlCommand sqlCmd ;
                SqlDataAdapter adapter = new SqlDataAdapter();
                DataSet ds = new DataSet();
                int i = 0;
                string sql = null;
    
                connetionString = "Data Source=ServerName;Initial Catalog=DatabaseName;User ID=UserName;Password=Password";
                sql = "Select * from product";
    
                sqlCnn = new SqlConnection(connetionString);
                try
                {
                    sqlCnn.Open();
                    sqlCmd = new SqlCommand(sql, sqlCnn);
                    adapter.SelectCommand = sqlCmd;
                    adapter.Fill(ds);
                    for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
                    {
                        MessageBox.Show(ds.Tables[0].Rows[i].ItemArray[0] + " -- " + ds.Tables[0].Rows[i].ItemArray[1]);
                    }
                    adapter.Dispose();
                    sqlCmd.Dispose();
                    sqlCnn.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Can not open connection ! ");
                }
            }
        }
    }

    domingo, 21 de diciembre de 2014 18:42
  • Hola, mira lo encontré por internet, guíate por acá

    Fuente: CLICK PARA ABRIR FUENTE

    using System;
    using System.Windows.Forms;
    using System.Data;
    using System.Data.SqlClient; 
    
    namespace WindowsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                string connetionString = null;
                SqlConnection sqlCnn ;
                SqlCommand sqlCmd ;
                SqlDataAdapter adapter = new SqlDataAdapter();
                DataSet ds = new DataSet();
                int i = 0;
                string sql = null;
    
                connetionString = "Data Source=ServerName;Initial Catalog=DatabaseName;User ID=UserName;Password=Password";
                sql = "Select * from product";
    
                sqlCnn = new SqlConnection(connetionString);
                try
                {
                    sqlCnn.Open();
                    sqlCmd = new SqlCommand(sql, sqlCnn);
                    adapter.SelectCommand = sqlCmd;
                    adapter.Fill(ds);
                    for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
                    {
                        MessageBox.Show(ds.Tables[0].Rows[i].ItemArray[0] + " -- " + ds.Tables[0].Rows[i].ItemArray[1]);
                    }
                    adapter.Dispose();
                    sqlCmd.Dispose();
                    sqlCnn.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Can not open connection ! ");
                }
            }
        }
    }

    Gracias lo tomaré en cuenta , pero sobre el código que he puesto en el primer post que ya ejecuta la sql y devuelve el resultado me gustaría saber como recoger el campo devuelto y ponerlo en un label.


    Gracias !!!

    domingo, 21 de diciembre de 2014 18:47
  • Hola,

    Creo haberte recomendado que hagas uso de procedimientos almacenados y en caso de pasar parámetros hagas uso de la colección Parameteres del objeto Command. Además, si el procedimiento retornará sólo un valor has uso de ExecuteScalar.

    El método retorna un tipo de dato y quién lo llame recibirá el valor y hará lo que cree conveniente. No deberías dentro del método hacer esas asignaciones. ¿Qué pasará si quieres reutilizar ese método? ¿Que harás con esa asignación al label que tienes dentro?. Hay un principio en POO que menciona que las cosas deben de hacer  lo que tienen que hacer, no mas, no menos.

    Bueno, luego de estas directivas paso a ponerte el código.

    OJO... No tengo el contexto total. No asumas que te bastará hacer COPY+PaSTE. Has las correctivas necesarias.

    Código T-sql

    CREATE PROCEDURE uspStock
      @idArticulo int,
      @tiendaArticulo int
    AS
    BEGIN
      SET NOCOUNT ON;
    
      SELECT
        ISNULL(MAX(uds), 0)
      FROM
        Stock
      WHERE
        (idArticulo = @idArticulo)
        AND (tiendaArticulo = @tiendaArticulo);
    END

    Pues bien, ese procedimiento recibe dos parámetros y devuelve un valor. Hagamos la codificación 

    public int CargarMovimientosArticulo(int idArticulo, int tiendaArticulo)
    {
    using(SqlConnection Conn = Conexion.ObtenerConexion())
    {
      SqlCommand cmd2 = New SqlCommand("uspStock", Conn);
    
      cmd2.CommandType = CommandType.StoredProcedure;
    
      cmd2.Parameters.AddWithValue("@idArticulo", idArticulo);
      cmd2.Parameters.AddWithValue("@tiendaArticulo", tiendaArticulo);
    
      return cmd2.ExecuteScalar();
    }
    }

    Esté método devuelve un entero. Esté método lo llamaras para asignar el valor a la etiqueta que mencionas.

    lblStockArticulo.Text = CargarMovimientosArticulo(param1, param2);

    -----------------------------------------------------------------------------------------------------
    Espero haberte ayudado con mi sugerencia, si resolvió tu problema no olvides marcarla como respuesta.

    Willams Morales P.
    Arequipa - Perú



    domingo, 21 de diciembre de 2014 18:47
  • Bueno un poco mas resumido para ayudarte, esta devolviendo una lista pero guiate, este codigo trae una lista de clientes, en tu caso solo trae uno, si es uno debería ser lblStockArticulo.Text = Convert.ToString(row[0]);

    List<Cliente> ListaCliente = new List<Cliente>();

    TU CODIGO ESTA HASTA AQUI

    DataTable aux = dt2.Tables[0];

                foreach (DataRow row in aux.Rows)
                {
                    setCliente(row);

                    ListaCliente.Add(unCliente);

                }
                return ListaCliente;

    public void setCliente(DataRow row)
            {
                int IdCliente = Convert.ToInt32(row[0]);
                string Edad = Convert.ToString(row[1]);
                string Nombre = Convert.ToString(row[2]);
                string Apellido1 = Convert.ToString(row[3]);
                string Apellido2 = Convert.ToString(row[4]);
                string Direccion = Convert.ToString(row[5]);
                string Ocuapacion = Convert.ToString(row[6]);
                string Localidad = Convert.ToString(row[7]);
                string Telefono = Convert.ToString(row[8]);
                string Celular = Convert.ToString(row[9]);
                string Correo = Convert.ToString(row[10]);
                DateTime FechaAlta = Convert.ToDateTime(row[11]);
                string Sexo = Convert.ToString(row[12]);
                string Observaciones = Convert.ToString(row[13]);                                
                
                unCliente = new Cliente(IdCliente,Edad,Nombre,Apellido1,Apellido2,Direccion,Ocuapacion,Localidad,Telefono,Celular,Correo,FechaAlta,Sexo,Observaciones);

            }

    domingo, 21 de diciembre de 2014 19:04
  • podrias usar

    private void cargarMovimientosArticulo(int idArticulo,int tiendaArticulo) { using (SqlConnection Conn = Conexion.obtenerConexion()) { string query2 = "SELECT sum(uds) from Stock where idArticulo = @idArticulo and tiendaArticulo= @tiendaArticulo "; SqlCommand cmd2 = new SqlCommand(query2, Conn);

    cmd2.Parameters.AddWithValue("@idArticulo", idArticulo); cmd2.Parameters.AddWithValue("@tiendaArticulo", tiendaArticulo);

    lblStockArticulo.Text = Convert.ToString(cmd2.ExecuteScalar()); } }

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    • Propuesto como respuesta Jesús López lunes, 22 de diciembre de 2014 11:53
    • Marcado como respuesta golfgti6 lunes, 22 de diciembre de 2014 14:11
    lunes, 22 de diciembre de 2014 4:47
  • Willams,

    ¿Por qué recomiendas en este caso el uso de un procedimiento almacenado?

    Si es por rendimiento, el aumento es insignificante, probablemente si lo mides no puedas apreciarlo, unas veces te dará que es más rápida la instrucción parametrizada y otras el procedimiento.

    Si te preocupa  el rendimiento entonces lo que habría que recomendar es un buen índice para la consulta como el siguiente:

    CREATE INDEX IX_Stock_IdArticulo_IdTiendaArticulo
    ON Sock(IdArticulo, IdTiendaArticulo)
    INCLUDE (uds)

    La presencia de este índice hará volar la consulta, te lo aseguro.

    Por otra parte creo que hay otras cosas que recomendar, como por ejemplo la separación de responsabilidades. El código original mezcla instrucciones SQL con código c# y objetos de acceso a datos y de interfaz de usuario en un mismo método.

    Una recomendación sería separar el código de acceso a datos en clases aparte. Y para evitar mezclar el código SQL con el de c# podrían usarse recursos para los casos más sencillos y runtime t4 temples para los dinámicos y complicados.



    Jesús López


    EntityLite a lightweight, database first, micro orm





    lunes, 22 de diciembre de 2014 12:11
  •          Que tal amigo puedes retornar un scalar. Mira el ejemplo


    private void cargarMovimientosArticulo(int idArticulo,int tiendaArticulo) { using (SqlConnection Conn = Conexion.obtenerConexion()) { string query2 = "SELECT sum(uds) from Stock where idArticulo =@idArticulo and tiendaArticulo=@tiendaArticulo"; SqlCommand cmd2 = new SqlCommand(query2, Conn); cmd2.Open(); cmd.CommandType=CommandType.Text; cmd2.Parameters.AddWithValue("@idArticulo",idArticulo) cmd2.Parameters.AddWithValue("@tiendaArticulo",tiendaArticulo); lblStockArticulo.Text=cmd2.ExecuteScalar().ToString();

    cmd2.Close(); } }





    OBS: Favor vota si te es útil la información.
    Saludos 
    BEMO- Paraguay 
    https://tcsystems.wordpress.com/







    • Editado Bader Molinas lunes, 22 de diciembre de 2014 12:33
    • Marcado como respuesta golfgti6 lunes, 22 de diciembre de 2014 14:11
    lunes, 22 de diciembre de 2014 12:23
  • Hola,

    Creo haberte recomendado que hagas uso de procedimientos almacenados y en caso de pasar parámetros hagas uso de la colección Parameteres del objeto Command. Además, si el procedimiento retornará sólo un valor has uso de ExecuteScalar.

    El método retorna un tipo de dato y quién lo llame recibirá el valor y hará lo que cree conveniente. No deberías dentro del método hacer esas asignaciones. ¿Qué pasará si quieres reutilizar ese método? ¿Que harás con esa asignación al label que tienes dentro?. Hay un principio en POO que menciona que las cosas deben de hacer  lo que tienen que hacer, no mas, no menos.

    Bueno, luego de estas directivas paso a ponerte el código.

    OJO... No tengo el contexto total. No asumas que te bastará hacer COPY+PaSTE. Has las correctivas necesarias.

    Código T-sql

    CREATE PROCEDURE uspStock
      @idArticulo int,
      @tiendaArticulo int
    AS
    BEGIN
      SET NOCOUNT ON;
    
      SELECT
        ISNULL(MAX(uds), 0)
      FROM
        Stock
      WHERE
        (idArticulo = @idArticulo)
        AND (tiendaArticulo = @tiendaArticulo);
    END

    Pues bien, ese procedimiento recibe dos parámetros y devuelve un valor. Hagamos la codificación 

    public int CargarMovimientosArticulo(int idArticulo, int tiendaArticulo)
    {
    using(SqlConnection Conn = Conexion.ObtenerConexion())
    {
      SqlCommand cmd2 = New SqlCommand("uspStock", Conn);
    
      cmd2.CommandType = CommandType.StoredProcedure;
    
      cmd2.Parameters.AddWithValue("@idArticulo", idArticulo);
      cmd2.Parameters.AddWithValue("@tiendaArticulo", tiendaArticulo);
    
      return cmd2.ExecuteScalar();
    }
    }

    Esté método devuelve un entero. Esté método lo llamaras para asignar el valor a la etiqueta que mencionas.

    lblStockArticulo.Text = CargarMovimientosArticulo(param1, param2);

    -----------------------------------------------------------------------------------------------------
    Espero haberte ayudado con mi sugerencia, si resolvió tu problema no olvides marcarla como respuesta.

    Willams Morales P.
    Arequipa - Perú



    Gracias el tema de usar stored procedures lanzo una pregunta , en el caso de querer distribuir un ejecutable que tendrá muchas instalaciones igual no es lo más óptimo pero lo más "cómodo" es ponerlo dentro del ejecutable como sentencia sql no ?

    El problema que veo de hacer tantos stored procedures que bien si hay algún fallo deberé corregirlos y hacérselos llegar al cliente , en cambio si lo pongo dentro del ejecutable es más fácil distribuir el ejecutable.

    Ahí lanzo el debate.

    Muchas gracias !!!!!


    • Editado golfgti6 lunes, 22 de diciembre de 2014 14:17
    lunes, 22 de diciembre de 2014 14:16
  • golfgti6

    El tema de usar procedimientos almacenados va por el lado del rendimiento y la seguridad. No es correcto escribir las consultas y concatenar los parámetros en modo "texto" desde la aplicación, además de probables problemas en la performance atentas contra la seguridad (llámese SQL Inyection) encontrarás mucha información al respecto.

    Ahora, mencionas que es mas fácil hacer deployment de un ejecutable a actualizar un objeto de bd? En caso de actualizar un procedimiento lo ejecutas una sola vez contra la bd. Un ejecutable deberás distribuirlo en todos tus clientes que podría ser mas de uno. 

    Mi principio básico es que lo mejor no siempre es lo más fácil, ante eso intento hacer lo que se debe de hacer.



    lunes, 22 de diciembre de 2014 15:22
  • Willams,

    ¿Por qué recomiendas en este caso el uso de un procedimiento almacenado?

    Si es por rendimiento, el aumento es insignificante, probablemente si lo mides no puedas apreciarlo, unas veces te dará que es más rápida la instrucción parametrizada y otras el procedimiento.

    Si te preocupa  el rendimiento entonces lo que habría que recomendar es un buen índice para la consulta como el siguiente:

    CREATE INDEX IX_Stock_IdArticulo_IdTiendaArticulo
    ON Sock(IdArticulo, IdTiendaArticulo)
    INCLUDE (uds)

    La presencia de este índice hará volar la consulta, te lo aseguro.

    Por otra parte creo que hay otras cosas que recomendar, como por ejemplo la separación de responsabilidades. El código original mezcla instrucciones SQL con código c# y objetos de acceso a datos y de interfaz de usuario en un mismo método.

    Una recomendación sería separar el código de acceso a datos en clases aparte. Y para evitar mezclar el código SQL con el de c# podrían usarse recursos para los casos más sencillos y runtime t4 temples para los dinámicos y complicados.



    Jesús López


    EntityLite a lightweight, database first, micro orm





    Jesús, en el caso de usar procedimientos o texto SQL desde la aplicación yo tengo una máxima: "Si decido usar procedimientos almacenados pues lo hago y en todo lugar", suelo ser ordenado y que todo el equipo tenga claro que los procedimientos están en la base de datos, no dejo entrever que pueden encontrarlo en la aplicación o en la base de datos dependiendo del buen humor o tiempos del desarrollador, llámalo orden si deseas.  Hago uso de DACPAC que me permite tener el control de todos mis objetos de bd a nivel del mismo proyecto. También tengo a mano un generador de procedimientos que me permite ahorrar tiempos en crearlos (no todo, está claro).

    Respecto a optimizar la sentencia SQL, claro y muy de acuerdo. Imagínate si tendrías que responder cada requerimiento con todas las recomendaciones que puedan haber. Se haría largo, imagino que lo que se intenta es resolver el tema puntual y dar algunas recomendaciones de lo que consideramos es correcto. El usuario no menciona tener problemas de rendimiento.

    Finalmente, trate de mostrar en el ejemplo adjunto lo que bien mencionas: separación de responsabilidades. Pero, llegar al extremo de separar código c# del sql (que no veo en el ejemplo que adjunté) no crees que ya sería un extremo? El código debe de ser consistente, óptimo, seguro y fácil. Porque complicarlo con plantillas t4 y demás temas que no eleva el rendimiento ni la productividad?

    lunes, 22 de diciembre de 2014 15:42
  • >> "Si decido usar procedimientos almacenados pues lo hago y en todo lugar" <<

    Pues yo tengo la máxima "the right tool for the right job".  El uso de los procedimientos no es todo o nada, o los uso para todo o no los uso para nada. Hay cosas para las que pueden venir bien, y hay cosas para las que no. En mi opinión, para hacer consultas, generalmente no. Y sí para modificaciones basadas en conjuntos de filas. Lo del humor del desarrollador simplemente tiene gracia.

    << También tengo a mano un generador de procedimientos que me permite ahorrar tiempos en crearlos (no todo, está claro). <<

    ¿Y que genera ese generador? Cosas simples, me imagino. ¿Quien lo necesita? ¿a parte de los que quieren acceder a la base de datos sólo mediante procedimientos?

    >> Pero, llegar al extremo de separar código c# del sql (que no veo en el ejemplo que adjunté) no crees que ya sería un extremo? El código debe de ser consistente, óptimo, seguro y fácil. Porque complicarlo con plantillas t4 y demás temas que no eleva el rendimiento ni la productividad? <<

    No creo que sea un extremo, sino una buena práctica. Es horrible, difícil de leer, y de mantener, todo ese código sql concatenando cadenas, mezclado con el código c#. Si pones tu consulta en un fichero sql y luego lo incrustas en los recursos,  tienes tus ventajas, legilibilidad, intellisense, coloreado, y posibilidad de ejecutalo desde Visual Studio. Los T4 templates son para cuando quieres generar dinámicamente, en tiempo de ejecución, código sql en el lado del cliente, los considero una alternativa mucho más limpia y elegante que concatenar cadenas en un procedimiento almacenado y ejecutarlo con sp_executesql.



    Jesús López


    EntityLite a lightweight, database first, micro orm

    lunes, 22 de diciembre de 2014 17:42
  • >> 

    El tema de usar procedimientos almacenados va por el lado del rendimiento y la seguridad.  

    <<

    Eso no son más que mitos, de los que parece imposible deshacerse.

    La ganancia en rendimiento de un procedimiento almacenado comparado de una instrucción parametricada es del orden de 1%, o sea si el procedimiento tarda 10 milisegundos, la instrucción parametrizada tarda 10,1 miliseguntos. ¿A quien le importa?

    ¿Es que nadie, a parte de mi,  hace mediciones comparativas para corroborar o cazar los mitos?

    Y en cuando a inyección de código, las instrucciones parametrizadas no sufren del problema de inyección de código.

    Nuca debes concatenar cadenas con información introducida por el usuario sin validarla. Usa un parámetro en su lugar si es posible, y si no es posible, como por ejemplo el caso de  "ordenado por la columna x". Valida que x es realmente una columna. Por cierto, en este último caso, los procedimientos almadenados no te van a librar de sql dinámico, y tendrás que validar igualmente que x es una columna, porque si no podrás tener inyección sql.



    Jesús López


    EntityLite a lightweight, database first, micro orm

    lunes, 22 de diciembre de 2014 18:06