我正在尝试通过 phpmyadmin
在数据库中执行此查询create trigger avoid_duplicated_sharing
before insert on sharingevents
for each row
begin
if ( select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0 ) then
delete from sharingevents where shared_note_id = NEW.shared_note AND shared_to = NEW.shared_to
END IF;
END
但是 phpmyadmin 给了我以下错误:
MySQL said: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'END IF' at line 7
两个问题:
BEFORE INSERT
触发后,是否会执行INSERT
操作?如果不是,我将不得不删除INSERT INTO SharingEvents (SELECT * FROM NEW);
答案 0 :(得分:0)
使用exists
:
if (exists (select 1 from sharingevents where shared_note_id = new.shared_note_id AND shared_to = new.shared_to) > 0) then
insert into sharingevents (shared_note_id,shared_to,permission_level)
values (NEW.shared_note_id,NEW.shared_to,NEW.permission_level);
end if;
或者,更好的是,在sharingevents(shared_note-id, shared_to)
上添加唯一索引,然后使用:
insert into sharingevents (shared_note_id, shared_to, permission_level)
values (NEW.shared_note_id, NEW.shared_to, NEW.permission_level)
on duplicate key update shared_note_id = values(shared_note_id);
这将忽略表中已存在对的任何更新。不需要if
。
答案 1 :(得分:0)
count(shared_note_id, shared_to)
语法无效。使用COUNT()
时,只能在count(DISTINCT ...)
内添加多个列名称。在您的情况下,您根本不需要放置列名,只需使用COUNT(*)
来计算与条件匹配的行数。
有关何时应将列名放在COUNT()
不幸的是,修复语法错误并不能真正解决您的问题,因为您无法使用触发器对同一个表进行更改。来自FAQ:
可以触发访问表吗?
触发器可以访问其自己的表中的旧数据和新数据。触发器也可以影响其他表,但不允许通过调用函数或触发器的语句修改已经使用(用于读取或写入)的表。
您需要重新编码调用者以使用INSERT ... ON DUPLICATE KEY UPDATE
或类似的东西来完成此操作。
答案 2 :(得分:0)
我用以下代码解决了这个问题:
delimiter $$
create trigger avoid_duplicated_sharing
before insert on sharingevents
for each row
begin
if ( select count(*) from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to > 0 ) then
delete from sharingevents where shared_note_id = NEW.shared_note_id AND shared_to = NEW.shared_to;
end if;
END$$
问题是分隔符。
即便如此,我的触发器也不起作用。当应用程序插入重复的主键时,MySQL会抛出以下错误:
#1442 - Can't update table 'sharingevents' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.