MYSQL - Simple after insert trigger won't fire - mysql

Here I have the following trigger:
USE dbsspf;
DELIMITER $$
CREATE
DEFINER = 'root'#'localhost'
TRIGGER TR_ASSIGN_PAGEINDEX
AFTER INSERT
ON LIB_RECORDS
FOR EACH ROW
BEGIN
UPDATE LIB_RECORDS
SET
PAGE_INDEX = 13;
END
$$
DELIMITER ;
As you can see I'm just updating the table in my trigger. However when I insert a new record the trigger does not fire. Can you please show me what I've missed?

B.5.9: Can triggers access tables?
A trigger can access both old and new data in its own table. A trigger
can also affect other tables, but 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.
http://dev.mysql.com/doc/refman/5.5/en/faqs-triggers.html#qandaitem-B-5-1-9
In other words, a trigger on LIB_RECORDS cannot write other rows on LIB_RECORDS.

Related

How can I keep the DDL for my Trigger in Harmony with my Trigger code?

I'm trying to create a Trigger in Database Workbench (Lite, for MySQL) with this:
delimiter //
CREATE TRIGGER employeesTableInsert AFTER INSERT ON EMPLOYEES FOR EACH ROW
SET NEW.CREATED = CURRENT_TIMESTAMP; END IF;//
When I try to create the new Trigger, though, I get this err msg:
This seems odd; I look at the DDL tab in Database Workbench, and it has this:
Why is it doubling and mangling my Trigger code there in the (read-only) DDL?
As shown at the outset, my Trigger code only contains what is shown above:
So is the problem with my code, or is it because the DDL tab is confused? Or is my code CAUSING the DDL tab to become confused, or what?
If you want to update only the value you need following.
you can't use SET without a BEGIN and END, it is not a query.
I am wondering why there is a END IF in your code
Edit i also changed your TRIGGER to BEFORE INSERT, because on there you can change the values of a NEW column (see Bill Karwin comment)
And actually you don't need a trigger see manual
DELIMITER //
CREATE TRIGGER employeesTableInsert BEFORE INSERT ON EMPLOYEES
FOR EACH ROW
BEGIN
SET NEW.CREATED = CURRENT_TIMESTAMP;
END//

MySQL 5.0 can not drop and create trigger

I'm using MySQL 5.0. I try to drop and recreate the trigger.
When I drop the trigger it says:
mysql> drop trigger ads_delete;
ERROR 1360 (HY000): Trigger does not exist
Then I try to create the trigger with the same name. It says:
ERROR 1359 (HY000): Trigger already exists
Here is my trigger:
delimiter //
create TRIGGER ads_delete
BEFORE INSERT ON ads
FOR EACH ROW
BEGIN
update params set ads_count=ads_count-1, freq_weight=freq_weight-NEW.freq;
END//
You need to drop the trigger like this:
USE db5;
DROP TRIGGER ads_delete;
Your trigger is in the db5 schema.
EDIT:
As OP commented that the problem is
BEFORE INSERT ON ads
ie, he is trying to create two triggers with the same instruction. (Probably a copy paste issue)
I found the error. The reason was my inadvertence. I copy/pasted my INSERT trigger, when changed the trigger name from ads_insert into ads_delete, I forgot to change BEFORE INSERT ON ads into BEFORE DELETE ON ads
Thanks to everyone.

What is the right way to modify a MySQL trigger?

As you probably know, there's no syntax that modifies a MySQL trigger.
To do that, you need to execute DROP TRIGGER and then re-create it again with the new definition.
What is the right/best way of doing this, considering the following:
You cannot encapsulate these two statements in a transaction as that will be pointless (both DROP TRIGGER and CREATE TRIGGER invoke implicit transactions)
You cannot use LOCK TABLES READ as an error is triggered
Just between your DROP and CREATE TRIGGER, some other session might insert/update/delete row(s) which won't be handled by neither of your new nor old triggers.
When testing before I posted, I overlooked what type of LOCK I'm acquiring, it was READ.
So it seems using WRITE lock does the job:
delimiter $$
LOCK TABLES table1 WRITE $$
DROP TRIGGER IF EXISTS after_insert_on_table1 $$
CREATE TRIGGER after_insert_on_table1 AFTER INSERT ON table1
FOR EACH ROW
BEGIN
...
END
$$
UNLOCK TABLES $$
delimiter ;
So my recommendation is to always use this sequence when updating/modifying triggers.

Can I create a trigger in mysql schema in phpmyadming

When I ran the same query in different databases, it works successfully. But in mysql schem it gives error:
#trigger can not be created on system table
My query is:
delimiter //
CREATE TRIGGER `invite` AFTER INSERT ON `Invite_page`
FOR EACH ROW BEGIN
Insert into userpost(userid,url,title,preview,sentiment,time) values(NEW.userid,NEW.url,NEW.title,NEW.preview,NEW.sentiment,NEW.time);
Insert into urlcontent(userid,url,title,preview,sentiment,time) values(NEW.userid,NEW.url,NEW.title,NEW.preview,NEW.sentiment,NEW.time);
END
//
delimiter ;
If I can't, then how can I solve this instead?
UPDATE:
actual error:
#1465 - Triggers can not be created on system tables
Try this
DELIMITER $$
CREATE TRIGGER `invite` AFTER INSERT ON `Invite_page`
FOR EACH ROW
BEGIN
Insert into userpost(userid,url,title,preview,sentiment,time) values(NEW.userid,NEW.url,NEW.title,NEW.preview,NEW.sentiment,NEW.time);
Insert into urlcontent(userid,url,title,preview,sentiment,time) values(NEW.userid,NEW.url,NEW.title,NEW.preview,NEW.sentiment,NEW.time);
END$$
DELIMITER ;
Under the "Restrictions for triggers" section in http://dev.mysql.com/doc/refman/5.5/en/stored-program-restrictions.html you can read:
Triggers are not permitted on tables in the mysql database.
BTW, are you using the mysql schema to store data? This is (usually) a very bad idea and probably you need to rethink your setup.

MySQL Triggers to Disable A User Account

I am trying to create a MySQL Trigger to disable someone's account if they have logged in to the site 3 times. I have tried to create this trigger using the following code, but it is not setting is_active to 0 no matter what times_logged_in is. Any help would be appreciated.
CREATE TRIGGER updateTrigger AFTER UPDATE ON users
FOR EACH ROW
BEGIN
UPDATE users SET is_active=0 WHERE NEW.is_code=1
AND NEW.times_logged_in>=3
AND NEW.user_id=user_id;
END;
You've hit a limitation of MySQL. Your table users invokes the trigger (AFTER UPDATE ON users), therefore the triggered code cannot modify it. See the MySQL-Manual:
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.
I'm not sure where user_id comes from in your trigger, looks like an extraneous check, try this:
CREATE TRIGGER updateTrigger AFTER UPDATE ON users
FOR EACH ROW
BEGIN
UPDATE users SET is_active=0 WHERE NEW.is_code=1
AND NEW.times_logged_in>=3
END;
Also, be sure that is_code = 1 is actually matching on the users you're updating, if it's not, it won't update any rows.
I would use a BEFORE UPDATE trigger instead:
CREATE TRIGGER updateTrigger BEFORE UPDATE ON users
FOR EACH ROW
BEGIN
IF NEW.is_code=1 AND NEW.times_logged_in>=3 THEN
SET NEW.is_active=0;
END IF;
END;