I need to write a trigger that will create a record in another table.
In my user table when a registering user responds to an activation email their status in that table changes from 0 to 1. When this change occurs I need it create a record in another table that has an auto-incrementing int primary id (Party).
Since the user status can be of three different states (not active (0), active (1), and banned (-1) I need this trigger to only set off when the status is changed from 0 to 1.
Can someone please help me with the SQL here?
DELIMITER $$
CREATE TRIGGER users_status_change AFTER UPDATE on users
FOR EACH ROW BEGIN
IF OLD.Status = 0 AND NEW.Status = 1 THEN
INSERT Party(Name)
VALUES('blar blar');
END IF;
END;
$$
DELIMITER ;
Related
Essentially I am trying to create a 'Retired' SQL table which will get its values from an already existing 'Staff' SQL table.
If the staff has more than 5 YearsOfService, then he/she will be added to the retired table.
I am sharing the code that I have tried.
CREATE TABLE Retired(
StaffID INT
);
DELIMITER #
CREATE TRIGGER RetiredTrigger after insert on Staff
FOR EACH ROW
BEGIN
INSERT INTO ALUMNI(StaffID) VALUES(new.StaffID);
IF Staff.YearsOfService > 5
END #
The result should ideally be a table(i.e. Retired Table) that should have StaffID's of only those teachers who have YearsOfService greater than 5.
I hope I was able to articulate my doubts clearly.
Thanks in advance.
CREATE TABLE Retired(
StaffID INT
);
DELIMITER #
CREATE TRIGGER RetiredTrigger after insert on Staff
FOR EACH ROW
BEGIN
IF (NEW.YearsOfService > 5) THEN
INSERT INTO Retired(StaffID) VALUES(new.StaffID);
END IF;
END #
DELIMITER ;
I am trying to create as following given:
Create a trigger on the Company table after an update that sets a
company's budget to 0 if it is less than 0.
But I struggle with errors such as being unable to update, set the table. I know it is because of I need to change from 'after update' to 'before update'. But I cannot dismiss the expected code. What could I do?
The mySQL code I have is:
delimiter $$
drop procedure if exists after_company_update $$
create trigger after_company_update after update on Company
for each row begin
update Company set budget = 0 where budget < 0;
end $$
delimiter ;
Error: ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG: Can't update table 'Company' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Such a trigger should logically be done before the update rather than afterwards:
delimiter $$
drop trigger if exists before_company_update $$
create trigger before_company_update after update on Company
for each row
begin
if old.budget < 0 then
set new.budget := 0
end if;
end $$
delimiter ;
You can express this as an after update trigger:
create trigger after_company_update after update on Company
for each row
update Company
set budget = 0
where Company.Id = new.Id;
The syntax works, but the trigger doesn't. It returns the error:
Can't update table 'Company' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
You can see this here.
You can't update the whole table which is already used by the trigger but you can update the column which is been modified.
Assuming your table has Primary Key which is company_id
Like
update Company
set budget = 0
where company_id=new.company_id and budget < 0;
'In an UPDATE trigger, you can use OLD.col_name to refer to the columns of a row before it is updated and NEW.col_name to refer to the columns of the row after it is updated' - https://dev.mysql.com/doc/refman/8.0/en/trigger-syntax.html
A before trigger would work but I'm not sure that it would be appropriate to have a trigger at all - do you really want to do this every time an update occurs to company (or only on specific occasions) , for example would it be appropriate if you changed address(assuming address is in the company table)
delimiter $$
drop trigger if exists after_company_update $$
create trigger after_company_update BEFORE update on Company
for each row begin
set NEW.budget = 0 where OLD.budget < 0;
end $$
DELIMITER ;
I have a table that has a status of either Approved, Rejected, or Pending. So I want to create a trigger that will populate the date_approved column on the table to current_timestamp when status is changed to approved. By default, status is pending.
What I've tried so far:
DELIMITER ;;
CREATE TRIGGER `date_approved_trig` ON CHANGE status = 'Approved' INSERT
ON `transaction` FOR EACH ROW
BEGIN
SET NEW.date_approved = NOW();
END;;
DELIMITER ;
I would really appreciate any help I could get
I am having a problem with a creation of a trigger.
So I have two tables: product(name,...) and detect(id,name_prod,quantity), and I wrote a code that whenever you insert a value in product, you would create a new row in detect for each id existent and initiate the value of quantity to zero:
DELIMITER $$
CREATE TRIGGER detect_default
AFTER INSERT ON product
FOR EACH ROW
BEGIN
IF NOT EXISTS (SELECT name_prod FROM detect WHERE new.name=name_prod) THEN
INSERT INTO detect(name_prod,quantity) VALUES(new.name,0);
END IF;
END$$
DELIMITER ;
The problem of this code is that only creates one row in detect with the name insert on product.name and quantity 0, but the id will be null.
How can I create a row for each existent ID?
I'm trying to create a trigger, however I keep getting back a syntax error.
Here's the statement:
DELIMITER $$
CREATE TRIGGER `swtalentbank`.`after_candidate_insert`
AFTER INSERT ON `Candidates` FOR EACH ROW
BEGIN
INSERT INTO useradmin (username, talent)
VALUES (NEW.email, 1);
UPDATE `Candidates` SET UserID = useradmin.userid where useradmin.username = NEW.email;
END
DELIMITER ;
I have a registration form on my site. When a person registers it populates the Candidates table with their profile information.
In the Candidates table, there are various fields, two of them being 'email' and 'UserID'.
UserID is also the PK in 'useradmin', so I'm linking the two up.
So when a user registers, I need to insert a record into 'useradmin' with the email address that's just been used to register, and then update the 'Candidates' table, with UserID that's just been created in 'useradmin'.
I hope this makes sense?
NB. I am changing the delimiter before running the statement.
Besides properly using DELIMITER when creating a trigger you have at least two fundamental issues with your current code:
In MySQL you can't use issue a DML statement (in your case UPDATE) against a table (candidates) on which you defined a trigger (also candidates). Your only option is to use BEFORE trigger and set a value of userid column of a row being inserted to a proper value.
You can't arbitrarily reference a column (useradmin.userid) of a table out of the context like you did in your UPDATE. You didn't joined useradmin table or used it in a subquery.
That being said and assuming that userid in useradmin table is an auto_increment column your trigger might look like this
DELIMITER $$
CREATE TRIGGER after_candidate_insert
BEFORE INSERT ON candidates
FOR EACH ROW
BEGIN
INSERT INTO useradmin (`username`, `talent`) VALUES (NEW.email, 1);
SET NEW.userid = LAST_INSERT_ID();
END$$
DELIMITER ;
Here is SQLFiddle demo
You should use semicolon after end your insert query.
You can use INSERT ... ON DUPLICATE KEY UPDATE syntax for your purpose
try out this...
DELIMITER $$
CREATE TRIGGER `swtalentbank`.`after_candidate_insert`
AFTER INSERT ON `Candidates` FOR EACH ROW
BEGIN
INSERT INTO useradmin (username, talent)
VALUES (NEW.email, 1);
UPDATE `Candidates` SET UserID = useradmin.userid where useradmin.username = NEW.email;
END $$
DELIMITER ;