【问题标题】:MySQL Stored Procedure with Insert Select and user variable带有插入选择和用户变量的 MySQL 存储过程
【发布时间】:2013-08-10 10:36:15
【问题描述】:

问题: 我有一个 MySQL 存储过程,我想在每次调用该过程时将用户变量重置为 0,但该变量似乎会记住每次运行时的值,我无法将其初始化为零。

详细信息:我有一个数据表(称为data),我从中读取数据表,然后在另一个表(称为results)中生成一对一相关的记录。我在使用 Insert Select 语句的存储过程中执行此操作。我还使用了一个用户变量@mycount,它随每一行递增。这是我的代码的简化版本:

DELIMITER //
CREATE PROCEDURE doSomething
BEGIN
    SET @mycount := 0;
    INSERT INTO results (data_id, mycounter)
        SELECT data.id, (@mycount := @mycount+1)
        FROM data LEFT JOIN results ON data.id = results.data_id
        WHERE ... GROUP BY ...
        HAVING ...
        ORDER BY ...;
END //
DELIMITER ;

分析:这几乎可以按预期工作,只是我需要在每次运行时将@mycount 重置为零,而上面的SET 语句没有实现这一点。调试时,我可以看到@mycount 的最后一个值总是从存储过程的上一次运行中记住的。我也尝试在插入后将其设置为零。

注意事项:

  1. 我正在使用@ 变量来增加和跟踪行号。也许这里还有其他选择?
  2. 问题似乎与Having 子句有关。当我运行一个类似但不同的查询但不带have子句时,变量重置没有问题。

问题:为什么不能在每次运行前将@mycount设置为零?如果它正在重置并且只是我的 Have 子句导致意外计数,是否有更好的方法来重写我的 SQL?

我希望有人遇到过类似的事情,因为这看起来很晦涩。

【问题讨论】:

标签: mysql sql stored-procedures insert-select user-variables


【解决方案1】:

我认为您正在使用会话变量(即@mycount)。检查以下网站您会得到答案

MySQL: @variable vs. variable. Whats the difference?

【讨论】:

    【解决方案2】:

    我找不到您的代码不能正常工作的任何原因。 不管怎样,试试下面的方法。

    INSERT INTO results (data_id, mycounter)
    select a.id, a.cnt from (
    select @mycount := 0 from dual
    join ( SELECT data.id, (@mycount := @mycount+1) cnt
            FROM data LEFT JOIN results ON data.id = results.data_id
            WHERE ... GROUP BY ...)) a;
    

    在这种情况下,您不需要指定SET @mycount := 0;

    【讨论】:

    • 你也可以试试:INSERT INTO results (data_id, mycounter) SELECT data.id, (@mycount := @mycount + 1) FROM (SELECT @mycount := 0) der, data LEFT JOIN results ON data.id = results.data_id;
    【解决方案3】:

    在下面SQL Fiddle我无法重现你提出的问题,理论上可以正常工作。

    更新

    试试:

    DELIMITER //
    
    CREATE PROCEDURE doSomething()
    BEGIN
        SET @mycount := 0;
        INSERT INTO results (data_id, mycounter)
            SELECT der.id, (@mycount := @mycount + 1)
            FROM (
                SELECT data.id
                FROM data
                    LEFT JOIN results ON data.id = results.data_id
                WHERE ...
                GROUP BY ...
                HAVING ...
                ORDER BY ...
            ) der;
    END //
    
    DELIMITER ;
    

    【讨论】:

    • 太奇怪了,它以某种方式在我的代码中保留了它的价值。到目前为止,我已经在此页面上尝试了答案,并且在每种情况下,值都会从一个调用持续到下一个调用。我想我的程序肯定有其他问题。
    • 如何调用存储过程?您使用 MySQL 命令行还是使用特定的 IDE?
    • 我在 PHP 脚本中调用它。这可能与它是@ 变量这一事实有关吗?有没有办法在这种情况下使用非会话变量(没有@)?
    • 如果做不到这一点,除此之外还有什么方法可以在插入选择中增加变量?
    • 一个选项是游标,应该评估性能。 13.6.6. Cursors
    猜你喜欢
    • 1970-01-01
    • 2012-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 1970-01-01
    • 2011-09-21
    相关资源
    最近更新 更多