MySQL 触发器中的“INSTEAD OF”,从 SQL Server 转换而来
Posted
技术标签:
【中文标题】MySQL 触发器中的“INSTEAD OF”,从 SQL Server 转换而来【英文标题】:"INSTEAD OF" in MySQL trigger, converted from SQL Server 【发布时间】:2021-07-01 20:27:59 【问题描述】:我正在将一些 SQL Server 触发器转换为 mysql,并且遇到了一些语法问题。当我将 SQL Server 数据库迁移到 Aurora RDS MySQL 时,使用 AWS Schema Conversion Tool 转换了其余的数据库架构和对象。这是我在转换时遇到问题的触发器示例:
-- 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 工作台遇到了 RAISERROR 问题,我已经查找了解决方法。但是我得到的错误是在 msg
变量附近,它说的是 Unknown system variable 'msg'
有什么想法吗?
【问题讨论】:
我建议阅读每个产品的文档以确定部分语法的工作方式。并且不要在寻找具有 MySQL 专业知识的人时标记 SQL Server。 通过拒绝选定用户的 UPDATE 权限可以更好地处理这种情况,这是一个比触发器更好的选择。在 SQL Server 和 MySQL 中。 我也在其中标记了 SQL,因为原始语法来自 SQL Server 数据库,其功能需要在 MySQL 中复制 请使用sql 标记用于SQL 语言,独立于任何实现,而sql-server 用于Microsoft SQL Server。 不要标记 SQL Server,因为 SQL Server 专家不一定是 MySQL 专家。与其说我需要在 SQL Server 中实现的这个功能,不如解释一下您的实际需求,而不依赖于 RBDMS。 【参考方案1】:它必须是 BEFORE UPDATE TRIGGER,这样 UPDATE 才会被中断
你也可以
REVOKE UPDATE ON AUD FROM '*'@'localhost';
所以没有人可以更新表了
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
无法更新 AUD 的审计行!UPDATE AUD SET id = 1 WHERE id = 1
db小提琴here
【讨论】:
【参考方案2】:我最终修改为
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 的良好转换吗?
【讨论】:
它是我的副本,你可以看到它有效 是的,我将你的答案标记为答案并投票赞成以上是关于MySQL 触发器中的“INSTEAD OF”,从 SQL Server 转换而来的主要内容,如果未能解决你的问题,请参考以下文章
SQL Server INSTEAD OF INSERT 触发器失败
为啥 INSTEAD OF UPDATE 触发器的 INSERTED 表为空?