TRIGGER with conditional IF statement - mysql

Drop TRIGGER if exists triggername;
DELIMITER $$
CREATE TRIGGER triggername
AFTER UPDATE ON table1 FOR EACH ROW
BEGIN
IF (
Select person from table1 e
JOIN table1Type et ON e.table1TypeID = et.table1TypeID
where et.Description = 'University Degree' and e.Active = 1)
THEN update table2
set field = 1 ;
ELSE update table2 set field = 0;
END IF;
END$$
DELIMITER ;
I am trying to use a conditional statement to update another table if that condition is met.
So in other words, if the person in table 1 has a type of university degree and is active then update another field in table 2.

CREATE TRIGGER triggername
AFTER UPDATE
ON table1
FOR EACH ROW
UPDATE table2
SET field = EXISTS (SELECT NULL
FROM table1 e
JOIN table1Type et USING (table1TypeID)
WHERE et.Description = 'University Degree'
AND e.Active = 1);
Maybe you must use NOT EXISTS (the logic is unclear).
PS. DELIMITER not needed for this trigger code.

Related

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

I have the following problem with mysql:
I have the table A with a trigger that update a columns of table B when something in A change. This trigger works.
I need te possibility to update a column of A when something in B change, but the second trigger generate the error.
I know is recursive, but how can I do it?
exp.
trigger A:
delimiter $$
CREATE TRIGGER TAU_A
AFTER UPDATE ON table_A FOR EACH ROW
begin
IF OLD.to_read <> NEW.to_read THEN
update table_B
set is_read=if(new.to_read=1,0,1)
where id=new.id;
END IF;
END$$
trigger B:
delimiter $$
CREATE TRIGGER TAU_B
AFTER UPDATE ON table_b FOR EACH ROW
begin
IF OLD.is_read <> NEW.is_readTHEN
update table_a
set to_read=if(new.is_read=1,0,1)
where id=new.id;
END IF;
END$$
Use user-defined variable, check for chaining update.
DEMO
#check_for_cycle user-defined variable is used for to prevent a cycle. The variable name must be unique over a system (i.e. it must be used in this triggers pack only) and provide interference absence (including another applications which may modify these tables data).
CREATE TABLE t1 (id INT PRIMARY KEY, val INT);
CREATE TABLE t2 (id INT PRIMARY KEY, val INT);
INSERT INTO t1 VALUES (1,1), (2,2);
INSERT INTO t2 VALUES (1,1), (3,3);
SELECT * FROM t1;
SELECT * FROM t2;
id
val
1
1
2
2
id
val
1
1
3
3
CREATE TRIGGER tr_au_t1
AFTER UPDATE ON t1
FOR EACH ROW
BEGIN
IF #check_for_cycle IS NULL THEN
SET #check_for_cycle := 1;
UPDATE t2 SET val = NEW.val + 10 WHERE id = NEW.id;
SET #check_for_cycle := NULL;
END IF;
END
CREATE TRIGGER tr_au_t2
AFTER UPDATE ON t2
FOR EACH ROW
BEGIN
IF #check_for_cycle IS NULL THEN
SET #check_for_cycle := 1;
UPDATE t1 SET val = NEW.val + 100 WHERE id = NEW.id;
SET #check_for_cycle := NULL;
END IF;
END
UPDATE t1 SET val = val + 1;
SELECT * FROM t1;
SELECT * FROM t2;
id
val
1
2
2
3
id
val
1
12
3
3
UPDATE t2 SET val = val + 2;
SELECT * FROM t1;
SELECT * FROM t2;
id
val
1
114
2
3
id
val
1
14
3
5
fiddle
You must check that no error occures in a trigger, and clear the variable in the error handler. Otherwise, when INSERT fails then the trigger breaks and the whole process rollbacks, but the variable value will stay non-cleared (variable assignment is not rollbacked) which will lock trigger action for further updates.

MySql trigger with where clause

This is my first trigger in MySql and I am having a few problems. I tried both of these pieces of code but both would not compile. I got it to work without the where clause.
CREATE TRIGGER ins_meal_details
AFTER INSERT ON meal_details
FOR EACH ROW
INSERT INTO sql_changes
SET
sc_table='book_room',
sc_reason='DINNER1',
sc_key='bh_no=NEW.bh_no,date=NEW.md_date',
sc_value='1',
sc_done =0
WHERE not exists (select 1 from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1)
CREATE TRIGGER ins_meal_details AFTER INSERT meal_details FOR EACH ROW
BEGIN
IF NOT EXISTS (select 1 from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1) THEN
INSERT INTO sql_changes (sc_table, sc_reason, sc_key, sc_value, sc_done )
VALUES ('book_room','DINNER1', 'bh_no=NEW.bh_no,date=NEW.md_date','1', 0);
END IF
END
CREATE TRIGGER ins_meal_details
AFTER INSERT
ON meal_details
FOR EACH ROW
INSERT INTO sql_changes (sc_table,
sc_reason,
sc_key,
sc_value,
sc_done)
SELECT 'book_room',
'DINNER1',
CONCAT('bh_no=',NEW.bh_no,',date=',NEW.md_date),
1,
0
WHERE NOT EXISTS (SELECT 1
FROM booking
WHERE bh_no = NEW.bh_no
AND bo_date = NEW.md_date
AND bo_meals < 1);
MySql did not like the select/where exists in my code when there is no table specified. This was due to using version 5.6 of MySql server.
This will not work: select 'works' where exists (select 1 from my-table)
The fix would be thanks to #akina to add from DUAL. The best solution.
I got round it by using a count(*) instead :-
DROP TRIGGER IF EXISTS ins_meal_details;
DELIMITER //
CREATE TRIGGER ins_meal_details
AFTER INSERT ON meal_details FOR EACH ROW
BEGIN
IF (select count(*) from booking where bh_no = NEW.bh_no and bo_date = NEW.md_date and bo_meals < 1) > 0 THEN
INSERT INTO sql_changes (sc_table,
sc_reason,
sc_key,
sc_value,
sc_done)
VALUES ('book_room','DINNER1', CONCAT('bh_no=',NEW.bh_no,',date=',NEW.md_date),'New Value', 0);
END IF;
END//
DELIMITER ;

After Insert trigger on table1 with Update IF condition on table2

I want to create trigger 'after insert' on table1
If i insert record in Table1
it will check corresponding ID in table2 and update the status of
corresponding ID in table2.
there is additional condition on table2.
status of that ID should be Null.
my attempt so far.
but its not working
CREATE TRIGGER 'table1_AFTER_INSERT` AFTER INSERT ON `table1` FOR EACH ROW
BEGIN
update table2 a
set a.status= 'coordination pass',
where a.ID = new.ID and a.status is Null;
END
You have many sintax errors like comma after set a.status= 'coordination pass', or in trigger name definition etc. Here is the correct triger sintax
CREATE TRIGGER `table1_AFTER_INSERT` AFTER INSERT ON `table1`
FOR EACH ROW BEGIN
UPDATE `table2` a
SET a.status= 'coordination pass'
WHERE a.ID = NEW.ID AND a.status is NULL;
END
As i seen your trigger there is two error first is with table name you use ' single quote and second is set a.status= 'coordination pass', comma at last
CREATE TRIGGER table1_AFTER_INSERT
AFTER INSERT ON table1`
FOR EACH ROW
BEGIN
UPDATE table2 a
SET a.status= 'coordination pass'
WHERE a.ID = new.ID AND a.status is Null;
END;

Trigger conditional

I would like to make a SQL Trigger that will evaluate a query like this:
IF NOT (SELECT * FROM table1 WHERE table1.id=1 AND table1.finished=0)
DO
UPDATE table2 SET finished=1 WHERE table2.id=table1.id
That would tell me that all rows from table1 with an id of 1 are finished (if there are no unfinished(0) rows) and, if so, it should update table2 and set the value finished to 1.
Can anyone help me with the Trigger structure? I'm new when it comes to that.
You can do it this way
DELIMITER //
CREATE TRIGGER tg_au_table1
AFTER UPDATE ON table1
FOR EACH ROW
BEGIN
IF NOT OLD.finished <=> NEW.finished THEN
UPDATE table2 t
SET finished = (EXISTS(SELECT *
FROM table1
WHERE id = t.id
AND finished = 0))
WHERE id = NEW.id;
END IF;
END//
DELIMITER ;
Here is SQLFiddle demo
Extended answer is provided in your other question https://stackoverflow.com/a/21270582/1920232

PostgreSQL trigger updating secondary related table

I have two tables: table1 and table2, which triggers on inserts and on updates in the same function.
As you insert a value in table1 or table2 a value is inserted in table3, with the value table1.lastname || table1.firstname assigned to column3. The id obtained for the insert in table3 must be inserted into table1.id_table3.
CREATE OR REPLACE FUNCTION myschema.myfunction() RETURNS trigger AS
$BODY$
DECLARE
new_id_table_4 integer;
BEGIN
IF TG_OP = 'INSERT' THEN
IF TG_TABLE_NAME = 'table1' THEN
new_id_table_4 := 1;
ELSIF TG_TABLE_NAME = 'table2' THEN
new_id_table_4 := 2;
END IF;
INSERT INTO myschema.table3
(id, id_table4, name)
VALUES (DEFAULT, new_id_table_4, NEW.columnA||', '||NEW.columnB, TRUE, TRUE)
RETURNING id
INTO NEW.id_table3;
ELSIF TG_OP = 'UPDATE' THEN
IF OLD.columnA <> NEW.columnA OR OLD.columnB <> NEW.columnB THEN
UPDATE myschema.table3 SET
name = NEW.columnA||', '||NEW.columnB
WHERE id = NEW.id_cuenta;
END IF;
END IF;
RETURN NEW;
END
$BODY$
LANGUAGE plpgsql VOLATILE COST 100;
ALTER FUNCTION myschema.myfunction() OWNER TO myuser;
CREATE TRIGGER add_table3record_table1
AFTER INSERT OR UPDATE
ON myschema.table1
FOR EACH ROW
EXECUTE PROCEDURE myschema.myfunction();
CREATE TRIGGER add_table3record_table2
AFTER INSERT OR UPDATE
ON myschema.table2
FOR EACH ROW
EXECUTE PROCEDURE myschema.myfunction();
The problem is that when I insert a new record into table1 or table2,
...RETURNING id INTO NEW.id_table3;
It does not seem to have any effect.
This is my first function/trigger ever, and I cannot find the error.
Thank you!
I'm pretty sure you can't update a row AFTER it has already been inserted just by setting NEW.foo = bar.
Either:
Perform an update on the table1 setting the new id_table3 value (which is going to recursively call you ON UPDATE trigger, so be careful), or
Use a BEFORE trigger instead of an AFTER.
Depending on how your foreign keys are set up between table1 and table3, the latter may or may not be an option.