pmc*_*try 3 mysql trigger insert
我试图用调用者的主机/IP 填充表中的某个列。我在表上有一个插入触发器,它像这样设置列:
CREATE TRIGGER access_insert_trg BEFORE INSERT ON access
FOR EACH ROW
set NEW.hostname = (select SUBSTRING_INDEX(host,':',1)
from information_schema.processlist
WHERE ID=connection_id())
;
Run Code Online (Sandbox Code Playgroud)
%
尽管当我在processlist
表上手动运行相同的查询时,我得到了实际的主机名,但我最终还是得到了主机名。我已经检查了该connection_id()
值,它是在主机列中processlist
具有实际hostname:port
值的行的 id 正确。
我无法弄清楚它是如何或为什么被转换为通用%:<port>
值的。关于发生了什么以及如何解决它的任何想法?
如果有任何改变,我正在使用 MySQL 5.1.57。
您是否正在执行从存储过程内部触发触发器的插入操作?
显然,当在存储过程中时,如果调用用户与定义者不同,则在 information_schema.processlist 中匹配您的线程的行将填充(尽管有点半心半意)DEFINER 用户名和主机名。
这有点出乎意料,所以我会在下面记录更多...
但首先,你的修复:
SET NEW.hostname = SUBSTRING_INDEX(user(),'@',-1);
Run Code Online (Sandbox Code Playgroud)
如果这行得通,那绝对是一种更好的方法——它是一种更轻量级的方式来获取您正在寻找的信息,并且似乎返回正确的答案,而另一个则没有。调用 information_schema.processlist 的开销很大,因为显然每次调用它时都会呈现整个表。
现在,为了那些(包括我在内)在没有看到它的实际行动的情况下不会相信它的人(包括我在内)的利益而复制该行为:
DELIMITER $$
DROP PROCEDURE IF EXISTS `bizarre` $$
CREATE DEFINER=`super_dev`@`%` PROCEDURE `bizarre`()
BEGIN
SELECT * FROM information_schema.processlist WHERE Id = CONNECTION_ID();
END $$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)
现在来测试SP。请注意,我不是以 super_dev 身份连接,而是以其他超级用户身份连接。如果我以 super_dev(DEFINER 用户)身份连接,这将按我们预期的方式工作。
mysql> call bizarre();
+-------+---------------+---------+------------+---------+------+-----------+-------------------------------------------------------------------------+
| ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO |
+-------+---------------+---------+------------+---------+------+-----------+-------------------------------------------------------------------------+
| 17261 | super_dev | %:49730 | dev_testsv | Query | 0 | executing | SELECT * FROM information_schema.processlist WHERE Id = CONNECTION_ID() |
+-------+---------------+---------+------------+---------+------+-----------+-------------------------------------------------------------------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
我最好的猜测是,这是调用存储过程时需要在内部发生的环境更改的工件。
归档时间: |
|
查看次数: |
2452 次 |
最近记录: |