# [OF] Detener un insert en un trigger mysql (closed)

## Soul Lost

Tengo dos tablas: Ventas y Productos:

```

+--------------+----------+------+-----+---------+-------+

| Field        | Type     | Null | Key | Default | Extra |

+--------------+----------+------+-----+---------+-------+

| Codigo       | int(11)  | NO   | PRI |         |       | 

| Descripccion | char(30) | NO   |     |         |       | 

| Precio       | float    | NO   |     |         |       | 

| Existencia   | int(11)  | NO   |     | 0       |       | 

+--------------+----------+------+-----+---------+-------+

4 rows in set (0.00 sec)

+----------+----------+------+-----+---------+-------+

| Field    | Type     | Null | Key | Default | Extra |

+----------+----------+------+-----+---------+-------+

| Folio    | char(30) | NO   | PRI |         |       | 

| Codigo   | int(11)  | NO   | PRI |         |       | 

| Cantidad | int(11)  | NO   |     |         |       | 

| Precio   | float    | NO   |     |         |       | 

+----------+----------+------+-----+---------+-------+

4 rows in set (0.00 sec)

```

El uso del trigger (disparador) lo uso para cuando una nueva venta se realza y se ingresa en la base de datos, al mismo tiempo disminuya la existencia del producto respecto a la cantidad del mismo que se haya vendido. En el trigger existe una condición donde se verifica lo siguiente:

```

        DECLARE num Integer;

        select PRODUCTO.Existencia into num from PRODUCTO where PRODUCTO.Codigo = NEW.Codigo;

        IF num > NEW.Cantidad THEN

                update PRODUCTO set Existencia=Existencia-NEW.Cantidad where PRODUCTO.Codigo = NEW.Codigo;

        END IF;

```

El problema viene cuando  a pesar de que la existencia sea menor a la cantidad que quiera vender, el registro se ingresa y por lo tanto, la existencia no se ve afectada. En sqlserver se puede detener la inserción del registro con un ROLLBACK, pero en mysql según he leído en la documentación esto no es posible.

----------

## opotonil

La verdad que en bases de datos ando justito... mas bien ni idea, pero haciendo una busqueda en google por "mysql rollback" el tercer resultado que es de mysql.com: http://dev.mysql.com/doc/refman/5.0/en/commit.html ponen la sintaxis de rollback, asi que la sentencia existir parece que existe, en la version 5 no se cual estaras usando:

```

START TRANSACTION [WITH CONSISTENT SNAPSHOT] | BEGIN [WORK]

COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]

ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]

SET AUTOCOMMIT = {0 | 1}

```

Espero que te sirva, salu2.

----------

## Soul Lost

 *opotonil wrote:*   

> La verdad que en bases de datos ando justito... mas bien ni idea, pero haciendo una busqueda en google por "mysql rollback" el tercer resultado que es de mysql.com: http://dev.mysql.com/doc/refman/5.0/en/commit.html ponen la sintaxis de rollback, asi que la sentencia existir parece que existe, en la version 5 no se cual estaras usando:
> 
> ```
> 
> START TRANSACTION [WITH CONSISTENT SNAPSHOT] | BEGIN [WORK]
> ...

 

Eso lo sé, ya he mirado la documentación y lo digo por:

 *Quote:*   

> 
> 
> El disparador no puede utilizar sentencias que inicien o finalicen una transacción, tal como START TRANSACTION, COMMIT, o ROLLBACK.
> 
> 

 

http://dev.mysql.com/doc/refman/5.0/es/using-triggers.html

----------

## JuanSimpson

por qué no usas un trigger después del insert, así; sí la cantidad vendida es mayor que la cantidad de productos puedes hacer un delete, sí no: actualizar la cantidad de productos en la tabla productos.

----------

## Soul Lost

 *JuanSimpson wrote:*   

> por qué no usas un trigger después del insert, así; sí la cantidad vendida es mayor que la cantidad de productos puedes hacer un delete, sí no: actualizar la cantidad de productos en la tabla productos.

 

Ps se, es la única forma en la que he pensado que podría dar solución pero quería saber si es posible detenerlo con una simple instrucción para otros casos particulares.

Saludos!!

----------

## Soul Lost

He realizado el trigger de la siguiente forma:

```
create trigger disminuir_existencia AFTER INSERT ON DETALLE_DE_VENTA

FOR EACH ROW

BEGIN

        DECLARE Existencia_Producto Integer;

        select PRODUCTO.Existencia into Existencia_Producto from PRODUCTO where PRODUCTO.Codigo = NEW.Codigo;

        IF Existencia_Producto >= NEW.Cantidad THEN

                update PRODUCTO set Existencia=Existencia-NEW.Cantidad where PRODUCTO.Codigo = NEW.Codigo;

        ELSE

                delete from DETALLE_DE_VENTA where Folio = NEW.Folio AND Codigo = NEW.Codigo;

        

        END IF;

        

END|
```

Cuando la existencia es mayor o igual a la cantidad que se quiere vender, el registro del producto se actualiza correctamente como debe de ser, pero cuando no (en caso de ELSE) me aparece el siguiente mensaje:

```
mysql> insert into DETALLE_DE_VENTA values ('200716100002',3,5,600);

ERROR 1442 (HY000): Can't update table 'DETALLE_DE_VENTA' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
```

Y el registro de la nueva venta se da por alto, cosa que debería borrarse después de verificar que la venta no es posible.

----------

## JuanSimpson

mmm... tal vez puedas asignar null a un campo not null en la tabla ventas y así generar un error claro antes del insert

----------

## Soul Lost

 *JuanSimpson wrote:*   

> mmm... tal vez puedas asignar null a un campo not null en la tabla ventas y así generar un error claro antes del insert

 

Gracias no se me había ocurrido   :Razz:  pero funciona!   :Rolling Eyes:  .

Saludos!!

PD: Closed.

----------

