MySQL Trigger获取导致触发器触发的当前查询

时间:2012-05-18 10:42:02

标签: mysql

我在过去的4个小时里搜索过网络以寻找解决方案,但我能找到的是:

你不能。 不可能。 不会发生。

我不喜欢这种做法。

我的理论是,如果它存储在information_schema.processlist中的某个点上,那么就有必要抓住它。 我试图在processlist表上运行一个触发器但是无法使它工作,我认为因为它是一个视图。 运行日志不是一个选项,因为这将影响已经拥挤的服务器上的性能,并且有许多查询正在运行,我只希望它登录特定的表,然后才更新..

这是传说中的stackoverflow!在哪里可以找到所有问题的解决方案,因为它充满了天才!

所以,我求求,天才们在哪里!显示你自己!! : - )

谢谢, 捷德

3 个答案:

答案 0 :(得分:1)

这里的问题是MySQL触发器的范围是行级,而不是语句级。因此,在触发器中,您可以访问给定行中每列的OLD和NEW值,但是您无权访问导致触发器触发的语句。

关于information_schema.processlist,该视图中实际上没有“存储”(持久化)任何内容。它只是进程列表的SQL接口,并且在触发器范围内无法访问导致触发器触发的语句。

你说你不想启用常规查询日志,这种方法并不完美,原因有多种(包括event_Time的粒度为1秒),但这里有一个如何重写你的例子的例子使用general_log表触发:

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 ;

答案 1 :(得分:0)

SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ... ;

答案 2 :(得分:0)

我们调查了这个问题并发现" DECLARE"在上面的示例中不起作用, 还应在服务器上启用 general_log 标志。最后我们有以下内容 触发代码:

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"是具有名为query的单个中间文本字段的表。 要启用常规日志,您应该运行此查询:general_log = 1;或启用它 在mysql设置中直接。