trigger to update values of another table according to input of first table - mysql

Create or replace Trigger t1 AFTER INSERT ON feedback
FOR EACH ROW
BEGIN
IF new.rating = 1 THEN update count SET count=count+1 WHERE scale="one";
ELSE IF new.rating = 2 THEN UPDATE count SET count=count+1 WHERE scale="two";
ELSE IF new.rating = 3 THEN UPDATE count SET count=count+1 WHERE scale="three";
ELSE IF new.rating = 4 THEN UPDATE count SET count=count+1 WHERE scale="four";
ELSE IF new.rating = 5 THEN UPDATE count SET count=count+1 WHERE scale="five";
END IF;
END
//
table feedback
table count
I want to write trigger which update value of count in table count according to new insert values in feedback.
e.g. if I insert value of rating as 3 in 'feedback' table then it will automatically update value of count of 'three' in 'count table' by 1.And suppose if I insert value of rating as 5 in 'feedback' table then it will automatically update value of count of 'five' in 'count table' by 1.
syntax error in above code

This
Create Trigger <trigger_name> AFTER INSERT OR UPDATE ON <FIRST_TABLE_NAME>
FOR EACH ROW
BEGIN
//update statement
END;
//
Source : https://dev.mysql.com/doc/refman/5.5/en/trigger-syntax.html

Here trigger is written on feedback table and inside trigger value of counter updating which is in another count table so that is not possible. when you write trigger you should update values of columns present in table on which trigger is written only. so here first we should write procedure and call it from trigger.
procedure:
create procedure c(cnt int(10))
begin
DECLARE rating_temp int (20);
DECLARE cur CURSOR FOR SELECT cnt;
OPEN cur;
FETCH cur INTO rating_temp;
IF rating_temp=5 then
update count1 SET counter=(counter+1) where scale="five";
ELSEIF rating_temp=4 then
update count1 SET counter=(counter+1) where scale="four";
ELSEIF rating_temp=3 then
update count1 SET counter=(counter+1) where scale="three";
ELSEIF rating_temp=2 then
update count1 SET counter=(counter+1) where scale="two";
ELSEIF rating_temp=1 then
update count1 SET counter=(counter+1) where scale="one";
END IF;
CLOSE cur;
END$$
2) trigger-
CREATE TRIGGER t1
AFTER INSERT
ON feedback
FOR EACH ROW
BEGIN
Declare cnt2 int(10);
select new.rating into cnt2;
call c(cnt2);
END$$

Related

How to solve error 1442 : Can`t update table 'tb_name' in stored fuction/trigger in mysql?

delimiter $$
create trigger payment_mile_trigger
after insert on PAYMENT
for each row
begin
if #mileuse = 'all' then
update customer
set cust_usedmile = cust_usedmile + cust_currentmile
and cust_currentmile = 0
where customer.cust_id = new.cust_id;
elseif #mileuse > 0 then
update customer
set cust_usedmile = cust_currentmile + #mileuse
and cust_currentmile = cust_currentmile - #mileuse
where customer.cust_id = new.cust_id;
end if ;
end $$
delimiter ;
delimiter $$
create trigger Booking_trigger3
before insert on Booking
for each row
begin
declare pay_totalamount int;
declare time_stamp timestamp;
declare pay_type varchar(15);
declare key_id int;
declare cust_id int;
set pay_totalamount = new.booking_totalamount;
set time_stamp = current_timestamp();
set pay_type = #paytype;
set key_id = null;
set cust_id = new.cust_id;
if #mileuse = 'all' then
insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id)
value ((select cust_currentmile from customer where customer.cust_id=cust_id),
time_stamp, 'mile',key_id,cust_id);
insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id)
value (pay_totalamount-(select cust_currentmile from customer where cust_id=cust_id),
time_stamp, pay_type,key_id,cust_id);
elseif #mileuse > 0 then
insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id)
value (#mileuse,
time_stamp, 'mile',key_id,cust_id);
insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id)
value (pay_totalamount-#mileuse,
time_stamp, pay_type,key_id,cust_id);
else
insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id)
value (pay_totalamount,time_stamp, pay_type,key_id,cust_id);
end if;
end $$
delimiter ;
I created two triggers.
One is a trigger that inserts two data into the payment table if you pay with mileage when making a reservation. (Payment of mileage, the remaining amount is paid by other payment methods)
And the other trigger is to deduct mileage.
If there is an item paid with mileage in the payment table, the mile is deducted from the customer table.
But I get an error:
Error Code: 1442. Can't update table 'customer' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
My guess is that this issue is due to a conflict of the above two triggers. This is because the one is selects data(mileage) from the customer table when all mileage is used, but the other one is updates data(mileage) from customer table.
I found two problems.
The first is that mileage is not deducted from the customer table.
The second problem is that when I set #mileuse = 'all' , I get the same error as the title.
How can I solve this problem?
I solved this problem in a slightly different way.
delimiter $$
create trigger Booking_trigger3
before insert on Booking
for each row
begin
declare pay_totalamount int;
declare time_stamp timestamp;
declare pay_type varchar(15);
declare key_id int;
declare cust_id int;
set pay_totalamount = new.booking_totalamount;
set time_stamp = current_timestamp();
set pay_type = #paytype;
set key_id = null;
set cust_id = new.cust_id;
if #mileuse > 0 then
insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id)
value (#mileuse,
time_stamp, 'mile',key_id,cust_id);
insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id)
value (pay_totalamount-#mileuse,
time_stamp, pay_type,key_id,cust_id);
else
insert into payment(pay_totalamount,pay_date,pay_type,key_id,cust_id)
value (pay_totalamount,time_stamp, pay_type,key_id,cust_id);
end if;
end $$
delimiter ;
I deleted 'if #mileuse = all then ...'
select #mileuse := '0';
select #mileuse :=
(select cust_currentmile from customer
where cust_id = #custid); # all mile pay
And I decided to split the variable in two.
This doesn't seem like a fundamental solution, but it was the best way to implement it.

No rows fetching from stored procedure

I have created a stored procedure like this, when I try to call it shows
call points;
$$
329 (02000): No data - zero rows fetched, selected, or processed
What is the error in this stored procedure?
DELIMITER $$
CREATE PROCEDURE POINTS()
BEGIN
DECLARE NAMEEE VARCHAR(15);
declare monthcount int(10);
DECLARE CUR2 CURSOR for SELECT * FROM TEMP;
open CUR2;
read_loop: LOOP
FETCH CUR2 INTO NAMEEE;
select monthlycount into monthcount from incident where name=NAMEEE;
if monthcount <= 3 then
UPDATE INCIDENT SET POINTS="10" WHERE NAME=NAMEEE;
elseif (monthcount > 3 and monthcount <=6) then
UPDATE INCIDENT SET POINTS="20" WHERE NAME=NAMEEE;
elseif (monthcount > 6 and monthcount <=9) then
UPDATE INCIDENT SET POINTS="30" WHERE NAME=NAMEEE;
elseif (monthcount >9 and monthcount <=12) then
UPDATE INCIDENT SET POINTS="40" WHERE NAME=NAMEEE;
elseif (monthcount >12 ) then
UPDATE INCIDENT SET POINTS="50" WHERE NAME=NAMEEE;
end if;
END LOOP;
CLOSE CUR2;
end $$
Here are my tables
CREATE TABLE IF NOT EXISTS INCIDENT(
NAME VARCHAR(45) NOT NULL,
DAILYCOUNT INT(10),
WEEKLYCOUNT INT(10),
MONTHLYCOUNT INT(10),
POINTS INT(10) NOT NULL
);
insert into incident values("peter","1","2","3","0");
insert into incident values("thomas","1","2","4","0");
insert into incident values("franklins","1","2","6","0");
insert into incident values("yedhu","1","2","8","0");
CREATE TABLE IF NOT EXISTS TEMP
(
NAME VARCHAR(15)
);
insert into temp values("peter");
insert into temp values("thomas");
insert into temp values("franklins");
insert into temp values("yedhu");
Your whole stored procedure can be expressed using a single multi-table update statement. The update statement joins the 2 tables on name and name fields, and updates the points field based on the value in the monthcount field. ceil() effectively rounds up the results of the division. The if() function introduces the cap at 12.
update incident inner join temp on incident.name=temp.namee
set incident.points=if(incident.monthcount<=12,ceil(incident.monthcount / 3) * 10, 50)
So, you can avoid having a complicated stored procedure and replace it with a s

trigger after insert delete query not working

I am writing trigger to work after insert and check if count records more than 500 make delete one record but not work this trigger
CREATE TRIGGER `delrecord` after insert on `tbl_coins`
FOR EACH ROW
BEGIN
DECLARE recordcount INT;
DECLARE deleterecordcount INT;
set recordcount = (select count(*) from tbl_coins);
if recordcount > 500
then
set deleterecordcount = (select ID from tbl_coins order by time asc limit 1);
delete from tbl_coins
where ID = deleterecordcount;
end if;
END

Mysql trigger to update empty field with condition

I have a MySQL table , look like this
t id lang title
1 7 en_UK my_title
1 7 kh_KH
I want write a trigger that update title to my_title with the same id is 7
Result
t id lang title
1 7 en_UK my_title
1 7 kh_KH my_title
From my understanding.
DELIMITER $$
CREATE TRIGGER upd_title BEFORE UPDATE ON `term`
FOR EACH ROW BEGIN
IF (NEW.title IS NULL OR NEW.title= '') THEN
SET NEW.title= ??? ;
END IF;
END$$
DELIMITER ;
[UPDATE1]->not works (trigger not being created)
DELIMITER $$
DROP TRIGGER IF EXISTS `update_category_after_insert`
CREATE TRIGGER `update_category` AFTER INSERT ON `categories`
FOR EACH ROW BEGIN
DECLARE loc_title text;
IF (NEW.libelle_categorie IS NULL OR NEW.libelle_categorie= '') THEN
select libelle_categorie into loc_title from categories where NEW.num_noeud= num_noeud and langue = 'en_UK';
SET NEW.libelle_categorie = loc_title;
END IF;
END
DELIMITER ;
[UPDATE2]
DELIMITER $$
CREATE TRIGGER ``update_category_after_insert`` BEFORE INSERT ON `categories`
FOR EACH ROW BEGIN
DECLARE loc_title text;
IF (NEW.libelle_categorie IS NULL OR NEW.libelle_categorie= '') THEN
select libelle_categorie into loc_title from categories where NEW.num_noeud= num_noeud and langue = 'en_UK';
SET NEW.libelle_categorie = loc_title;
END IF;
END
DELIMITER ;
Finally , I found the good solution for my case
UPDATE categories c INNER JOIN categories c2 ON (
c.num_noeud = c2.num_noeud
) SET c.libelle_categorie = c2.`libelle_categorie`
Can you clarify?
Are you trying to pull the value from the title column in the 'en_UK' row that exists when you insert an new row with the same id that HAS the title column not entered?
okay
CREATE TRIGGER upd_title BEFORE UPDATE ON `term`
FOR EACH ROW BEGIN
DECLARE loc_title VARCHAR(20);
IF (NEW.title IS NULL OR NEW.title= '') THEN
select title into loc_title from term where NEW.id = id and lang = 'en_UK';
SET NEW.title= loc_title;
END IF;
END
This should do the trick.
This was my trigger def:
CREATE DEFINER = CURRENT_USER TRIGGER `therinks`.`glreturndata_BEFORE_UPDATE` BEFORE UPDATE ON `glreturndata` FOR EACH ROW
BEGIN
DECLARE myVal VARCHAR(20);
if NEW.DESCRIPTION IS NULL or new.description = '' THEN
SELECT min(description) into myVal from glreturndata where category = NEW.category and new.idglreturndata <> idglreturndata;
Set NEW.DESCRIPTION = myval;
end if;
END
It seems that you can't do all this in a trigger. According to the documentation:
Within a stored function or trigger, it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
According to this answer, it seems that you should:
create a stored procedure, that inserts into/Updates the target table, then updates the other row(s), all in a transaction.
With a stored proc you'll manually commit the changes (insert and update). I haven't done this in MySQL, but this post looks like a good example.

INSERT INTO if conditions are met

A user is only meant to have up to 3 keys registered to his account at any one time. To add a new key, the user must first delete another key to "make room" for a new one.
I want this to be checked server-side, but I can't get the query to work. Here is what I tried:
IF (SELECT COUNT(serial_key_nbr)
FROM keys_table WHERE user_id = 9) <= 2
THEN INSERT INTO keys_table (user_id, serial_key_nbr)
VALUES (9, 'abc123')
How to do this?
You can use the below mention Script for the same:
INSERT INTO keys_table (user_id, serial_key_nbr)
SELECT 9, 'abc123' FROM DUAL
WHERE
(SELECT COUNT(serial_key_nbr)
FROM keys_table WHERE user_id = 9)<=2
if you want to use an if to do a conditional select then I would put it in a variable like so.
BEGIN
DECLARE var1 INT;
SELECT COUNT(serial_key_nbr) INTO var1
FROM keys_table
WHERE user_id = 9;
IF var1 <= 2
THEN
INSERT INTO keys_table (user_id, serial_key_nbr)
VALUES (9, 'abc123')
END IF;
A trigger might be the way to go. If a condition is met, a trigger before inserting in the table can perform an invalid operation and cause the insert operation to fail:
delimiter $$
create trigger keep_three before insert on keys_table for each row
begin
if (select count(serial_key_nbr) from keys_table where user_id = new.user_id) >= 3 then
insert into non_existent_table (non_existent_field) values (new.user_id);
end if;
end$$
delimiter ;
Ugly, but it might work.
Reference:
"MySQL Triggers: How do you abort an INSERT, UPDATE or DELETE with a trigger?"
Another solution (better I think) is to forcibly delete an entry before attepting the insert. When there are less than 3 entries, the insert procedes normally:
delimiter $$
create trigger keep_three before insert on keys_table for each row
begin
while (select count(serial_key_nbr) from keys_table where user_id = new.user_id) >= 3 do
delete from keys_table where user_id = new.user_id
-- OPTIONAL: Add an ordering criteria to define which entry is deleted first
limit 1;
end while;
end$$
delimiter ;
I think this is cleaner.
A third way (I've found it here). It will return an error message (by signaling sqlstate 45000: Unhandled user defined exception) associated with the defined condition:
delimiter $$
create trigger keep_three before insert on keys table for each row
begin
declare msg varchar(255);
declare n int default 0;
set n = (select count(serial_key_nbr) from keys_table where user_id = new.user_id);
if n >= 3 then
set msg = "INSERT failed: There must be only three entries for each user. Delete an entry first";
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
end if;
end$$
delimiter ;
A cleaner version of my first option.