MySQL触发器保持输入重复记录

时间:2015-04-11 16:41:06

标签: mysql stored-procedures triggers

我有一个包含以下列的表:

ID(primary key),
USER,
ACTION
TIME
LOCATION

我希望使用触发器或更新表时运行的东西,以确保根据USER,ACTION,TIME,LOCATION的分组没有重复的条目。我找到了一个关于如何清除现有条目的一个关键问题:

DELETE t1.*
        FROM
  testlogins t1 INNER JOIN testlogins t2
  ON t1.user=t2.user
     AND t1.action=t2.action
     AND t1.time=t2.time
     AND t2.location=t2.location
     AND t1.id>t2.id;

这有助于清除现有记录。我想我可能会基于此创建一个触发器,我想出了这个:

DELIMITER $$
create trigger del_duplicates
after insert
on test.testlogins for each row
begin
    DELETE t1.*
        FROM
  testlogins t1 INNER JOIN testlogins t2
  ON t1.user=t2.user
     AND t1.action=t2.action
     AND t1.time=t2.time
     AND t2.location=t2.location
     AND t1.id>t2.id;
end 
$$

然而,返回:

Error Code: 1442. Can't update table 'testlogins' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

我认为这是因为我要求系统在插入后执行删除操作。我还想知道在触发期间调用存储过程来实现这一点是否值得。

在这四列中保留匹配的重复行的最佳方法是:USER,ACTION,TIME,LOCATION

3 个答案:

答案 0 :(得分:0)

之前的答案是关于如何删除重复项,但如果您想防止重复发生,最好添加唯一索引:

CREATE UNIQUE INDEX idx_userlogins ON testlogins (USER, ACTION, TIME, LOCATION)

然后为了防止在插入重复行时引发错误,您可以使用以下语法:

INSERT INTO testlogins VALUES (value1, value2, value3, value4)
ON DUPLICATE KEY UPDATE user=user;

答案 1 :(得分:0)

CREATE UNIQUE INDEX body_idx ON testlogins (action, time, location);

这样可以防止现有的(action, time, location)重复。

答案 2 :(得分:0)

像其他人所说的那样,创建一个UNQUE INDEX(任何对每个用户都是唯一的字段,即userName)

REPLACE INTO testlogins (`USER`, `ACTION`, `TIME`, `LOCATION`) VALUES (val1, val2, val3, val4)

如果唯一索引匹配或插入,如果唯一索引没有匹配,则替换为一个很酷的函数将替换