具有插入选择和用户变量的MySQL存储过程

时间:2013-08-10 10:36:15

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

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

详细信息:我有一个数据表(称为data),我从中读取数据表,然后在另一个表中以1对1的相关性生成记录(称为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子句有关。当我在没有having子句的情况下运行类似但不同的查询时,该变量不会重置。
  3. 问题:为什么我不能在每次运行之前将@mycount设置为零?如果它正在重置并且只是我的Having子句导致意外计数,是否有更好的方法来重写我的SQL?

    我希望有人碰到类似的东西,因为这看起来很模糊。

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

我没有找到任何理由为什么你的代码不起作用。 无论如何,尝试以下方法。

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;

答案 2 :(得分:0)

在下面的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 ;