5

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

我正在使用:

  • mysql 5.1.41
  • SqlYog 作为管理者
  • (在 xampp 安装上本地运行)

即使复制粘贴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 CURSOR FOR SELECT uid FROM views; ' 在第 1 行

我的天,这太难了……

4

3 回答 3

3

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

delimiter ##
...
end##

需要在分隔符后放置一个空格

而且结局END不需要;

于 2011-01-06T13:27:38.323 回答
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
于 2013-03-21T21:58:26.267 回答
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 ;
//

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

于 2020-07-28T12:03:37.930 回答