5

I'm thinking about using triggers as a logging mechanism in MySQL (v. 5.1) and therefore I'd like my trigger to get the query string in order to store it in another tabe.

I couldn't find anything like that in the MySQL documentation so I expect the answer to be no – but I still hope that I've overlooked something.

PS: this question is related to IcarusNM's answer to my question "Log MySQL DB changing queries and users"

1
  • That's a wild question, the likes of which I have never heard before. +1 for such outside-the-box thinking. Commented Nov 18, 2011 at 16:25

2 Answers 2

5

I have a working theory (LaForge would say to Capt Picard)...

Since you are using MySQL 5.1, you have access to the table INFORMATION_SCHEMA.PROCESSLIST.

You also have access to the ID of the current process the trigger is running on. The function to get that process ID is CONNECTION_ID.

You could try to fish out the query like this:

SELECT info FROM INFORMATION_SCHEMA.PROCESSLIST WHERE id = CONNECTION_ID();

Keep in mind that the info is LONGTEXT:

mysql> show create table information_schema.processlist\G
*************************** 1. row ***************************
       Table: PROCESSLIST
Create Table: CREATE TEMPORARY TABLE `PROCESSLIST` (
  `ID` bigint(4) NOT NULL DEFAULT '0',
  `USER` varchar(16) NOT NULL DEFAULT '',
  `HOST` varchar(64) NOT NULL DEFAULT '',
  `DB` varchar(64) DEFAULT NULL,
  `COMMAND` varchar(16) NOT NULL DEFAULT '',
  `TIME` int(7) NOT NULL DEFAULT '0',
  `STATE` varchar(64) DEFAULT NULL,
  `INFO` longtext
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

Within the trigger, you could use a local variable to hold the query

DECLARE original_query VARCHAR(1024);

and then capture the query

SELECT info INTO original_query FROM INFORMATION_SCHEMA.PROCESSLIST WHERE id = CONNECTION_ID();

Give it a Try !!!

If it works, then

Make it so (Capt Picard would quip back to LaForge)

7
  • Haha, a truly nice solution, wouldn't have thought about that. I couldn't fully test it yet (too small thread stack), but each of the parts work perfectly. Thank you! Commented Nov 18, 2011 at 17:29
  • It is very nice, though I am curious on the performance impact of a write-heavy table :) Commented Nov 18, 2011 at 21:42
  • I'll use an archive table, I hope that will limit the performace impact Commented Nov 18, 2011 at 22:53
  • 1
    I have tried this, but the query I always get is the "SELECT info INTO" query. The CONNECTION_ID() does change, but it looks like the current id is always that of the select? Should I try and save the CONNECTION_ID() earlier in the process? Commented Dec 8, 2011 at 9:53
  • 1
    Was having same problem, similar answer here that works for me: stackoverflow.com/questions/10628640/… Commented Aug 19, 2015 at 17:17
0
DROP TRIGGER IF EXISTS DEBUG_TIGGER;
CREATE TRIGGER DEBUG_TIGGER
AFTER UPDATE ON my_table 
FOR EACH ROW 
BEGIN
    INSERT INTO log_my_table(query)
    SELECT argument 
    FROM mysql.general_log 
    WHERE thread_id = connection_id()
    ORDER BY event_time DESC 
    LIMIT 5; /*gives last 5 queries(this will help you get idea of what logical path was taken)*/

    INSERT log_my_table
    (query)
    VALUES('-----------------');/*empty place holder*/
END
2
  • you can access the previous record using OLD.colName and you can use new updated record using NEW.colName Commented Nov 26, 2013 at 9:41
  • example "IF OLD.eventName <> NEW.eventName THEN /*log my query*/" Commented Nov 26, 2013 at 9:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.