在 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
的文档。
根据 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, ...
, orSELECT 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
的文档。