【问题标题】:Defining user variables in stored procedures / routines for MySQL 9.0在 MySQL 9.0 的存储过程/例程中定义用户变量
【发布时间】:2021-06-02 20:50:34
【问题描述】:

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

支持在 SET 以外的语句中设置用户变量是 在 MySQL 8.0.13 中已弃用。此功能可能会被删除 在 MySQL 9.0 中。

现在 MySQL 8.0.25 已经发出警告:

1287 在表达式中设置用户变量已被弃用,并将 在未来的版本中被删除。考虑替代方案:SET variable=expression, ...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 的方法替换它。

【问题讨论】:

    标签: mysql deprecation-warning user-variables


    【解决方案1】:

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

    DECLARE 语法未被弃用。我认为发行说明的作者不认为这是一种“设置”变量的方法。诚然,它确实通过使用可选的DEFAULT 子句为声明的变量设置了一个初始值。但我仍然将其解释为不被视为已弃用的声明。

    不推荐使用的是在如下表达式中将变量设置为“副作用”:

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

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

    SELECT ROW_NUMBER() OVER (), ...
    

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

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


    你的cmets:

    除了SELECT @myVar := somevalue ...,您可以使用以下任一形式:

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

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

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

    阅读我在上面链接到的SELECT ... INTO 上的文档。

    【讨论】:

    • 太好了,谢谢。那么我怎样才能摆脱这些警告(«1287 Setting user variables within expressions is deprecated and will be removed in a future release.»)?
    • 您是说警告来自您使用DECLARE 的过程,即使您没有使用@var := ... assignment-in-expressions 语法?
    • 其实有SELECT @myVar := someValueSELECT @myVar FROM…。需要注意的是,当我在 MySQL Workbench 中将例程的 DDL 作为常规 SQL 脚本而不是通过 Stored Procedures → Create Stored Procedure... 执行时,我会收到此警告。
    猜你喜欢
    • 1970-01-01
    • 2010-12-08
    • 2011-03-13
    • 2016-11-03
    • 2012-04-09
    • 1970-01-01
    • 2016-07-19
    • 2015-12-10
    相关资源
    最近更新 更多