Trigger complejos MySQL

Iniciado por rubcr, 3 Junio 2020, 00:43 AM

0 Miembros y 1 Visitante están viendo este tema.

rubcr

Hola a todos.
Tengo que crear unos triggers y son bastante liosos para mi ya que no tengo el suficiente nivel para ello.
Las tablas dadas son las siguientes:
Código (sql) [Seleccionar]

CREATE TABLE Pedido(
 id_pedido INT PRIMARY KEY,
 fecha_ped DATE,
 total FLOAT,
 iva VARCHAR,
 id_vendedor INT,
 id_cliente INT,
);

CREATE TABLE Producto(
 id_producto INT PRIMARY KEY,
 descripcion VARCHAR,
 stock INT,
 precio FLOAT,
 estrellas INT(1)
);

CREATE TABLE Inventario(
 id_pedido INT,
 id_producto INT,
 cantidad INT DEFAULT 1,
 PRIMARY KEY(id_pedido, id_producto),
 CONSTRAINT FK_Inventario_Pedido FOREIGN KEY (id_pedido) REFERENCES Pedido(id_pedido),
 CONSTRAINT FK_Inventario_Producto FOREIGN KEY (id_producto) REFERENCES Producto(id_producto)
);


Los triggers son:
1.Trigger que al introducir una fila en la tabla que nace de la relación entre pedido y producto (inventario) , compruebe que en la tabla producto hay stock y sino tiré un warning.
2.Trigger que tras introducir un nuevo producto compruebe que el precio es mayor que 0. Si es menor o igual a 0, el trigger deberá eliminar el artículo que se ha insertado.

Espero que alguien pueda ayudarme.
Un saludo.


MCKSys Argentina

MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


rubcr

Cita de: MCKSys Argentina en  3 Junio 2020, 19:05 PM
Hola!

Revisa este tutorial: https://www.mysqltutorial.org/mysql-triggers/mysql-after-insert-trigger/

Saludos!
Hola gracias por el tutorial, pero no se ajusta al tipo de triggers que necesito ya que estos triggers no incluyen los datos generados en una tabla adicional.

Un saludo.

K-YreX

Cita de: rubcr en  3 Junio 2020, 00:43 AM
Los triggers son:
1.Trigger que al introducir una fila en la tabla que nace de la relación entre pedido y producto (inventario) , compruebe que en la tabla producto hay stock y sino tiré un warning.
En este caso puedes crear un trigger BEFORE INSERT que compruebe lo que tú dices y en caso de que no sea válido puedes ejecutar:
Código (sql) [Seleccionar]

SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insercion no valida...'

Te dejo un link para que leas más acerca de ello: https://dev.mysql.com/doc/refman/8.0/en/signal.html

Cita de: rubcr en  3 Junio 2020, 00:43 AM
2.Trigger que tras introducir un nuevo producto compruebe que el precio es mayor que 0. Si es menor o igual a 0, el trigger deberá eliminar el artículo que se ha insertado.
De la misma forma que antes. En vez de insertar el producto y después de la inserción, comprobar la validez del mismo; puedes usar un trigger BEFORE INSERT y lanzar otro error si no se cumple la condición de validez del registro.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

rubcr

Cita de: YreX-DwX en  4 Junio 2020, 11:33 AM
En este caso puedes crear un trigger BEFORE INSERT que compruebe lo que tú dices y en caso de que no sea válido puedes ejecutar:
Código (sql) [Seleccionar]

SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insercion no valida...'

Te dejo un link para que leas más acerca de ello: https://dev.mysql.com/doc/refman/8.0/en/signal.html
De la misma forma que antes. En vez de insertar el producto y después de la inserción, comprobar la validez del mismo; puedes usar un trigger BEFORE INSERT y lanzar otro error si no se cumple la condición de validez del registro.
Puedes ayudarme un poco con la sintaxis porque no se muy bien como estructurarlo y que seleccionar a parte de lo que me indicas.

K-YreX

Veo que el código que has puesto al comienzo del tema está completado en base a mi respuesta de este otro tema: https://foro.elhacker.net/bases_de_datos/pasar_a_mysql-t505018.0.html;msg2222689#msg2222689, lo que me hace pensar que no estás empleando ningún esfuerzo en hacerlo por ti mismo.

El foro es para ayudar, no para hacer tareas. No puedes esperar que te den todos los problemas solucionados porque en algún momento de tu vida tendrás que hacerlo tú solo y entonces no sabrás ni por dónde empezar.

Ya tienes un punto de referencia para saber por donde empezar, además tienes muchísima información tanto en otros temas del foro como en Internet sobre cómo hacer triggers.

Inténtalo tú e investiga sobre los problemas que tengas. Y cuando no encuentres información o no entiendas cómo solucionar un problema, aporta tu código para que alguien de la comunidad pueda ayudarte.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

rubcr

Cita de: YreX-DwX en  4 Junio 2020, 15:16 PM
Veo que el código que has puesto al comienzo del tema está completado en base a mi respuesta de este otro tema: https://foro.elhacker.net/bases_de_datos/pasar_a_mysql-t505018.0.html;msg2222689#msg2222689, lo que me hace pensar que no estás empleando ningún esfuerzo en hacerlo por ti mismo.

El foro es para ayudar, no para hacer tareas. No puedes esperar que te den todos los problemas solucionados porque en algún momento de tu vida tendrás que hacerlo tú solo y entonces no sabrás ni por dónde empezar.

Ya tienes un punto de referencia para saber por donde empezar, además tienes muchísima información tanto en otros temas del foro como en Internet sobre cómo hacer triggers.

Inténtalo tú e investiga sobre los problemas que tengas. Y cuando no encuentres información o no entiendas cómo solucionar un problema, aporta tu código para que alguien de la comunidad pueda ayudarte.
Para el primero tengo esto:
Código (sql) [Seleccionar]

CREATE TRIGGER test_stock 
AFTER INSERT ON inventario
FOR EACH ROW BEGIN
    IF (producto.stock < 0) THEN
        SIGNAL SQLSTATE '02000' SET MESSAGE_TEXT = 'Warning: No hay stock disponible!';
    END IF;
END$$

DELIMITER ;

No me genera nada y no sé por qué está mal.

K-YreX

Para empezar ese trigger salta después de la inserción por lo que aunque no sea válido el registro, ya estará insertado. Tiene que ser before.

Además no vale eso de producto.stock y ya. Cuando insertas un registro en Inventario, los campos que introduces son: id_pedido, id_producto, cantidad. Ninguno de ellos es stock. Así que lo que tienes que hacer es una consulta a la tabla Producto para obtener el registro asociado a ese id_producto.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

rubcr

#8
Cita de: YreX-DwX en  4 Junio 2020, 19:23 PM
Para empezar ese trigger salta después de la inserción por lo que aunque no sea válido el registro, ya estará insertado. Tiene que ser before.

Además no vale eso de producto.stock y ya. Cuando insertas un registro en Inventario, los campos que introduces son: id_pedido, id_producto, cantidad. Ninguno de ellos es stock. Así que lo que tienes que hacer es una consulta a la tabla Producto para obtener el registro asociado a ese id_producto.
Llevo varias horas intentando añadir lo que me indicas pero me has terminado de descolocar. Xddddd
Como hago una consulta a una tabla entera?


Cita de: YreX-DwX en  4 Junio 2020, 11:33 AM
En este caso puedes crear un trigger BEFORE INSERT que compruebe lo que tú dices y en caso de que no sea válido puedes ejecutar:
Código (sql) [Seleccionar]

SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insercion no valida...'

Te dejo un link para que leas más acerca de ello: https://dev.mysql.com/doc/refman/8.0/en/signal.html
De la misma forma que antes. En vez de insertar el producto y después de la inserción, comprobar la validez del mismo; puedes usar un trigger BEFORE INSERT y lanzar otro error si no se cumple la condición de validez del registro.
Hola de nuevo, el segundo trigger no se puede hacer, basicamente cuando haces un Insert la tabla se queda bloqueada y no podrias hacer otra accion como un delete seguida.
Y del primero no consigo hacer nada.

MOD: No hacer doble post. Usa el boton modificar.

K-YreX

Cita de: rubcr en  5 Junio 2020, 19:27 PM
Hola de nuevo, el segundo trigger no se puede hacer, basicamente cuando haces un Insert la tabla se queda bloqueada y no podrias hacer otra accion como un delete seguida.
Y del primero no consigo hacer nada.

Trigger para que no permita introducir en Inventario una cantidad mayor que la que tiene ese producto en la tabla Producto:
Código (sql) [Seleccionar]

DELIMITER //
CREATE TRIGGER TR_Inventario BEFORE INSERT ON Inventario FOR EACH ROW BEGIN
  DECLARE producto_stock INT;
  SELECT producto.stock INTO producto_stock FROM producto WHERE producto.id_producto = new.id_producto;
  IF(producto_stock < new.cantidad) THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error: Inventario';
  END IF;
END//
DELIMITER ;


Trigger que no permita introducir en la tabla Producto cantidades negativas:
Código (sql) [Seleccionar]

DELIMITER //
CREATE TRIGGER TR_Producto BEFORE INSERT ON Producto FOR EACH ROW BEGIN
  IF(new.cantidad < 1) THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Error: La cantidad tiene que ser mayor que 0';
  END IF;
END//
DELIMITER ;


He probado ambos triggers en una base de datos de prueba y funcionan. :silbar: :silbar:
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;