"INSTEAD OF" 在 MySQL 触发器中,从 SQL 服务器转换而来
"INSTEAD OF" in MySQL trigger, converted from SQL Server
我正在将一些 SQL 服务器触发器转换为 MySQL,并且 运行 出现一些语法问题。其余的数据库架构和对象是使用 AWS 架构转换工具转换的,因为我正在将 SQL 服务器数据库迁移到 Aurora RDS MySQL。这是我在转换时遇到问题的触发器示例:
-- Create the UpdateAUD trigger on the new table.
CREATE TRIGGER [dbo].[UpdateAUD] ON [dbo].[AUD]
INSTEAD OF UPDATE
AS
BEGIN
IF @@ROWCOUNT > 0
BEGIN
RAISERROR( 'Audit rows for AUD cannot be updated!', -1, 0 );
ROLLBACK;
END
END;
我试过的代码如下所示:
DELIMITER $$
-- Create the UpdateAUD trigger on the new table.
CREATE TRIGGER dbo.UpdateAUD
AFTER UPDATE
ON dbo.AUD FOR EACH ROW
BEGIN
set msg = ('Audit rows for AUD cannot be updated!');
signal sqlstate '45000' set message_text = msg;
ROLLBACK;
END$$
首先,AFTER
是否可以替代 INSTEAD OF
?其次,MySQL workbench RAISERROR 有问题,我已经查找了解决方法。然而,我得到的错误是关于 msg
变量的,它说的是 Unknown system variable 'msg'
有什么想法吗?
必须是 BEFORE UPDATE TRIGGER,以便中断 UPDATE
你也可以
REVOKE UPDATE ON AUD FROM '*'@'localhost';
所以没有人可以再更新 table
CREATE TABLE AUD (id int)
INSERT INTO AUD VALUES(1)
CREATE TRIGGER UpdateAUD
BEFORE UPDATE
ON AUD FOR EACH ROW
BEGIN
set @msg := 'Audit rows for AUD cannot be updated!';
signal sqlstate '45000' set message_text = @msg;
END
✓
UPDATE AUD SET id = 1 WHERE id = 1
Audit rows for AUD cannot be updated!
db<>fiddle here
我最终修改为
DELIMITER $$
-- Create the UpdateAUD trigger on the new table.
CREATE TRIGGER dbo.UpdateAUD
BEFORE UPDATE
ON dbo.AUD FOR EACH ROW
BEGIN
signal sqlstate '45000' set message_text = 'Audit rows for AUD cannot be updated!';
END$$
根据文档,不需要 ROWCOUNT
,因为 FOR EACH ROW
应该可以处理。就 ROLLBACK
而言,我检查了 https://dev.mysql.com/doc/refman/5.6/en/trigger-syntax.html 并发现它也应该被处理。
这看起来像是对顶部发布的原始 MS-SQL 的良好转换吗?
我正在将一些 SQL 服务器触发器转换为 MySQL,并且 运行 出现一些语法问题。其余的数据库架构和对象是使用 AWS 架构转换工具转换的,因为我正在将 SQL 服务器数据库迁移到 Aurora RDS MySQL。这是我在转换时遇到问题的触发器示例:
-- Create the UpdateAUD trigger on the new table.
CREATE TRIGGER [dbo].[UpdateAUD] ON [dbo].[AUD]
INSTEAD OF UPDATE
AS
BEGIN
IF @@ROWCOUNT > 0
BEGIN
RAISERROR( 'Audit rows for AUD cannot be updated!', -1, 0 );
ROLLBACK;
END
END;
我试过的代码如下所示:
DELIMITER $$
-- Create the UpdateAUD trigger on the new table.
CREATE TRIGGER dbo.UpdateAUD
AFTER UPDATE
ON dbo.AUD FOR EACH ROW
BEGIN
set msg = ('Audit rows for AUD cannot be updated!');
signal sqlstate '45000' set message_text = msg;
ROLLBACK;
END$$
首先,AFTER
是否可以替代 INSTEAD OF
?其次,MySQL workbench RAISERROR 有问题,我已经查找了解决方法。然而,我得到的错误是关于 msg
变量的,它说的是 Unknown system variable 'msg'
有什么想法吗?
必须是 BEFORE UPDATE TRIGGER,以便中断 UPDATE
你也可以
REVOKE UPDATE ON AUD FROM '*'@'localhost';
所以没有人可以再更新 table
CREATE TABLE AUD (id int)
INSERT INTO AUD VALUES(1)
CREATE TRIGGER UpdateAUD BEFORE UPDATE ON AUD FOR EACH ROW BEGIN set @msg := 'Audit rows for AUD cannot be updated!'; signal sqlstate '45000' set message_text = @msg; END
✓
UPDATE AUD SET id = 1 WHERE id = 1
Audit rows for AUD cannot be updated!
db<>fiddle here
我最终修改为
DELIMITER $$
-- Create the UpdateAUD trigger on the new table.
CREATE TRIGGER dbo.UpdateAUD
BEFORE UPDATE
ON dbo.AUD FOR EACH ROW
BEGIN
signal sqlstate '45000' set message_text = 'Audit rows for AUD cannot be updated!';
END$$
根据文档,不需要 ROWCOUNT
,因为 FOR EACH ROW
应该可以处理。就 ROLLBACK
而言,我检查了 https://dev.mysql.com/doc/refman/5.6/en/trigger-syntax.html 并发现它也应该被处理。
这看起来像是对顶部发布的原始 MS-SQL 的良好转换吗?