I have created a trigger to delete a row from orders when the user_id and restaurant_id are set to null.
delimiter //
create trigger order_delete
before update on orders
for each row
if new.user_id is null and new.restaurant_id is null then
delete from orders where order_id = new.order_id;
end if;
//
delimiter ;
user_id and restaurant_id are foreign keys from two other tables and will be set to null when they are deleted from their respective tables. However, when I tried deleting them from their tables it does not execute the trigger. So I still have an order with two user_id = NULL and restaurant_id = NULLremaining in my orders table. Does anyone know why my trigger is not triggering?
As MySQL documentation on foreign keys says:
Cascaded foreign key actions do not activate triggers
Therefore, no mtter what trigger you create, it is not going to be called when a value is set to null via cascade.
If you only want to delete a record if both fields are set to null, then you have to perform this action from the application code, you cannot rely on database automation.
Just a side note: you should not delete orders from your system, since they are the basis of your financial transactions and you can get into trouble with the tax authorities and the external financial auditors for doing that.
You want that trigger to be fired when user_id and restaurant_id are set to NULL?
In that case, you should use:
delimiter //
create trigger order_delete
after update on orders
for each row
if new.user_id is null and new.restaurant_id is null then
delete from orders where order_id = new.order_id;
end if;
//
delimiter ;
Using the keyword after instead of before means the trigger will be fired after the fields are set to null. Using before, the trigger will be fired when user_id and restaurant_id still have their previous values. In that case, the condition in the if statement is never true.
Related
I have the date type column valid_upto in the users table which is a foreign key referring to the valid_upto column in the subscription table. I need users.valid_upto to update when a change is made to subscription.valid_upto where the corresponding user ID values match. Currently the trigger updates all rows in the users table when a single row is changed in the subscription table. It basically ignores the WHERE clause.
DROP TRIGGER IF EXISTS `valid_date` ;
CREATE DEFINER = `root`#`localhost` TRIGGER `valid_date` AFTER UPDATE ON `users`
FOR EACH ROW
BEGIN
UPDATE valid_upto SET users.valid_upto = subscription.valid_upto WHERE users.id = subscription.user_id;
END ;
I'd like to create a before delete trigger that deletes rows from two different tables. But I can't figure out which parameters to use.
I got a house table, and when I delete a row, I'd like to delete every row in my two other tables: user_house and firm_house, which contains same house id as the one triggering the event.
What does FOR EACH ROW mean? And how can I properly set my trigger up?
USE `mydb`;
DELIMITER $$
CREATE TRIGGER `deleteUnions` BEFORE DELETE ON `house`
FOR EACH ROW
BEGIN
DELETE FROM user_house WHERE ?? = ??;
DELETE FROM firm_house WHERE ?? = ??;
END
Some details about the structure:
user_house is joined by user_id and house_id;
firm_houise is joined by firm_id and house_id.
Refer to the record that gets deleted in the trigger with OLD. Then use the id to delete from the other tables.
DELETE FROM user_house WHERE house_id = OLD.house_id;
DELETE FROM firm_house WHERE house_id = OLD.house_id;
I have two tables:
oee_main
oee_client
I already have an after insert trigger on oee_main as follows:
CREATE TRIGGER `oee_upd` AFTER INSERT ON `oee_main`
FOR EACH ROW UPDATE oee_client
SET END_DATE= NOW() where END_DATE IS NULL
I now need to develop the trigger even more so that the newly inserted row in oee_main will not only update the END_DATE of oee_client to NOW() where END_DATE is NULL but to only update the row(s) of oee_client where the column called Machine_ID is equal to the newly inserted column named NAME in oee_main.
I have tried adding this to the where condition of the above trigger to no success:
where END_DATE IS NULL and Machine_ID = new.`oee_main`.`NAME`
Therefore what I am after is that when a new record is inserted in oee_main which has a value of for example '2' in column 'NAME' the trigger updates only the columns END_DATE of oee_client where NULL and where Machine_ID of oee_client is equal to the newly inserted value of NAME in oee_main.
Thanks
I think this is the logic you want:
DELIMITER $$
CREATE TRIGGER `oee_upd` AFTER INSERT ON `oee_main`
FOR EACH ROW
BEGIN
UPDATE oee_client c
SET c.END_DATE = NOW()
WHERE c.END_DATE IS NULL AND c.Machine_ID = new.NAME;
END$$
DELIMITER ;
Remember to use the delimiter statement whenever you define triggers, stored procedures and functions. It will help prevent errors in the future.
As for your error, you don't need to mention the table name when you use NEW.
As an outsider, I find it confusing that NAME in one table matches MACHINE_ID in another table. I would expect both tables to have a column called MACHINE_ID.
I have this reservation table that has RESERVATION_ID , ROOM_NUM, Date_Start , Date_End and cost columns. what I want to do is insert all the columns except cost and fill the cost automatically.
delimiter //
CREATE TRIGGER upd_check before INSERT ON reservation
FOR EACH ROW
BEGIN
IF NEW.RESERVATION_COST = NULL THEN
SET NEW.RESERVATION_COST = 'timestampdiff(day, NEW.RESERVATION_STARTD, NEW.RESERVATION_ENDD)*70';
END IF;
END;//
delimiter ;
I wrote this trigger to do it, but whenever I press Apply to insert everything nothing is inserted to the RESERVATION_COST column.
why?
I would put this in a comment if I had enough reputation, but anyways. Triggers cannot act on the same table which activated them. Seems limiting, but we've had the same issue.
This link doesn't explicitly say this but it does say "in the associated table". Not the same: https://dev.mysql.com/doc/refman/5.0/en/triggers.html
You can't compare a value to NULL, you need to check if it IS NULL instead.
e.g.
IF NEW.RESERVATION_COST IS NULL THEN
I have to Write one or more triggers that keep track of how many total records have been in the sakila_film table in a single variable, but I am having trouble figuring out how to do this trigger the table is taken from http://dev.mysql.com/doc/sakila/en/sakila-structure-tables-film.html .This is what I have tried the code below but I am getting an error and I don't know any other way i could do it.
create trigger records after Update on sakila_film Count(*) from sakila_film;
Where are you planning on storing this count of total rows in the film table?
If you are going to manage this with triggers, it seems like you'd need two triggers. One for INSERT, one for DELETE. An UPDATE statement won't change the number of rows in the table. (Note that triggers are NOT fired for foreign key actions; which is a concern if there's a foreign defined with a DELETE rule.) And the triggers will not be fired for a TRUNCATE statement.
Setting aside those concerns, we'd need somewhere to store the rowcount over time. As an example:
CREATE TABLE rowcount_history_film
( ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
, rowcount INT NOT NULL
, KEY rowcount_history_film_IX1 (ts)
) Engine=MyISAM;
And then we could use trigger to insert a row into that table whenever a DML statement changes the number of rows in the film table:
DELIMITER $$
CREATE TRIGGER film_ad
AFTER DELETE ON film
FOR EACH ROW
BEGIN
INSERT INTO rowcount_history_film (ts, rowcount)
SELECT NOW(), COUNT(*) FROM film;
END$$
CREATE TRIGGER film_ai
AFTER INSERT ON film
FOR EACH ROW
BEGIN
INSERT INTO rowcount_history_film (ts, rowcount)
SELECT NOW(), COUNT(*) FROM film;
END$$
DELIMITER ;