Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

[SOLUCIONADO] Trigger

Estas en el tema de Trigger en el foro de Mysql en Foros del Web. Buenos días, estoy intentando realizar el siguiente trigger: @import url("http://static.forosdelweb.com/clientscript/vbulletin_css/geshi.css"); Código MySQL: Ver original USE tienda ;   DELIMITER $$ DROP TRIGGER IF EXISTS actualizar_stock$$ ...
  #1 (permalink)  
Antiguo 15/02/2016, 05:25
 
Fecha de Ingreso: julio-2015
Mensajes: 67
Antigüedad: 8 años, 8 meses
Puntos: 5
Trigger

Buenos días, estoy intentando realizar el siguiente trigger:

Código MySQL:
Ver original
  1. USE tienda;
  2.  
  3. DELIMITER $$
  4. DROP TRIGGER IF EXISTS actualizar_stock$$
  5. CREATE TRIGGER actualizar_stock AFTER INSERT ON detalles FOR EACH ROW
  6.  
  7.  
  8. DECLARE vstock INT(11);
  9. SET vstock = (SELECT stock FROM productos WHERE id_producto=NEW.id_producto);
  10. UPDATE productos SET stock=vstock-NEW.cantidad WHERE id_producto=NEW.id_producto;
  11.  
  12. END $$

Lo que quiero hacer, es que tras realizar un INSERT en la tabla detalles, se resten a la tabla productos la cantidad de productos utilizados en la compra, no sé si me he explicado bien..

El problema está en que me salta el siguiente mensaje de error:

Error Code: 1442. Can't update table 'productos' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

No tengo ningún otro trigger en dicha tabla, así que no entiendo muy bien de donde sale ese error.

Saludos y gracias.
  #2 (permalink)  
Antiguo 15/02/2016, 06:13
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Trigger

En principio, habría que analizar el INSERT que ejecutas para el detalle. Si ese INSERT usa la tabla PRODUCTOS en alguna forma, entonces no puedes utilizarla en este trigger. En caso de no ser eso, hay que revisar todos los SP y triggers que puedan estar involucrados en la operación, ya que puede haber un bloqueo en alguna etapa no visible.
Este tipo de entrecruzamientos de triggers no es tan raro como parece. Si abusas innecesariamente de los TRIGGERs es fácil que aparezcan interbloqueos de difícil diagnóstico. Tienes que tener muy en cuenta que un SELECT en una subconsulta que alimenta un INSERT/UPDATE, o bien un TRIGGER que ejecute una lectura de una tabla cualquiera, genera un bloqueo de escritura en esa tabla.

Por otro lado, hay un error de lógica: Los productos a entregar en una venta se deben reservar al momento de insertarse en la factura, pero sólo deben restarse al emitir el comprobante de venta/cobro.
Si la factura es el comprobante de venta, se hace entonces con el alta del pago en la caja.
La idea es que:
1) Sólo al emitir el pago el cliente el cliente se hace dieño del bien adquirido.
2) El bien en stock debe ser reservado para evitar que una venta en curso iniciada después de esta, lo elimine del stock antes de completar la venta.

Eso es a nivel sistema.

Por lo demás, esta línea es innecesaria:
Código MySQL:
Ver original
  1. SET vstock = (SELECT stock FROM productos WHERE id_producto=NEW.id_producto);
Puedes escribirlo asi:
Código MySQL:
Ver original
  1. DELIMITER $$
  2. DROP TRIGGER IF EXISTS actualizar_stock$$
  3. CREATE TRIGGER actualizar_stock AFTER INSERT ON detalles FOR EACH ROW
  4.  
  5.  
  6.     UPDATE productos SET stock = stock - NEW.cantidad
  7.     WHERE id_producto=NEW.id_producto;
  8.  
  9. END $$
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 15/02/2016, 06:39
 
Fecha de Ingreso: julio-2015
Mensajes: 67
Antigüedad: 8 años, 8 meses
Puntos: 5
Respuesta: Trigger

Cita:
Iniciado por gnzsoloyo Ver Mensaje
En principio, habría que analizar el INSERT que ejecutas para el detalle. Si ese INSERT usa la tabla PRODUCTOS en alguna forma, entonces no puedes utilizarla en este trigger. En caso de no ser eso, hay que revisar todos los SP y triggers que puedan estar involucrados en la operación, ya que puede haber un bloqueo en alguna etapa no visible.
Este tipo de entrecruzamientos de triggers no es tan raro como parece. Si abusas innecesariamente de los TRIGGERs es fácil que aparezcan interbloqueos de difícil diagnóstico. Tienes que tener muy en cuenta que un SELECT en una subconsulta que alimenta un INSERT/UPDATE, o bien un TRIGGER que ejecute una lectura de una tabla cualquiera, genera un bloqueo de escritura en esa tabla.
He estado revisando el INSERT, y no creo que interfiera en la tabla productos, pero es tan raro..no he podido detectar el fallo.

Hago directamente el INSERT en la tabla detalles, introduciendo el id_producto, id_venta, cantidad y precio, por lo que realmente en la tabla productos no se hace nada.

También he eliminado todos los TRIGGERS que tenía creado, he hecho un DROP de la base de datos completa, y tampoco..no sé donde puede estar el error.

Por lo del tema de la lógica, cree una base de datos simple, con 5 tablas únicamente, ya que era para realizar una práctica en la que tengo que crear procedimientos, funciones, triggers, etc.., la verdad es que por eso está mal estructurada, pero como era para algo rápido..

Este trigger en concreto es para realizar un control de campos derivados, por eso lo que quería hacer era que si se realizaba la compra de un producto, haciéndose un INSERT en detalles, después de realizarse, se restara de productos.

Para las pocas líneas que son, está dando muchos problemas..

Gracias por la respuesta, gnzsoloyo, seguiré dándole vueltas a la cabeza. :)
  #4 (permalink)  
Antiguo 15/02/2016, 07:10
 
Fecha de Ingreso: julio-2015
Mensajes: 67
Antigüedad: 8 años, 8 meses
Puntos: 5
Respuesta: Trigger

, ya encontré el fallo..resulta que si que estaba tirando de la tabla productos con el INSERT que hacía en detalles, ya que solicitaba el precio del producto con la id_producto dada.

Lo tenía delante de mí y era incapaz de verlo..

Saludos y gracias, marco el tema como solucionado.

Etiquetas: select, tabla, trigger
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:13.