MySql Cursor - 创建一个过程

时间:2011-01-06 13:05:50

标签: mysql cursor mysql-error-1064

我正在尝试第一次创建游标。我已经查看了文档,我理解了这个概念,但我似乎无法理解它......

我正在使用:

  • MySql 5.1.41
  • SqlYog作为经理
  • (在xampp instalation上本地运行)

即使复制粘贴http://dev.mysql.com/doc/refman/5.1/en/cursors.html

中的示例
    CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT 0;
  DECLARE a CHAR(16);
  DECLARE b,c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES (a,b);
    ELSE
      INSERT INTO test.t3 VALUES (a,c);
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;

我立即收到错误: 错误代码:1064

  

您的SQL语法有错误;   检查对应的手册   您的MySQL服务器版本   正确的语法在''第3行附近使用

以及其他一些人,

这对我没有任何意义,任何善良的灵魂都可以帮助我吗?

谢谢

所以我让样本查询工作(感谢ajreal),重置DELIMITER。但是当我运行我的查询时:

DELIMITER##
CREATE PROCEDURE RetiraPoints()
BEGIN
    DECLARE userid BIGINT;  
    DECLARE done INT DEFAULT 0;
    DECLARE cur CURSOR FOR SELECT uid FROM viewpoints;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    OPEN cur;
    read_loop: LOOP 
    FETCH cur INTO userid;
        IF done THEN
            LEAVE read_loop;
        END IF;
        INSERT INTO points (iduser, points, pointcat) VALUES (uid, -1, 1), (userid, -1, 2), (userid, -1, 3), (userid, -1, 4), (userid, -1, 5), (userid, -1, 6);
    END LOOP;
    CLOSE cur;
END;##

我得到: 错误代码:1064

  

您的SQL语法有错误;   检查对应的手册   您的MySQL服务器版本   正确的语法在'DECLARE done附近使用   INT DEFAULT 0; DECLARE cur CURSOR FOR   SELECT uid FROM viewpoints; '在线   1

天哪,这很难......

3 个答案:

答案 0 :(得分:3)

您忘记将分隔符重置为NOT ;

delimiter ##
...
end##

需要在分隔符后面加上空格

结尾END不需要;

答案 1 :(得分:2)

我需要做同样的事情,所以我最终编写了一个存储过程来完成这项工作。我把它包含在这里,它在MySQL Workbench上运行得很好。有趣的是,它将 在Navicat上正确运行,因为原始的select语句不会省略NULL值,因此会删除所有索引。

我建议您仔细阅读代码并打破一些内容并单独运行,以确保它能够满足您的需求。

编写它的方式,它应该删除给定连接中所有数据库中的每个外键。不要按原样运行它,除非你想做的事情。

使用风险自负。

DELIMITER $$

CREATE PROCEDURE `pRemoveAllForeignKeys`()
BEGIN

DECLARE sName TEXT;
DECLARE cName TEXT;
DECLARE tName TEXT;
DECLARE done INT DEFAULT 0;
DECLARE cur CURSOR FOR 
    SELECT TABLE_SCHEMA, CONSTRAINT_NAME, TABLE_NAME
        FROM information_schema.key_column_usage
        WHERE REFERENCED_TABLE_SCHEMA IS NOT NULL
--          AND TABLE_SCHEMA = 'NameOfAParticularSchema' -- use this line to limit the results to one schema
--          LIMIT 1 -- use this the first time because it might make you nervous to run it all at once.
        ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

OPEN cur;
read_loop: LOOP 
FETCH cur INTO sName, cName, tName;
    IF done THEN
        LEAVE read_loop;
    END IF;
    SET @s = CONCAT('ALTER TABLE ',sName, '.', tName, ' DROP FOREIGN KEY ', cName);
--      SELECT @s; -- uncomment this if you want to see the command being sent
    PREPARE stmt FROM @s;
    EXECUTE stmt;
END LOOP;
CLOSE cur;
deallocate prepare stmt;
END

答案 2 :(得分:0)

create or replace procedure cursor_sample()
BEGIN

DECLARE done int default 0 ;
DECLARE data1 varchar(20) ;
DECLARE data2 int ;

DECLARE cur1 CURSOR FOR 
select sname,examscore from student ;
DECLARE CONTINUE HANDLER 
FOR NOT FOUND SET done = 1 ;
OPEN cur1;
loop1:LOOP 
    FETCH cur1 into data1,data2 ;
    insert into student_log(user_name,score) values (data1,data2) ;
    if done = 1 THEN
        LEAVE loop1 ;
    END IF ;
END LOOP;
CLOSE cur1;
END ;
//

-这是存储过程中正确执行游标的示例。---