Mysql trigger is not updating record - mysql

I have two tables "Products" and "stocks". Products table will have all the products. In stock table, I save stock of product as a new entry each time.
I have two type of products. Product of "1" type will have stock as a number and product of "0" type will have stock as weight. Therefore, in products table I have created two columns "stock_weight (to keep total weight entered in stock table)" and "pieces (to keep total quantity entered in stock table)".
For this I have created a trigger on stock table that will execute to update total weight or quantity(pieces) in products table whenever I will insert new record into this table. Below is the code of trigger:
BEGIN
DECLARE product_type tinyint default 0;
SET product_type = (Select product_type from products where id = NEW.product_id);
IF (product_type = 0) THEN
UPDATE products set stock_weight = stock_weight + NEW.net_weight where id = NEW.product_id;
ELSE
UPDATE products set stock_pieces = stock_pieces + NEW.pieces where id = NEW.product_id;
END IF;
END
But after inserting new record in stock table for any product, nothing is updating in product table. I have debugged trigger and trigger is executing but nothing is updating in product table.
Can someone please tell me what I am missing and what thing I am doing wrong?

Don't give variables the same name as columns and anticipate nulls
DROP TABLE IF EXISTS PRODUCTS,STOCKS;
create table products(id int,product_type int,stock_weight int,stock_pieces int);
create table stocks(product_id int,net_weight int,pieces int);
drop trigger if exists t;
delimiter $$
create trigger t after insert on stocks
for each row
BEGIN
DECLARE vproduct_type tinyint default 0;
SET vproduct_type = (Select product_type from products where id = NEW.product_id);
IF (vproduct_type = 0) THEN
UPDATE products set stock_weight = coalesce(stock_weight,0) + NEW.net_weight where id = NEW.product_id;
ELSE
UPDATE products set stock_pieces = coalesce(stock_pieces,0) + NEW.pieces where id = NEW.product_id;
END IF;
END $$
delimiter ;
insert into products values(1,1,null,null),(2,0,null,null);
insert into stocks values(1,null,10),(2,10,null);
select * from products;
+------+--------------+--------------+--------------+
| id | product_type | stock_weight | stock_pieces |
+------+--------------+--------------+--------------+
| 1 | 1 | NULL | 10 |
| 2 | 0 | 10 | NULL |
+------+--------------+--------------+--------------+
2 rows in set (0.001 sec)

Related

Trigger to update a counter when data is entered in another table's column

Let's say I have a table named Count and a table named Records.
Count table:-
| countRecords | typeRecord |
|--------------|--------------------|
| 0 | type of record |
Records table:-
| ID | recordType |
|------------|------------------|
| id | type of record |
I want to update the countRecords as per the type in recordType in table Records. Whenever a user enters a recordType, I want to update the counter for it in Count table and whenever a user deletes a row/entry, I want to decrement the counter. How do I do this using a trigger?
Basically you need two triger
The insert trigger, as long as it only needs to update a row, can be done so.
If your database is more complex and you have fpor example an empty recordType , you need more code
CREATE TRIGGER after_recods_insert
AFTERINSERT
ON recods FOR EACH ROW
UPDATE count_table SET countRecords = countRecords +1 WHERE typeRecord = NEW.recordType ;
AN UPDATE Trigger ist somewhat more complex as you need to change teh count when the type changes
DELIMITER $$
CREATE TRIGGER after_recods_UPDATE
AFTER UPDATE
ON recods FOR EACH ROW
BEGIN
IF (OLD.recordType <> NEW.recordType) THEN
UPDATE count_table SET countRecords = countRecords -1 WHERE typeRecord = OLD.recordType ;
UPDATE count_table SET countRecords = countRecords +1 WHERE typeRecord = NEW.recordType ;
END IF;
END$$
DELIMITER ;
Serg is right, to complte the set
CREATE TRIGGER after_recods_delete
AFTER DELETE
ON recods FOR EACH ROW
UPDATE count_table SET countRecords = countRecords - 1 WHERE typeRecord = OLD.recordType ;

Using join in update command in trigger

I have 3 tables
'stockMedicina' (farmaciaID,seriemedicina,stock)
'Factura' (farmaciaid,facturaid)
'DetalleFactura' (facturaid,seriemedicina,cantidad)
and i want to update the inventory of stockMedicina which is an int named stock when i insert a new value to detalleFactura. So when i insert a new value in detalleFactura i want to update the inventory of the farmaciaid which is on the factura table to decrease the amount of stock. I have this code but it doesn't work, and i don't know what to do now. :(
DELIMITER $$;
CREATE TRIGGER diminuirStock
AFTER INSERT ON detalleFactura
FOR EACH ROW
BEGIN
UPDATE stockmedicina sm
INNER JOIN factura fa ON sm.farmaciaid = fa.farmacia
INNER JOIN detalleFactura df ON sm.seriemedicina = df.seriemedicina AND fa.facturaID=df.facturaID
SET sm.stock = sm.stock - NEW.cantidad
WHERE sm.FarmaciaID = fa.Farmacia and sm.seriemedicina=NEW.facturaID
END$$
DELIMITER ;
Any thought or help about it would be really helpful :c
Some of your columns have the false column name
Schema (MySQL v8.0)
CREATE TABLE stockMedicina (farmaciaID INT,seriemedicina INT ,stock INT);
INSERT INTO stockMedicina VALUES (1,1,10);
CREATE TABLE Factura (farmaciaid INT, faturaid INT);
INSERT INTO Factura VALUES (1,1);
CREATE TABLE DetalleFactura (facturaid INT ,seriemedicina INT ,cantidad INT);
DELIMITER $$
CREATE TRIGGER diminuirStock
AFTER INSERT ON DetalleFactura
FOR EACH ROW
BEGIN
UPDATE stockMedicina sm
INNER JOIN Factura fa ON sm.farmaciaID = fa.farmaciaid
INNER JOIN DetalleFactura df ON sm.seriemedicina = df.seriemedicina AND fa.faturaid=df.facturaID
SET sm.stock = sm.stock - NEW.cantidad
WHERE sm.FarmaciaID = fa.farmaciaid and sm.seriemedicina=NEW.facturaid;
END$$
DELIMITER ;
INSERT INTO DetalleFactura VALUES (1,1,2)
Query #1
SELECT * FROM stockMedicina;
| farmaciaID | seriemedicina | stock |
| ---------- | ------------- | ----- |
| 1 | 1 | 8 |
View on DB Fiddle

How to make triggers for delete and adding with if statement MySQL?

have two table's Queue (appointment_id, actual_time) Queue_Summary (date, doctor_id, num_of_patients)
The first is all the queues there are and the second is how many queues for each doctor on a certain date. I need to build a trigger that updates the num_of_patients, every time in Queue that a queue is added I need to add to a doctor num_of_patients on that date. Also when removing.
I have just counted the number of queues given a doctor_id and date, made it into two triggers.
But the only problem I have is where do I place the if statement that checks if this date is on Queue_Summary and if not adds it.
(P.S - Im not 100% on thoes also as my database is a bit off and does tons of problems, if there are any problem in thoes statments I'll be more them happy to know)
delimiter //
CREATE TRIGGER update_queue_summary
AFTER DELETE ON queue
FOR EACH ROW
BEGIN
update queue_summary as qs set num_of_patient = (
select count(appointment_id)
from queue as q join appointment as a on appointment_id
where a.doctor_id=qs.doctor_id and date(qs.actual_time)=date(qs.date())
group by appointment_id
) where doctor_id=qs.doctor_id and date(qs.actual_time)=date(qs.date());
END;//
delimiter ;
delimiter //
CREATE TRIGGER update_queue_summary
AFTER insert ON queue
FOR EACH ROW
BEGIN
update queue_summary as qs set num_of_patient = (
select count(appointment_id)
from queue as q join appointment as a on appointment_id
where a.doctor_id=qs.doctor_id and date(qs.actual_time)=date(qs.date())
group by appointment_id
) where doctor_id=qs.doctor_id and date(qs.actual_time)=date(qs.date());
END;//
delimiter ;
You should carry out an existence test in your trigger. For example
drop table if exists queue,queue_summary;
create table queue (appointment_id int auto_increment primary key, doctor_id int,actual_time datetime);
create table Queue_Summary (date date, doctor_id int, num_of_patients int);
delimiter $$
create trigger ut after insert on queue
for each row
begin
if not exists (select 1 from queue_summary where date = date(new.actual_time) and doctor_id = new.doctor_id) then
insert into queue_summary values(date(new.actual_time),new.doctor_id,1);
else
update queue_summary
set num_of_patients = num_of_patients + 1
where date = date(new.actual_time) and doctor_id = new.doctor_id;
end if;
end $$
delimiter ;
insert into queue (doctor_id,actual_time) values(1,'2020-05-03 09:00'),(1,'2020-05-03 09:30');
select * from queue;
select * from queue_summary;
MariaDB [sandbox]> select * from queue;
+----------------+-----------+---------------------+
| appointment_id | doctor_id | actual_time |
+----------------+-----------+---------------------+
| 1 | 1 | 2020-05-03 09:00:00 |
| 2 | 1 | 2020-05-03 09:30:00 |
+----------------+-----------+---------------------+
2 rows in set (0.001 sec)
MariaDB [sandbox]> select * from queue_summary;
+------------+-----------+-----------------+
| date | doctor_id | num_of_patients |
+------------+-----------+-----------------+
| 2020-05-03 | 1 | 2 |
+------------+-----------+-----------------+
1 row in set (0.001 sec)
And a delete trigger is similar but simpler
delimiter $$
create trigger dt after delete on queue
for each row
begin
if exists (select 1 from queue_summary where date = date(OLD.actual_time) and doctor_id = old.doctor_id) then
update queue_summary
set num_of_patients = num_of_patients - 1
where date = date(old.actual_time) and doctor_id = old.doctor_id;
end if;
end $$
delimiter ;
The existence check is entirely cosmetic since a delete won't complain if there is nothing to delete.

Trigger "AFTER INSERT" doesn't work, after insertion if I Add values in tables?

Purpose of trigger:
I should +add some number 50 to that user to table money where in table paym both columns table1 and table2 are not empty.
For example: User 'John' has both columns not empty and to him added 50 in table money.
Example in table below:
table: paym
ID username table1 Table2
+-------+-------------+-------------+-----------+
| 1 | John | Value | Value |
+-------+-------------+-------------+-----------+
| 2 | Alex | Null | Null |
+-------+-------------+-------------+-----------+
Table: money
ID username total_money
+-------+-------------+-------------+
| 1 | John | 50 |
+-------+-------------+-------------+
| 2 | Alex | 0 |
+-------+-------------+-------------+
Trigger below, works perfectly only when we insert all tables at one time. But it doesn't work if you insert only username two tables empty and after insertion, if you add values to empty tables table1 and table2 triggers not works at this point! Can we solve this problem???
Trigger should work even if we add value to the table After insertion!
DELIMITER $$
CREATE trigger update_money_after_paym
AFTER INSERT ON paym
FOR EACH ROW
BEGIN
IF (NEW.table1 IS NOT NULL AND NEW.table2 IS NOT NULL) THEN
UPDATE money SET total_money = total_money + 50 WHERE username = NEW.username;
END IF;
END;
$$
DELIMITER;
Not that trigger. It is an insert trigger, so it doesn't get called for an update.
If you want an update trigger, then define one:
DELIMITER $$
CREATE trigger update_money_after_paym
AFTER UPDATE ON paym
FOR EACH ROW
BEGIN
IF (NEW.table1 IS NOT NULL AND NEW.table2 IS NOT NULL) THEN
UPDATE money m
SET total_money = total_money + 50
WHERE m.username = NEW.username;
END IF;
END;
$$
DELIMITER;
This may not do exactly what you want. For instance, you might only want to add 50 when the previous values are both NULL:
DELIMITER $$
CREATE trigger update_money_after_paym
AFTER UPDATE ON paym
FOR EACH ROW
BEGIN
IF (NEW.table1 IS NOT NULL AND NEW.table2 IS NOT NULL AND
OLD.table1 IS NULL AND old.table2 IS NULL) THEN
UPDATE money m
SET total_money = total_money + 50
WHERE m.username = NEW.username;
END IF;
END;
$$
DELIMITER;

how to get the updated row from a table when calling a trigger after update

This is my table structure
mysql> select * from product_table;
+----------------+---------------------+
| product_number | product_description |
+----------------+---------------------+
| 1 | product one |
| 2 | product two |
| 3 | product three |
| 9 | product five |
| 10 | product six |
| 11 | product six |
+----------------+---------------------+
I want to say update a row say 9th product number from the table like this
UPDATE product_table SET product_description ="product seven" WHERE product_number=9;
So that in the trigger i can get the corresponding updated product number from the table product_table
I wrote the trigger like this and it got created without any errors.
DELIMITER //
CREATE TRIGGER product_table_update
AFTER UPDATE
ON product_table
FOR EACH ROW
BEGIN
DECLARE l_product_number INT;
set #l_table_name = 'product_table';
set #l_action = 'updation';
SET #l_table_column = 'product_description';
select new.product_number into #l_product_number from product_table;// here is i think where the problem is , i am trying to fetch the updated row to l_product_number
IF (OLD.product_description <> NEW.product_description) THEN
SET #oldval = OLD.product_description;
SET #newval = NEW.product_description;
select concat(#oldval,#newval) into #l_description;
END IF;
INSERT INTO audit_table_test
( table_name,
changed_row_id,
action,
table_column,
change_desciption,
change_time
)
VALUES
( #l_table_name,
#l_product_number,
#l_action,
#l_table_column,
#l_description,
NOW()
);
END; //
DELIMITER ;
then when i tried to update like this
UPDATE product_table SET product_description ="product seven" WHERE product_number=11;
This error is showing
ERROR 1172 (42000): Result consisted of more than one row
I know the problem has to be in this code
select new.product_number into #l_product_number from product_table;// here is i think where the problem is , i am trying to fetch the updated row to l_product_number
Please someone help me to get the update row on calling this trigger
Try:
...
SET #l_table_column = 'product_description';
/*
here is i think where the problem is , i am trying to fetch the
updated row to l_product_number
*/
-- select new.product_number into #l_product_number from product_table;
SET #l_product_number := NEW.product_number;
IF (OLD.product_description <> NEW.product_description) THEN
...