none
Validar stock con trigger RRS feed

  • Pregunta

  • Hola estoy utilizando este codigo para stock, pero deseo que si el producto llega a 0, no se realize la suma, ya que actualmente se suma. Ejemplo hay 10 en stock, y se registran 15, se queda en: -5 el stock.
    create trigger reduce_existencias
    After Insert
    As
    Begin
    
    Set Nocount on;
    update Producto set Stock=(Producto.Stock)-(Select Cantidad_Vendida From Inserted)
    Where IdArticulo = (Select IdArticulo from inserted)
    End
    
    Gracias.
    martes, 11 de febrero de 2014 2:16

Respuestas

  • Evidentemente, no puedes sacar directamente así el stock del producto. Tienes que hacer un select de la tabla de productos para obtener el stock. Y además deberías hacerlo ANTES del update, y ejecutar el update únicamente en el ELSE del IF (para que solo se ejecute el UPDATE si el stock es suficiente).

    Y adicionalmente, hay que tener en cuenta que esto no funcionará en caso de que se inserten simultaneamente varios registros, y se dispare el trigger una sola vez para todos ellos. En este caso, tendrás que usar una técnica parecida a la que indicaba Qwalgrande en un mensaje anterior, para ver si alguno de ellos excede el stock. Quedará complicadillo y habrá que probarlo bien; no es un trigger sencillo que se pueda escribir en un minuto.

    Quedará algo parecido a lo siguiente, pero no lo interpretes literalmente al pie de la letra; sobre este ejemplo que te pongo habrá que realizar los ajustes y modificaciones necesarios para adaptarlo a tu caso concreto, corrigiendo los errores que contenga:

    if Exists(select 1
        from productos p
        join inserted i on p.IdArticulo=i.IdArticulo
        where p.stock<i.cantidad_vendida)
    begin
        THROW 51000,'Stock insuficiente',1
    end
    else
    begin
    with CTE as (
      select IdArticulo, Vend = sum(Cantidad_Vendida)
      from Inserted
      group by IdArticulo
    )
    update P set Stock = 
      case when P.Stock > CTE.Vend then P.Stock - CTE.Vend else 0 end
    from 
      Producto P inner join 
      CTE on P.IdArticulo = CTE.IdArticulo
    end

    • Marcado como respuesta T2014 sábado, 15 de febrero de 2014 20:24
    sábado, 15 de febrero de 2014 20:10

Todas las respuestas

  • Puedes poner un CASE en el Update:

    update Producto set Stock=
    case when (Producto.Stock)-(Select Cantidad_Vendida From Inserted)>0 then (Producto.Stock)-(Select Cantidad_Vendida From Inserted) else 0 end
    Where IdArticulo = (Select IdArticulo from inserted)

    Pero tendrías que plantearte si con esto es suficiente, o si no sería conveniente hacer un THROW para lanzar una excepción en el caso de que intenten vender más unidades de las que hay en stock, para alertar de esta anomalía en lugar de simplemente dejar el stock en cero de manera silenciosa.

    martes, 11 de febrero de 2014 7:14
  • Hola.

    Adicionalmente, comentar que el trigger no funcionará si se inserta más de un artículo. Es preciso transformarlo a una solución de conjuntos:

    ;with CTE as (
      select IdArticulo, Vend = sum(Cantidad_Vendida)
      from Inserted
      group by IdArticulo
    )
    
    update P set Stock = 
      case when P.Stock > CTE.Vend then P.Stock - CTE.Vend else 0 end
    from 
      Producto P inner join 
      CTE on P.IdArticulo = CTE.IdArticulo


    Alberto López Grande
    SQL Server MVP
    Visita mi blog en http://qwalgrande.com
    Sígueme en twitter en http://twitter.com/qwalgrande

    martes, 11 de febrero de 2014 10:40
    Moderador
  • Antes al insertar 5 compras del stock cuando solo quedan 3, realiza la venta y quedaba en -2, actualmente con el codigo actual queda en 0, Pero igual sigue registrando ventas.

    create trigger reduce_existencias
    on Detalle_Venta
    After Insert
    As
    Begin
    Set Nocount on;
    update Producto set Stock=
    case when (Producto.Stock)-(Select Cantidad_Vendida From Inserted)>0 then (Producto.Stock)-(Select Cantidad_Vendida From Inserted) else 0 end
    Where IdArticulo = (Select IdArticulo from inserted)
    End

    Asi es como queda, pero tienes razon, silenciosamente queda en 0.
    lo correcto seria que a la vez cuando este en cero indique que no acepta más ventas.
    Se quiere vender 5 productos del stock que esta en 3, que confirme realmente si el stcok esta para dar.  Actualmente con el codigo si realiza la venta y queda en 0.
    Disculpe el poco conocimiento en tema de stock.

    viernes, 14 de febrero de 2014 20:12
  • Podrías poner algo así como

    IF Producto.Stock<(Select Cantidad_Vendida From Inserted) BEGIN THROW 51000,"Stock insuficiente",1 END

    Evidentemente el programa cliente debe interceptar el error mediante un try/catch o instrucción equivalente en el lenguaje que se esté empleando, con el fin de informar debidamente al usuario en el caso de que se produzca este error.

    Nota: La instrucción THROW es nueva en SQL Server 2012. Si estás usando una versión más antigua, utiliza RAISERROR.

    sábado, 15 de febrero de 2014 6:18
  • create trigger reduce_existencias
    on Detalle_Venta
    After Insert
    As
    Begin
    Set Nocount on;
    update Producto set Stock=
    case when (Producto.Stock)-(Select Cantidad_Vendida From Inserted)>0 then (Producto.Stock)-(Select Cantidad_Vendida From Inserted) else 0 end
    Where IdArticulo = (Select IdArticulo from inserted)
    IF Producto.Stock<(Select Cantidad_Vendida From Inserted) BEGIN THROW 51000,'Stock insuficiente',1 END
    End
    SQL 2012.
    El identificador formado por varias partes "Producto.Stock" no se pudo enlazar.
    sábado, 15 de febrero de 2014 19:37
  • Evidentemente, no puedes sacar directamente así el stock del producto. Tienes que hacer un select de la tabla de productos para obtener el stock. Y además deberías hacerlo ANTES del update, y ejecutar el update únicamente en el ELSE del IF (para que solo se ejecute el UPDATE si el stock es suficiente).

    Y adicionalmente, hay que tener en cuenta que esto no funcionará en caso de que se inserten simultaneamente varios registros, y se dispare el trigger una sola vez para todos ellos. En este caso, tendrás que usar una técnica parecida a la que indicaba Qwalgrande en un mensaje anterior, para ver si alguno de ellos excede el stock. Quedará complicadillo y habrá que probarlo bien; no es un trigger sencillo que se pueda escribir en un minuto.

    Quedará algo parecido a lo siguiente, pero no lo interpretes literalmente al pie de la letra; sobre este ejemplo que te pongo habrá que realizar los ajustes y modificaciones necesarios para adaptarlo a tu caso concreto, corrigiendo los errores que contenga:

    if Exists(select 1
        from productos p
        join inserted i on p.IdArticulo=i.IdArticulo
        where p.stock<i.cantidad_vendida)
    begin
        THROW 51000,'Stock insuficiente',1
    end
    else
    begin
    with CTE as (
      select IdArticulo, Vend = sum(Cantidad_Vendida)
      from Inserted
      group by IdArticulo
    )
    update P set Stock = 
      case when P.Stock > CTE.Vend then P.Stock - CTE.Vend else 0 end
    from 
      Producto P inner join 
      CTE on P.IdArticulo = CTE.IdArticulo
    end

    • Marcado como respuesta T2014 sábado, 15 de febrero de 2014 20:24
    sábado, 15 de febrero de 2014 20:10
  • Gracias, fue todo lo que necesitaba, Al fin termine este proyecto.
    sábado, 15 de febrero de 2014 20:24
  • BUENAS TARDE HERMANO

    EXCELENTE LA EXPLICACION ...

    ME GUSTARIA POR FAVOR COMO SE PODRIA HACER ESO EN C#

    POR MEDIO DE UN BOTON

    motacarlosjuan@hotmail.com 

    este mi correo por favor

    BENDICIONES HERMANO 

    miércoles, 11 de septiembre de 2019 16:52
  • Hola Juan carlos mota de la paz:

    Este hilo ha sido validado en 2014. Si quieres tener una respuesta más precisa a tu escenario, pregúntalo en un nuevo hilo.

    Intenta acercarte a lo propuesto en este escenario.

    Ayudanos a ayudarte Sql Server

    Ahora bien, si como dices lo que quieres es un botón en c#, esto no tiene nada que ver con un trigger.

    Entonces quizá, el mejor sitio para poner la pregunta es:

    Foro c#

    En el foro de c#, para poder ayudarte mejor, sigue estos consejos.

    Ayudanos a ayudarte C#


    miércoles, 11 de septiembre de 2019 19:43