none
Actualizar un registro de una tabla con otra tabla con un procedimiento en sql server que lo llamo en Visual Studio. RRS feed

  • Pregunta

  • Estimados Señores del foro, solicito de su ayuda para resolver un problema, estoy haciendo un programa de facturación en Sql Server 2014 y Visual Studio 2017, tengo mi tabla artículos que se va a estar actualizando su inventario con el ingreso de facturas que está dividida en dos tablas: ingreso y detalle_ingreso, cuando ingreso una factura los valores de la factura en este caso cantidad_unidad se vayan sumando a la existencia de la tabla artículo, hice un procedimiento en Sql Server que la llamo en Visual Studio para cuando ingrese la factura esta vaya sumando pero no lo está haciendo y también cuando esta sea anulada los valores regresen a su estado anterior, por lo que necesito de la valiosa colaboración del foro para superar este inconveniente que no me deja seguir trabajando en el proyecto y a mi falta de experiencia.

    Saludos y bendiciones.

    tabla articulo: idarticulo(llave), codigo, nombre, descripcion, imagen, idcategoria, existencia, caja, fardo, precio_venta, precio_costo, precio_distribuidor.

    tabla ingreso: idingreso(llave), idtrabajador, idproveedor, fecha, tipo_comprobante, serie, correlativo, iva, estado

    tabla detalle_ingreso: iddetalle_ingreso(llave), idingreso, idarticulo, precio_compra, cantidad_caja, cantidad_unidad, fecha_produccion, fecha_vencimiento 

    PROCEDIMIENTO EN SQL.

    ALTER proc [dbo].[update_articulos]

    @textobuscar int

    as

    update articulo set existencia+=@textobuscar

    from articulo a inner join detalle_ingreso d

    on a.idarticulo=d.idarticulo

    inner join ingreso i

    on d.idingreso=i.idingreso

    where i.estado='EMITIDO'

    CAPA PRESENTACION

    private void BtnAgregar_Click(object sender, EventArgs e)

            {

                try

                {

                    string rpta = "";

                    if (this.TxtIdArticulo.Text == string.Empty || this.TxtArticulo.Text == string.Empty ||

                        this.TxtPrecio_costo.Text == string.Empty)

                    {

                        MensajeError("Falta ingresar algunos datos, serán remarcados");

                        errorIcono.SetError(TxtIdArticulo, "Seleccione el Articulo");

                        errorIcono.SetError(TxtArticulo, "Seleccione el Articulo ");

                        errorIcono.SetError(TxtPrecio_costo, "Ingrese el costo del Articulo");

                    }

                    else

                    {

                        decimal SubTotal =Convert.ToDecimal(this.TxtCantidad_Un.Text) *                     Convert.ToDecimal(this.TxtCantidad_caja.Text)  * Convert.ToDecimal(this.TxtPrecio_costo.Text);

                            TotalPagado = TotalPagado + SubTotal;

                            this.LblTotal_pagado.Text = TotalPagado.ToString("#0.00#");

                            //agregar ese detalle al datalistadodetalle

                            DataRow row=this.DtDetalle.NewRow();

                            row["idarticulo"] = Convert.ToInt32(this.TxtIdArticulo.Text);

                            row["articulo"] = this.TxtArticulo.Text;

                            row["cantidad_caja"] = Convert.ToInt32(this.TxtCantidad_caja.Text);

                            row["cantidad_unidad"] = Convert.ToInt32(this.TxtCantidad_Un.Text);

                            row["precio_costo"] = Convert.ToDecimal(this.TxtPrecio_costo.Text);

                            row["fecha_produccion"] = DtFechaProd.Value;

                            row["fecha_vencimiento"] = DtFechaVen.Value;

                            row["iva"] = Convert.ToDecimal(this.TxtIva.Text);

                            row["subtotal"] = SubTotal;

                            this.DtDetalle.Rows.Add(row);

                            this.Limpiardetalle();

                            rpta = NIngresofact.Update_articulo(Convert.ToInt32(this.TxtCantidad_Un.Text));

                    }

                }

                catch (Exception ex)

                {

                    MessageBox.Show(ex.Message + ex.StackTrace);

                }

            }

    CAPA NEGOCIO

    public static string Update_articulo(int existencia_total)

            {

                DDetalle_ingreso Obj = new DDetalle_ingreso();

                Obj.Cantidad_unidad= existencia_total;

                return Obj.Update_Articulo(Obj);

            }

    CAPA DATOS

    public string Update_Articulo(DDetalle_ingreso Ingreso)

            {

                string rpta = "";

                SqlConnection SqlCon = new SqlConnection();

                try

                {

                    //Código

                    SqlCon.ConnectionString = Conexion.Cn;

                    SqlCon.Open();

                    //Establecer el Comando

                    SqlCommand SqlCmd = new SqlCommand();

                    SqlCmd.Connection = SqlCon;

                    SqlCmd.CommandText = "update_articulos";

                    SqlCmd.CommandType = CommandType.StoredProcedure;

                    SqlParameter ParCantidad = new SqlParameter();

                    ParCantidad.ParameterName = "@cantidad";

                    ParCantidad.SqlDbType = SqlDbType.Int;

                    ParCantidad.Value = Ingreso.Cantidad_unidad;

                    SqlCmd.Parameters.Add(ParCantidad);

                }

                catch (Exception ex)

                {

                    rpta = ex.Message;

                }

                finally

                {

                    if (SqlCon.State == ConnectionState.Open) SqlCon.Close();

                }

                return rpta;

            }

        }

    martes, 16 de octubre de 2018 17:11

Respuestas

  • Hola Ventura Estrada:

    Tu procedimiento no es correcto, por unos pequeños flecos. No puedes hacer esa relacion dentro del procedimiento sin mas, y no tienes constancia de que registro de articulos le estas modificando existencias. No puedes hacerlo a toda la tabla. (mejor, no debes)

    USE foros;
    GO
    CREATE TABLE articulo
    (idarticulo          INT
     PRIMARY KEY,
     codigo              INT,
     nombre              VARCHAR(10),
     descripcion         VARCHAR(10),
     imagen              VARCHAR(10),
     idcategoria         INT,
     existencia          INT,
     caja                INT,
     fardo               INT,
     precio_venta        FLOAT,
     precio_costo        FLOAT,
     precio_distribuidor FLOAT
    );
    GO
    INSERT INTO articulo
    (idarticulo,
     codigo,
     nombre,
     descripcion,
     imagen,
     idcategoria,
     existencia,
     caja,
     fardo,
     precio_venta,
     precio_costo,
     precio_distribuidor
    )
    VALUES
    (1,
     1,
     'a',
     'a',
     'imagen',
     1,
     10,
     1,
     1,
     15,
     3,
     6
    ),
    (2,
     1,
     'b',
     'b',
     'imagen',
     1,
     10,
     1,
     1,
     15,
     3,
     6
    ),
    (3,
     1,
     'b',
     'b',
     'imagen',
     1,
     10,
     1,
     1,
     15,
     3,
     6
    );
    GO
    CREATE PROCEDURE dbo.update_Articulos
    (@stock      INT,
     @idArticulo INT
    )
    AS
         UPDATE a
           SET
               existencia = existencia + @stock
         FROM articulo a
         WHERE a.idarticulo = @idArticulo;
    
    /* porque lo relacionas con ingreso, si no importa. si has efectuado el ingreso, cambias las existencias, y si no no.
    Si lo tienes que relacionar con detalle_ingreso, tienes que pasarle el identificador al procedimiento, o hacerlo 
    en el mismo procedimiento almacenado que hagas la inserccion del detalle ingreso. */
    
         RETURN;
    
    	 exec dbo.update_Articulos -5,1

    Este sería un modo simple de enfocarlo.

    Luego en tu Visual Studio, pon un punto de interrupción justo antes de invocar al procedure y comprueba, que es lo que le envias como parametros. Recuerda que le tienes que pasar tambien el articulo.

    Espero te ayude, sino comentas


    martes, 16 de octubre de 2018 20:01
  • Una rectificación al código.

    En esta linea de código mostrada mas abajo, la rectifique cambiando la variable como @textobuscar que declaré en el procedimiento update_articulos, aún así persiste el problema.

    Saludos a todos y bendiciones. 

    ParCantidad.ParameterName = "@textobuscar"; 


    martes, 16 de octubre de 2018 17:18
  • Si lo quieres hacer como planteas, en el mismo procedure, imagínate que tienes tres recibos simultaneos emitidos...... Además imaginate que tu le estas mandando el stock como parametro, si tu detalle_ingreso tiene 5 lineas con diferentes articulos, que le descontamos, lo mismo a las 5.

    Si le pasas como parametro el identificador del ingreso, y en el detalle, viene el codigo de articulo, entonces se puede hacer similar.

    CREATE PROCEDURE dbo.update_Articulos
    (@stock      INT,
     @idDetalle INT
    )
    AS
         UPDATE a
           SET
               existencia = existencia + @stock
    		    /*esto ya no haría falta, si tienes unidades en cada una de las lineas del detalle, se podría poner las mismas por ejemplo d.unidades */
         FROM articulo a inner join detalle_ingreso d
    		on a.idarticulo=d.idarticulo
    			inner join ingreso i
    		on d.idingreso=i.idingreso
    where i.estado='EMITIDO'
    and i.idDetalle = @idDetalle;
         
    return

    O algo del estilo

    martes, 16 de octubre de 2018 20:08

Todas las respuestas

  • Una rectificación al código.

    En esta linea de código mostrada mas abajo, la rectifique cambiando la variable como @textobuscar que declaré en el procedimiento update_articulos, aún así persiste el problema.

    Saludos a todos y bendiciones. 

    ParCantidad.ParameterName = "@textobuscar"; 


    martes, 16 de octubre de 2018 17:18
  • Hola VenturaEstrada, ¿por que no te planteas usar Entity Framework o Datasets para las operaciones con la base de datos?, en lo personal nunca me ha gustado manejar  las operaciones de base de datos y administrar SqlConnections, cuando ya hay herramientas en el Framework que simplifican las operaciones con las BD's como las que te menciono al principio.

    Carlos Aldi

    martes, 16 de octubre de 2018 18:19
  • Hola Ventura Estrada:

    Tu procedimiento no es correcto, por unos pequeños flecos. No puedes hacer esa relacion dentro del procedimiento sin mas, y no tienes constancia de que registro de articulos le estas modificando existencias. No puedes hacerlo a toda la tabla. (mejor, no debes)

    USE foros;
    GO
    CREATE TABLE articulo
    (idarticulo          INT
     PRIMARY KEY,
     codigo              INT,
     nombre              VARCHAR(10),
     descripcion         VARCHAR(10),
     imagen              VARCHAR(10),
     idcategoria         INT,
     existencia          INT,
     caja                INT,
     fardo               INT,
     precio_venta        FLOAT,
     precio_costo        FLOAT,
     precio_distribuidor FLOAT
    );
    GO
    INSERT INTO articulo
    (idarticulo,
     codigo,
     nombre,
     descripcion,
     imagen,
     idcategoria,
     existencia,
     caja,
     fardo,
     precio_venta,
     precio_costo,
     precio_distribuidor
    )
    VALUES
    (1,
     1,
     'a',
     'a',
     'imagen',
     1,
     10,
     1,
     1,
     15,
     3,
     6
    ),
    (2,
     1,
     'b',
     'b',
     'imagen',
     1,
     10,
     1,
     1,
     15,
     3,
     6
    ),
    (3,
     1,
     'b',
     'b',
     'imagen',
     1,
     10,
     1,
     1,
     15,
     3,
     6
    );
    GO
    CREATE PROCEDURE dbo.update_Articulos
    (@stock      INT,
     @idArticulo INT
    )
    AS
         UPDATE a
           SET
               existencia = existencia + @stock
         FROM articulo a
         WHERE a.idarticulo = @idArticulo;
    
    /* porque lo relacionas con ingreso, si no importa. si has efectuado el ingreso, cambias las existencias, y si no no.
    Si lo tienes que relacionar con detalle_ingreso, tienes que pasarle el identificador al procedimiento, o hacerlo 
    en el mismo procedimiento almacenado que hagas la inserccion del detalle ingreso. */
    
         RETURN;
    
    	 exec dbo.update_Articulos -5,1

    Este sería un modo simple de enfocarlo.

    Luego en tu Visual Studio, pon un punto de interrupción justo antes de invocar al procedure y comprueba, que es lo que le envias como parametros. Recuerda que le tienes que pasar tambien el articulo.

    Espero te ayude, sino comentas


    martes, 16 de octubre de 2018 20:01
  • Si lo quieres hacer como planteas, en el mismo procedure, imagínate que tienes tres recibos simultaneos emitidos...... Además imaginate que tu le estas mandando el stock como parametro, si tu detalle_ingreso tiene 5 lineas con diferentes articulos, que le descontamos, lo mismo a las 5.

    Si le pasas como parametro el identificador del ingreso, y en el detalle, viene el codigo de articulo, entonces se puede hacer similar.

    CREATE PROCEDURE dbo.update_Articulos
    (@stock      INT,
     @idDetalle INT
    )
    AS
         UPDATE a
           SET
               existencia = existencia + @stock
    		    /*esto ya no haría falta, si tienes unidades en cada una de las lineas del detalle, se podría poner las mismas por ejemplo d.unidades */
         FROM articulo a inner join detalle_ingreso d
    		on a.idarticulo=d.idarticulo
    			inner join ingreso i
    		on d.idingreso=i.idingreso
    where i.estado='EMITIDO'
    and i.idDetalle = @idDetalle;
         
    return

    O algo del estilo

    martes, 16 de octubre de 2018 20:08
  • Hola Carlos Aldi:

    Agradezco tu recomendación, no tenía conocimiento sobre estos framework voy a buscar videotutoriales sobre ellos.

    gracias.

    martes, 16 de octubre de 2018 23:00
  • Estimado Javi Fernández

    Agradezco tu repuesta, estaré probando con el código que me enviaste.

    Saludos.

    Denis Ventura.

    martes, 16 de octubre de 2018 23:33
  • Estimado Javi Fernández.

    Voy a realizar las pruebas, después aviso si me funciona.

    Saludos y bendiciones.

    martes, 16 de octubre de 2018 23:36