转换SQL Server触发器到MySQL时语法错误



我必须将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;

我得到的错误:

ERROR: 1064: SQL语法错误;检查与MySQL服务器版本对应的手册,以便在"DECLARE @id int"附近使用正确的语法SELECT @id = id_sala FROM删除更新奇观设置id_hall = ' at line 2

这个触发器应该做什么并不完全清楚。但是这里有一个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有两种类型的变量:

  • 不使用@标志的局部变量。它们是用DECLARE创建的,并分配了一个数据类型。对于声明它们的代码块来说,它们是局部的。

  • 用户定义的会话变量,使用@标志。您可以使用这些内部触发器,但它们不是本地的。换句话说,在触发器完成后,您设置的值将在会话中保持设置。这些变量是在您设置它们时创建的,因此您不用declare声明它们。它们没有数据类型

代码块内的语句必须以;结束。这会造成歧义,因为CREATE TRIGGER语句本身需要终止。但是,如果您在客户机中运行此命令,并且假定;终止CREATE TRIGGER,并且在触发器的主体中有;字符,那么它就会变得混乱。解决方案是使用DELIMITER更改CREATE TRIGGER的终止符,然后可以在主体内使用;。你应该阅读https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html

另一方面,如果使用一次只处理一条输入语句的查询接口执行CREATE TRIGGER,则不会产生歧义,因此不需要更改DELIMITER。示例将是大多数查询api。

MySQL中的存储例程与SQL Server中的存储例程有很大的不同。您需要努力阅读文档并研究示例。通过Stack Overflow学习复杂的语法对你和我们的时间都不是一个有效的利用。

相关内容

  • 没有找到相关文章

最新更新