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.
Related
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//
I'm currently building a replication database (for reporting from) for an already existing database and we are wanting to obfuscate/hash certain columns. Both are on AWS RDS platform with the replication set up as a 'read replica' of the source.
One of the issues with using RDS Replication I've found is you cannot specify which columns to ignore (given that RDS read replicas are supposed to be 1:1 this isn't surprising and I fully understand I'm doing something very niche)
The solution to this problem was to set up triggers on updates/inserts to alter these values, like so:
DELIMITER $$
CREATE TRIGGER clients_insert_obfuscate
BEFORE INSERT ON clients
FOR EACH ROW
BEGIN
SET NEW.access_token = NULL, NEW.user_token_ttl = 0;
END$$
DELIMITER ;
However one of the values we want to alter is a primary key (the PKs on this table are used as coupon code redemption numbers).
Which leads me to my question - is there anyway of altering the where clause in a update before its executed from within mysql? So on the replica databse, instead of matching against the unhashed code its matching against the hashed code?
So far I have this:
DELIMITER $$
CREATE TRIGGER insert_obfuscate
BEFORE INSERT ON codes
FOR EACH ROW
BEGIN
SET NEW.code = SHA2(NEW.code, 256);
END$$
DELIMITER ;
DELIMITER $$
CREATE TRIGGER update_obfuscate
BEFORE UPDATE ON codes
FOR EACH ROW
BEGIN
SET NEW.code = SHA2(NEW.code, 256);
END$$
DELIMITER ;
So the insert is fine - but the update trigger is only looking at the params to update - not the where clause.
I understand a trigger might not be the right route to take on this but I'm struggling to find anything else.
Is there anyway of doing this or do I need to look at changing the schema? I would prefer not to change the schema on a production DB though.
Thanks
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.
Problem is that, I want a trigger that deletes old rows in the same table that the new rows are being inserted into.
MsSQL and oracle can do this,
but looks like mySQL can't,
It allows the trigger to be created, but when it runs it gives the error
"can't update table "tbl" in stored procedure or function/trigger
because it is already used by statemtent whicgh invoked this stored
procedure or function/trigger"
Any work around for this?
Is it planned in future releases?
I have in my database all tables with filed name GHOST, so when GHOST is TRUE this row is like DELETED. So if You want change row after insert maybe use like this:
CREATE TRIGGER my_trigg
BEFORE INSERT ON table
FOR EACH ROW
BEGIN
SET NEW.ghost = TRUE;
END
$$
DELIMITER ;
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.