MYSQL Trigger problem -Very Easy - mysql

DELIMITER $$
CREATE TRIGGER stock_empty AFTER UPDATE on products
FOR EACH ROW
DELETE FROM products WHERE stock <=0;
END$$
I am trying to make my products table check itself after every UPDATE statement and delete rows that have 0 or negative stock counts. I could manage to get this far, but it is not working.
Thanks for any help

If it's that easy, how come you didn't solve it yourself?
DELIMITER ||
CREATE TRIGGER stock_empty AFTER UPDATE on products
FOR EACH ROW BEGIN
DELETE FROM products WHERE stock <=0;
END ||
[edit]
That's how correct syntax should look like, however there's one more thing:
A stored function or trigger cannot
modify a table that is already being
used (for reading or writing) by the
statement that invoked the function or
trigger.
From: http://dev.mysql.com/doc/refman/5.5/en/stored-program-restrictions.html

Related

How to create 'before insert' trigger that looks at multiple tables

I am struggling to understand the format to create an 'insert before' trigger that must meet conditions of other tables.
For example, if I have a table named 'borrowed' that I would like to insert values into but must meet conditions from another table called 'member'. The condition is that MemberStatus = 'regular'. If this condition passes, I will be able to run a 'insert into borrowed' but if the conditions aren't met then it will not be able to pass.
This is how I previously understood the concept but after hours of reading i've become confused. Any help would be appreciated.
delimiter //
drop trigger if exists trigger1
//
create trigger trigger1
before insert on borrowed
for each row
begin
if...
end if;
end;
//

MySQL select statement result in after delete trigger always null

I'm having a little issue with a trigger in a MySQL database. I have a DB with two tables: "tasks" and "files". The "tasks" table have a field which is a foreign key of the primary key from the "files" table. It also sometimes may be null.
What I'm trying to acomplish is to delete in the first place a row in the "tasks" table, and after that delete the corresponding row in the "files" table using a trigger.
This is the trigger I'm using right now:
DELIMITER //
CREATE TRIGGER after_delete_file AFTER DELETE ON tasks
FOR EACH ROW
BEGIN
DECLARE fileId int;
SELECT file INTO fileId FROM tasks WHERE id=old.id;
DELETE FROM files WHERE id=fileId;
END;//
DELIMITER ;
The field "file" in the "tasks" table is the one containing the foreign key. In the examples I've been running, that field has never been null.
The problem is that the select statement always returns null. The delete statement that triggers this trigger goes fine, but the row in the "files" table is never deleted. I've tried to insert the "fieldId" variable on a testing table, and it's always saving a null value.
Is there any problem on that trigger? Maybe I'm trying to do something merely impossible?
All the help is much appreciated :)
Since it should be looping over each deleted row, why would this not work?
DELIMITER //
CREATE TRIGGER after_delete_file AFTER DELETE ON tasks
FOR EACH ROW
BEGIN
DELETE FROM files WHERE id=old.file;
END;//
DELIMITER ;
If that doesn't work, could try this:
DELIMITER //
CREATE TRIGGER after_delete_file AFTER DELETE ON tasks
FOR EACH ROW
BEGIN
DELETE FROM files INNER JOIN tasks ON files.id=tasks.file WHERE tasks.id=old.id;
END;//
DELIMITER ;
but I don't think that should be necessary.
AFTER delete means that the data is deleted, of course you can't find it. Try creating the trigger for BEFORE delete.
You could also more carefully use all of the old values rather than selecting from the table that was deleted from.

MySQL Trigger with conditional statement and update another table

On MySQL 5.5, I am trying to write a trigger to do the following:
Checks a condition for the insert (is group_id between 8-20?)
If the condition is true, then update the user with the same user_id on another table, called phpbb_users.
The update on this other table is to set user_rank to NEW.group_id from the insert on the table that has the trigger.
Else, do nothing.
Not experienced at all, and stuck. It's not working when I run the query. Here is what I've got so far.
DELIMITER $$
CREATE OR REPLACE TRIGGER upd_rank AFTER INSERT ON `phpbb_user_group`
FOR EACH ROW BEGIN
IF (NEW.group_id BETWEEN 8 AND 20) THEN
UPDATE phpbb_users
SET user_rank=NEW.group_id
WHERE user_id=NEW.user_id;
ELSE
UPDATE phpbb_users
SET user_rank='0'
WHERE user_id=NEW.user_id;
END IF;
END$$;
DELIMITER;
(Note, the "else" clause is unnecessary really - happy for any suggestions for improvement of this code!)
if you only want to get rid of the else try
CREATE TRIGGER upd_rank AFTER INSERT ON `phpbb_user_group`
FOR EACH ROW
UPDATE phpbb_users
SET user_rank=IF(NEW.group_id BETWEEN 8 AND 20,NEW.group_id,"0")
WHERE user_id=NEW.user_id;

How to structure this IF condition in MySQL trigger

I am trying to write a MySQL trigger. I have two tables that look like this:
When a customer makes a purchase a new record is added to each table. I have added column ‘sku_copy’ to Table B, so it does not get populated when a new record is created.
When a new record is created, I want my trigger to copy the ‘sku’ field in Table A to the ‘sku_copy’ field in Table B. However, the problem I am having is how to structure the following condition in the trigger.
IF: ‘order_id’ in Table A matches ‘order_id’ in Table B. THEN: copy ‘sku’ from that Table A record to the record in Table B with the matching ‘order_id’. The data should be added to Table B ‘sku_copy'.
ELSE: don’t do anything.
Can someone show me how to write this into my trigger?
Thanks for any help you can give.
Try this but why do u think of using trigger for this ?
DELIMITER $$
CREATE TRIGGER trigger_name
AFTER INSERT ON tableA
FOR EACH ROW BEGIN
INSERT INTO tableB
SET sku_copy = OLD.sku,
order_id = OLD.order_id,
order = OLD.order;
END$$
DELIMITER ;
I want to post the trigger that was constructed with examples offered here and on another forum. Thanks to everyone who helped with this.
DELIMITER $$
CREATE TRIGGER sku_AfterInsert
AFTER INSERT ON uau3h_virtuemart_order_items
FOR EACH ROW BEGIN
UPDATE uau3h_virtuemart_orders
SET order_item_sku_copy = NEW.order_item_sku
WHERE virtuemart_order_id = NEW.virtuemart_order_id;
END$$;
DELIMITER ;

mySQL trigger cannot update table : already in use by the statement that invoked the trigger

so i've edited my code
i had this problem in another trigger but this time even changing WHERE clause doesn't help
DELIMITER $$
CREATE TRIGGER pic_album_change AFTER UPDATE ON pictures
FOR EACH ROW BEGIN
UPDATE albums SET counter = counter + 1 WHERE albums.id = NEW.album_id;
UPDATE albums SET counter = counter - 1 WHERE albums.id = OLD.album_id;
END $$
DELIMITER ;
error :
<p>Error Number: 1442</p><p>Can't update table 'pictures' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
i dont see any changes on the pictures table in this trigger
i have another trigger that involves these two tables
DELIMITER $$
CREATE TRIGGER album_change
AFTER UPDATE
ON albums
FOR EACH ROW
BEGIN
UPDATE pictures
SET
level = NEW.level
WHERE
pictures.album_id = NEW.id ;
END $$
DELIMITER ;
Your WHERE clause is the wrong way round.
WHERE albums.id = NEW.album_id
would cause albums.counter to be incremented (presumably that's the number of pictures in each album).
It matters because joins on tables are not commutative — the direction of the join is important. Here you need to find the record in albums to update based on the value of the row in pictures.
While in this case there isn't really any ambiguity, SQL needs to follow rules about joins.
The issue with your second trigger is that MySQL is preventing a continuous cycle of updates. You have a trigger pic_album_change which updates albums when pictures is updated. And you have a trigger album_change which updates pictures when albums is updated. Those triggers will trigger each other.
It seems to me that the database design may need to be changed. Do you really need albums.counter when that data can be found with SELECT count(*) FROM pictures WHERE album_id=...? It should be possible to normalise data so that there no circular references in triggers. In fact triggers may not be necessary at all.