将SQL Server触发器转换为MySQL时出现语法错误

ssgvzors  于 2022-12-10  发布在  Mysql
关注(0)|答案(1)|浏览(140)

我必须将SQLServer触发器转换为MySQL。我试图在MySQL中重新创建它,但问题是每次尝试不同的组合时都会出现语法错误,我不知道什么不起作用,为什么不起作用。
我正在创建影院数据库,当从Hall表中删除条目时,将启动以下触发器。假设一个大厅正在翻新,我们必须将那个大厅的演出转移到其他地方。在本例中,它们被移动到索引为1的大厅,该大厅比远处的大厅小。
以下是SQLServer查询:

CREATE TRIGGER tDeleteHall ON Hall
FOR DELETE
AS
BEGIN
DECLARE @id int
SELECT @id = id_hall FROM deleted
UPDATE Spectacle set id_hall = @id - 1
END
DELETE FROM Hall WHERE id_hall = 3;

MySQL代码

CREATE TRIGGER tDeleteHall BEFORE DELETE ON Hall
DECLARE @id int
SELECT @id = id_hall FROM deleted
UPDATE Spectacle set id_hall = @id - 1
END
DELETE FROM Spectacle WHERE id_hall = 3;

我得到的错误是:
错误:1064:您的SQL语法中有一个错误;请查看与您的MySQL服务器版本对应的手册,以了解在第2行的删除更新场景集合id_Hall=‘中使用的正确语法

bzzcjhmw

bzzcjhmw1#

目前还不完全清楚这个扳机应该起到什么作用。但这里有一个MySQL触发器,我认为它可以做同样的事情。

CREATE TRIGGER tDeleteHall BEFORE DELETE ON Hall
FOR EACH ROW
BEGIN
  UPDATE Spectacle SET id_hall = OLD.id_hall - 1;
END

MySQL没有deleted伪表。相反,它使用OLD.<column>来引用已删除的行,或者在INSERT和UPDATE触发器中,使用NEW.<column>来引用新行版本。
MySQL的触发器始终是行触发器,而不是SQL Server中的语句触发器。然而,MySQL触发器需要使用FOR EACH ROW语法。也许有一天它们也会支持语句触发器。
您不需要为所显示的示例声明局部变量。但如果您确实使用局部变量,请注意,与SQL Server不同,MySQL例程中的局部变量不能使用@符号。
MySQL有两种类型的变量:

  • Local variables,不使用@符号。它们是用DECLARE创建的,并分配了一种数据类型。它们对于在其中声明它们的代码块是本地的。
  • User-defined session variables,使用@符号。您可以使用这些内部触发器,但它们不是本地触发器。换句话说,触发器完成后,您设置的值将在您的会话中保持设置。这些变量是在您设置它们时创建的,因此您不需要使用DECLARE来声明它们。它们没有数据类型。

代码块内的语句必须以;结尾。这造成了歧义,因为CREATE TRIGGER语句本身需要终止。但是,如果您在假定;终止CREATE TRIGGER,并且触发器主体中有;字符的客户端中运行此命令,它就会变得混乱。解决方案是使用DELIMITER更改CREATE TRIGGER的终止符,然后可以在体内使用;。你应该阅读https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html
另一方面,如果使用一次只处理一条输入语句的查询接口执行CREATE TRIGGER,则不会有歧义,因此不需要更改分隔符。大多数查询API就是一个例子。
MySQL中存储的例程与SQL Server有很大不同。您需要努力阅读文档并研究示例。试图通过Stack Overflow学习复杂的语法并不是有效地利用您或我们的时间。

相关问题