Tracking database changes - mysql

Does anyone here can suggest a way to track database changes that were made through wordpress? For example I add a menu in wordpress, how can I keep track of this changes in database?
I use mysql
I tried searching and I only find toad and mysqldiff but still no luck. I also tried activating tracking for mysql but it only records changes that were made through phpmyadmin

You can create a trigger function in your mysql database. This function could copy the row before any UPDATE or INSERT statement into a separate table.
http://dev.mysql.com/doc/refman/5.7/en/create-trigger.html
BUT! Write a small IF check into your procedure so that you can disable it. Otherwise you will have a hard time when importing data through sql scripts during development.
A sample:
DROP TRIGGER IF EXISTS `backup`;
DELIMITER //
CREATE TRIGGER `backup`
BEFORE UPDATE
ON `sourceTable` FOR EACH ROW
BEGIN
IF #disableTriggers <> 1 THEN
INSERT INTO `backupTable` (col1,col2,col3) VALUES (OLD.col1,OLD.col2,OLD.col3)
END IF;
END;
//
DELIMITER ;

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//

Alter a where clause on a update through a trigger or similar

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

How to create a trigger for before/after delete with update/insert in mysql?

I have two tables like as:
fee_master(id,cTId,feeType,amount,startDate,lastDate,fine_last_date,fine,status)
payroll(id,emId,date,loan,netSalary)
I am trying to create a trigger like as:
DELIMITER $$
DROP TRIGGER IF EXISTS test
DELIMITER $$;
CREATE TRIGGER test
BEFORE DELETE ON fee_master
FOR EACH ROW
UPDATE payroll SET loan=OLD.amount,netSalary=OLD.fine WHERE id=18;
DELIMITER $$;
delete from fee_master where id='18';
When I have run this trigger, the data is deleted from fee_master, but payroll is not updated, also I have tried to insert payroll but not working.Every times the data is deleted from fee_master.
If I change the update and delete query position with trigger then It is ok. Actually, It is not working on trigger operation.
What is the problem ?
Your syntax for UPDATE is incorrect. Multiple assignments are separated by ,, not AND.
UPDATE payroll SET loan=OLD.amount, netSalary=OLD.fine WHERE id=18;
May be you are new on triggering.
According to your question, I recommend you first read basics of triggering from here http://www.sitepoint.com/how-to-create-mysql-triggers/
Remind that, It is a stored process. You do not need to run the trigger every times,I hope you are confuse here. After creating a trigger, You have to run the master query then the trigger automatically run the next operation.
Your code is ok. And the code of Barmar also ok.The main problem your understanding.

MySql triggers can't update same table

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 ;

MySQL Trigger converting

I have such SqLite trigger:
CREATE TRIGGER update_rating AFTER UPDATE ON gameServers
FOR EACH ROW BEGIN UPDATE gameServers
SET rated_order=NEW.rating || '#' || NEW._address
WHERE rowid=NEW.rowid; END;
Help me, please, with converting it into MySQL.
CREATE TRIGGER update_rating BEFORE UPDATE ON gameServers
FOR EACH ROW SET NEW.rated_order=CONCAT(NEW.rating,' # ',NEW.address);
OF COURSE - this does nothing ON INSERT...(!)
Note that I changed it from AFTER to BEFORE (quite deliberately): Apart from the question why I should start another UPDATE after the one triggering the trigger, there is the issue Updating table in trigger after update on the same table
Your (full) "UPDATE" statement in your AFTER trigger would cause a circular trigger-calling-trigger-calling-trigger... (which mysql would prevent by refusing the statement)
EDIT: At first I wanted to use the '||' too for string concatenation, but this is MySQL and not Oracle :)
It should work, I actually tested it on one of my own tables just to be sure. This trigger stuff is fickle at times :)