我可以通过存储过程来显示这一点。这个概念是从 wchiquito 的这个答案中提出的。我相信您会发现这是一个更详尽的答案。这只是一个例子。根据您的特定需求(其他触发器类型)等进行必要的更改。如何在不使用存储过程之外执行 mysql 触发器信号触发是任何人的猜测。因此,如果您不愿意或无法执行存储过程,请不要继续阅读。
请注意,为了您的方便,任何删除或截断都会被保留并重新删除。
create database trigTranTest; -- creates a separate database for testing
use trigTranTest; -- use that database
-- drop table tableA;
create table tableA
( id int auto_increment primary key,
something varchar(100) not null,
age int not null, -- do not accept unlucky 13
myDT datetime not null
);
-- drop table tableB;
create table tableB
( -- simply to demonstrate multiple tables in a transaction and that they are honored as a group (ie: Transaction)
-- all or nothing basically
id int auto_increment primary key,
something varchar(100) not null,
myDT datetime not null
);
-- drop table auditInfoNotInTrans;
create table auditInfoNotInTrans
( -- a boring table outside of Transaction to show an attempt was made
id int auto_increment primary key,
debugInfo varchar(100) not null,
myDT datetime not null
);
Run Code Online (Sandbox Code Playgroud)
-- POINT A
drop trigger if exists tableA_BeforeIns;
DELIMITER $$
create trigger tableA_BeforeIns before insert on tableA
for each row
begin
if new.age = 13 then
-- disallow unlucky age=13 for inserts. Wait another year.
signal sqlstate '45000' set message_text = "tableA_BeforeIns bombed due to age=13";
end if;
end$$
DELIMITER ;
-- POINT B
Run Code Online (Sandbox Code Playgroud)
关于触发器的快速说明:如果您尝试插入age=13,则会设置信号。这将启动ROLLBACK交易的最终阶段。
请注意,分隔符很重要。要修改上述内容,请突出显示POINT A和之间的所有文本POINT B并执行它。该块将使用 DELIMITER 后面需要的那种痛苦来执行删除和娱乐。如果没有 DELIMITER,错误 1064即将出现。翻译:这不会起作用。什么不行?首先创建触发器的部分。
-- POINT A
drop procedure if exists insertChunk;
DELIMITER $$
CREATE PROCEDURE insertChunk(pSomething varchar(100), pAge int)
-- takes two parameters, a string for a thing, and an age
BEGIN
-- idea lifted from /sf/answers/1393573821/ by user wchiquito
-- so spread the appreciation there
DECLARE `_rollback` BOOL DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET `_rollback` = 1;
-- the following happens outside of the Transaction
insert auditInfoNotInTrans(debugInfo,myDT) values(pSomething,now());
-- now our Transaction part begins
START TRANSACTION;
insert tableA(something,age,myDT) values (pSomething,pAge,now()); -- pAge being unlucky 13 fails via the Trigger
IF `_rollback` THEN
ROLLBACK;
ELSE
insert tableB(something,myDT) values (pSomething,now());
COMMIT;
END IF;
END$$
DELIMITER ;
-- POINT B
Run Code Online (Sandbox Code Playgroud)
这里快速说明一下:一旦START TRANSACTION发生,我们就会进入,COMMIT除非我们的触发器发出 SQLSTATE 信号,从而导致ROLLBACK.
如前所述,突出显示并执行 和 中的所有代码,POINT A以POINT B对上述内容进行编辑。这次是存储过程,但与create trigger之前类似。
意思是,类似于使用 DELIMITER 块的安全包装来触发修改。否则,将出现错误 1064,并且将不会创建存储过程。
请注意,为了测试期间的方便,此处保留了以下重新删除的截断内容。
-- truncate tableA;
-- truncate tableB;
-- truncate auditInfoNotInTrans;
call insertChunk('frog',1);
call insertChunk('lizard',13); -- force a Trigger failure with the unlucky 13
call insertChunk('snake',2);
Run Code Online (Sandbox Code Playgroud)
select * from auditInfoNotInTrans;
+----+-----------+---------------------+
| id | debugInfo | myDT |
+----+-----------+---------------------+
| 1 | frog | 2016-06-10 15:09:02 |
| 2 | lizard | 2016-06-10 15:09:06 |
| 3 | snake | 2016-06-10 15:09:08 |
+----+-----------+---------------------+
select * from tableA;
+----+-----------+-----+---------------------+
| id | something | age | myDT |
+----+-----------+-----+---------------------+
| 1 | frog | 1 | 2016-06-10 15:09:02 |
| 2 | snake | 2 | 2016-06-10 15:09:08 |
+----+-----------+-----+---------------------+
select * from tableB;
+----+-----------+---------------------+
| id | something | myDT |
+----+-----------+---------------------+
| 1 | frog | 2016-06-10 15:09:02 |
| 2 | snake | 2016-06-10 15:09:08 |
+----+-----------+---------------------+
Run Code Online (Sandbox Code Playgroud)
结果符合预期,尊重事务处理,并且不允许年龄 = 13 的插入。当然,它是任意的,但我们必须以某种方式测试它。
最后一张视觉效果。直接从 Mysql Workbench 运行插入,年龄=13
insert tableA(something,age,myDT) values ('turtle',13,now());
Run Code Online (Sandbox Code Playgroud)
错误代码:1644。由于年龄 = 13 0.000 秒,tableA_BeforeIns 被轰炸
drop database trigTranTest;
Run Code Online (Sandbox Code Playgroud)
测试数据库已被删除并消失。
| 归档时间: |
|
| 查看次数: |
6082 次 |
| 最近记录: |