MySQL Trigger get current query that caused trigger to fire

后端 未结 3 1716
滥情空心
滥情空心 2021-01-22 19:30

I have scoured the web for the past 4 hours in search of a solution but all i can find is:

You cant. Impossible. Not gonna happen.

I dont like that approach.

相关标签:
3条回答
  • 2021-01-22 20:16

    We have investigated the issue and found that "DECLARE" doesn't work in the sample above, also the general_log flag should be enabled on the server. Finally we have the following trigger code:

    DELIMITER $$
    
    DROP TRIGGER IF EXISTS `our_trigger`$$
    CREATE TRIGGER `our_trigger` 
    BEFORE UPDATE ON `our_table_for_debug` 
    FOR EACH ROW BEGIN 
    
    SELECT argument INTO @tquery FROM mysql.general_log where thread_id = connection_id() and argument like 'update%' order by event_time desc limit 1;
    INSERT INTO `our_log_table` (`query`) VALUES (@tquery);
    
    END IF;
    
    END$$
    
    DELIMITER ;
    

    "our_log_table" is table with single mediumtext field named query. to enable general log you should run this query: general_log = 1; or enable it in mysql settings directly.

    0 讨论(0)
  • 2021-01-22 20:27
    SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ... ;
    
    0 讨论(0)
  • 2021-01-22 20:30

    The issue here is that the scope of MySQL triggers is row-level, not statement-level. As such, within the trigger you have access to the OLD and NEW values for each column in the given row, but you do not have access to the statement that caused the trigger to fire.

    In regard to information_schema.processlist, nothing is actually "stored" (persisted) in that view. It's just a SQL interface to the processlist, and the statement that caused the trigger to fire is not accessible within the scope of the trigger.

    You said you don't want to enable the general query log, and this approach isn't perfect for multiple reasons (including the granularity of event_Time being 1 second), but here's an example of how you could re-write your trigger using the general_log table:

    SET GLOBAL GENERAL_LOG='ON';
    SET GLOBAL LOG_OUTPUT='TABLE';
    
    DELIMITER || 
    
    CREATE TRIGGER DEBUG_DATE BEFORE UPDATE ON db.tbl FOR EACH ROW 
    BEGIN 
      DECLARE Q MEDIUMTEXT; 
      SELECT argument INTO Q 
      FROM mysql.general_log 
      where thread_id = connection_id() 
      order by event_time desc 
      limit 1;
    
      INSERT INTO db.tbl_log (INFO) 
      VALUES (Q); 
    
    END ||
    
    DELIMITER ;
    
    0 讨论(0)
提交回复
热议问题