这是我的表:
Id Password Status
1 a6cc890.. 1
我在密码上有一个触发器,用于加密字段。
触发器如下:
-- Trigger DDL Statements
DELIMITER $$
USE `ediftpdb`$$
CREATE
DEFINER=`edidbo`@`%`
TRIGGER `ediftpdb`.`trigger_format_passwd`
BEFORE INSERT ON `ediftpdb`.`users`
FOR EACH ROW
SET NEW.passwd=md5(NEW.passwd)$$
CREATE
DEFINER=`edidbo`@`%`
TRIGGER `ediftpdb`.`trigger_format_passwd_update`
BEFORE UPDATE ON `ediftpdb`.`users`
FOR EACH ROW
SET NEW.passwd=md5(NEW.passwd)$$
令我惊讶的是,当我更新状态时会触发触发器,并且密码再次加密!
我该怎么做才能解决这个问题?
答案 0 :(得分:1)
如果更新Status
,则表示您正在进行更新,并且所有UPDATE触发器都将触发。您需要做的就是比较passwd
的新旧值,只有在它们不同时才应用您的MD5。幸运的是,MySQL提供OLD
and NEW
row aliases:
您可以使用别名
OLD
和NEW
来引用主题表(与触发器关联的表)中的列。OLD.col_name
在更新或删除之前引用现有行的列。NEW.col_name
指的是要插入的新行的列或更新后的现有行。尝试使用IF
:
BEFORE UPDATE ON `ediftpdb`.`users`
FOR EACH ROW
SET NEW.passwd = IF(NEW.passwd = OLD.passwd, NEW.passwd, md5(NEW.passwd))
除非NEW.passwd
(新密码)和NEW.passwd
(数据库中已有的哈希密码)不同,否则不应更改OLD.passwd
。当然,如果有人设法输入旧密码的MD5作为新密码,这可能会失败,但这种情况不太可能。
答案 1 :(得分:0)
当您“更新Status
”时,您实际上是在整个表格上执行UPDATE
。你只修改一个字段的值的事实不会进入它!
您可以使用the NEW
and OLD
identifiers手动检查passwd
的值是否已更改。