在 MySQL 9.0 的存储过程/例程中定义用户变量

Defining user variables in stored procedures / routines for MySQL 9.0

根据 MySQL 8.0 弃用 notes,从 MySQL 9.0 开始,使用 DECLARE(例如 DECLARE studentID INT)的用户变量定义将被弃用:

Support for setting user variables in statements other than SET was deprecated in MySQL 8.0.13. This functionality is subject to removal in MySQL 9.0.

如今 MySQL 8.0.25 发出警告:

1287 Setting user variables within expressions is deprecated and will be removed in a future release. Consider alternatives: SET variable=expression, ..., or SELECT expression(s) INTO variables(s).

因此,我想了解如何将 DECLARE 正确替换为 SET。比方说,我声明了以下变量:

DECLARE cursor_studentID INT;
DECLARE done INT DEFAULT FALSE;
DECLARE cursor_i CURSOR FOR SELECT courseID FROM tblCoursesToCopy;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

现在我想让这些声明与 MySQL 9.0 兼容。在 DECLARE cursor_studentID INT; 的情况下,一切都相对明显:

DECLARE cursor_studentID INT; → SET @cursor_studentID;

真正的障碍是最后一个案例:

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

我不明白如何用基于 SET 的方法替换它。

弃用警告不明确,很容易被误解。

DECLARE 语法未弃用。我认为发行说明的作者不认为这是一种“设置”变量的方法。不可否认,它确实通过使用可选的 DEFAULT 子句为声明的变量设置了初始值。但我还是把它理解为一种不算弃用的说法。

弃用的是将变量设置为表达式中的“副作用”,如下所示:

SELECT @row := @row+1, ...

该技术是 MySQL 在 8.0 之前的版本中缺少 window functions 的常见解决方法。但它是非标准语法,通常容易出错且难以使用。现在 MySQL 支持标准 SQL window 函数和常见的 table 表达式,您可以像在 SQL 的其他流行实现中一样编写查询。上面的例子是:

SELECT ROW_NUMBER() OVER (), ...

:= 赋值的另一个用途是将查询的 select 列表中的表达式保存到用户定义的变量中。 MySQL 为这种用法提供了 SELECT ... INTO syntax。这个支持很久了,8.0之前的版本。

我们还没有听到任何关于 DECLARE 语法更改的通知。这不需要改变。


回复您的评论:

您可以使用以下任一形式代替 SELECT @myVar := somevalue ...

SELECT someValue INTO @myVar ...

SET @myVar = (SELECT someValue FROM ...);

请注意,后一种形式不允许您为每个查询设置多个变量。前者允许您像这样设置多个变量:

SELECT someValue, otherValue INTO @myVar1, @myVal2 ...

阅读我上面链接的关于 SELECT ... INTO 的文档。