简体   繁体   English

循环进入MySql存储过程错误代码1064

[英]Loop in a MySql stored procedure error code 1064

I'm reasonably new to writing MySQL stored procedures, and I'm trying to get my head around using loops and variables. 我是刚开始编写MySQL存储过程的新手,并且我正在尝试使用循环和变量来解决问题。

I have a table with a column called STAT_NAME, where several rows could have the same value for that column. 我有一个表,该表的列名为STAT_NAME,其中该行的几行可能具有相同的值。 I want to create a temporary column which numbers the occurrences of each STAT_NAME value, so for example first time STAT_NAME is "stat A", set STAT_COUNT to 1, 2nd time 2 etc. And then start again at 1 for "stat B" and so on. 我想创建一个临时列,该列对每个STAT_NAME值的出现进行编号,例如,第一次STAT_NAME是“ stat A”,将STAT_COUNT设置为1,第二次是2,依此类推。然后再次从1开始“ stat B”并以此类推。

I've got as far as creating the the temporary table with an empty column called STAT_COUNT, and sorted the table by STAT_NAME. 我已经创建了一个临时表,其中包含一个名为STAT_COUNT的空列,并按STAT_NAME对表进行了排序。

I've then tried to loop through all the rows and set STAT_COUNT accordingly. 然后,我尝试遍历所有行并相应地设置STAT_COUNT。 However, I get the following error: 但是,出现以下错误:

Error Code: 1064. You have an error in your SQL syntax; 错误代码:1064。 check the manual that corresponds to your MySQL server version for the right syntax to use near '@counting,1) THEN SET @STAT_NAME_CURR = (SELECT @STAT_NAME FROM tmp1 LIMIT @' 请检查与您的MySQL服务器版本相对应的手册,以获取在'@ counting,1附近使用的正确语法。然后SET @STAT_NAME_CURR =(从tmp1 LIMIT @中选择@STAT_NAME

Is anyone able to explain why what I've written is not OK? 有谁能解释为什么我写的东西不好? I think it would be fine if I used a system variable instead of @counting, and I don't understand why. 我认为如果我使用系统变量而不是@counting会很好,但我不明白为什么。 I've tried googling the problem but not getting anywhere! 我已经尝试使用Google搜索问题,但没有解决任何问题!

cheers. 干杯。

DROP PROCEDURE IF EXISTS collate_stats;
delimiter //
CREATE PROCEDURE collate_stats()
begin

create temporary table tmp1 engine=memory 
SELECT STAT_NAME, STAT, '' AS STAT_COUNT
FROM performance_testing_stats.20131014
ORDER BY STAT_NAME;

-- stat name that we are currently looking at
SET @STAT_NAME_CURR := "";
-- number of times this name has been found so far
SET @STAT_NAME_COUNT := 0;

-- Use to loop through all rows
SET @n := (SELECT COUNT(*) FROM tmp1);

-- Row reached so far
SET @counting := 0;
WHILE @counting < @n DO

    -- IF @STAT_NAME_CURR is not equal to the STAT_NAME for the current row,
    -- THEN set @STAT_NAME_CURR to STAT_NAME value and reset @STAT_NAME_COUNT
    -- ELSE just increment @STAT_NAME_COUNT
     IF @STAT_NAME_CURR <> (SELECT @STAT_NAME FROM tmp1 LIMIT @counting,1) THEN
        SET @STAT_NAME_CURR = (SELECT @STAT_NAME FROM tmp1 LIMIT @counting,1);
        SET @STAT_NAME_COUNT = 0;
    ELSE
        SET @STAT_NAME_COUNT = @STAT_NAME_COUNT + 1;
    END IF;

    -- Set STAT_COUNT for current row to value of @STAT_NAME_COUNT
    UPDATE tmp1 SET STAT_COUNT = @STAT_NAME_COUNT WHERE STAT_NAME = @STAT_NAME_CURR AND STAT_COUNT = '' LIMIT 1;

    -- Move to next row
    SET @counting = @counting + 1;
END WHILE;

select * from tmp1;

END //

delimiter ;

You might want to look into using cursors instead of the while loop. 您可能想研究使用游标而不是while循环。

However, you could probably accomplish what you are trying to do with a simple GROUP BY query: 但是,您可能可以通过一个简单的GROUP BY查询来完成您想做的事情:

SELECT STAT_NAME, STAT, COUNT(1) as STAT_COUNT
FROM performance_testing_stats.20131014
GROUP BY STAT_NAME, STAT
ORDER BY STAT_NAME, STAT;

Unless I'm missing something about what you are doing. 除非我对您的工作有所遗漏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM