MySQL游标只返回一条记录

时间:2013-11-18 01:24:48

标签: mysql phpmyadmin cursor

我正在使用Hostgator来托管我的PHP网站MySQL 5.5.33和PHPMyAdmin 3.5.5。我想使用游标从表中的单个记录中获取值。以下是该存储过程的代码:

CREATE DEFINER=`lnutri`@`localhost` PROCEDURE `TestCursor`()
   NO SQL
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE cGroupID INT;
DECLARE cGroupName VARCHAR(50);
DECLARE cursor1 CURSOR FOR SELECT GroupID, GroupName FROM Groups;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

OPEN cursor1;

read_loop: LOOP
FETCH cursor1 INTO cGroupID,cGroupName;
IF done THEN
    LEAVE read_loop;
END IF;
SELECT cGroupID AS GroupID, cGroupName as GroupName;

END LOOP;

CLOSE cursor1;
END

但是存储过程似乎只返回第一条记录:

GroupID GroupName
1           Default Group

这是Groups表的结构

CREATE TABLE IF NOT EXISTS `Groups` (
  `GroupID` int(11) NOT NULL AUTO_INCREMENT,
  `GroupName` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `Description` varchar(500) COLLATE utf8_unicode_ci NOT NULL,
  `DateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`GroupID`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=39 ;

这是Groups Table的数据:

GroupID GroupName   Description DateCreated
1           Default Group               0000-00-00 00:00:00
2           Group 2                     0000-00-00 00:00:00
29          Regis                       0000-00-00 00:00:00
31          Benetas                     0000-00-00 00:00:00
32          Domain                      0000-00-00 00:00:00
36          none                        0000-00-00 00:00:00
37          Aevum                       2013-11-11 17:40:56
38          Uniting Aged Care       2013-11-15 07:26:19

1 个答案:

答案 0 :(得分:2)

您的问题是存储过程返回结果集与表中的行一样多,并且每个结果集只有一行。您的客户端恰好是phpmyAdmin,不会处理多个结果集。这就是为什么你只看到一行。

要检查光标是否正常工作,您只需要暂时创建表格(让我们称之为log),然后更改

SELECT cGroupID AS GroupID, cGroupName as GroupName;

INSERT INTO log(group_id, group_name)
SELECT cGroupID AS GroupID, cGroupName as GroupName;

你会在调用手续后看到你在log表中记录了所有记录。

这是 SQLFiddle 演示


现在做你刚刚做的事是绝对不切实际的。如果你真的需要逐行进行一些处理并返回一些结果呢

  1. 创建临时表
  2. 在迭代光标时插入所需的结果
  3. 使用select
  4. 将结果从temp表返回给客户端
  5. 删除临时表
  6. 为了说明这一点,假设您希望您的过程仅返回每隔一行。那你的程序可能看起来像这样

    DELIMITER $$
    CREATE PROCEDURE `TestCursor`()
    BEGIN
      DECLARE done, counter INT DEFAULT FALSE;
      DECLARE cGroupID INT;
      DECLARE cGroupName VARCHAR(50);
      DECLARE cursor1 CURSOR FOR SELECT GroupID, GroupName FROM Groups;
      DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
      CREATE TEMPORARY TABLE log
      (
        id int not null auto_increment primary key, 
        group_id int,
        group_name varchar(50)
      );
    
      OPEN cursor1;
    
      read_loop: LOOP
        FETCH cursor1 INTO cGroupID,cGroupName;
        SET counter = counter + 1;
        IF done THEN
            LEAVE read_loop;
        END IF;
        IF counter % 2 <> 0 THEN
          INSERT INTO log(group_id, group_name)
          SELECT cGroupID AS GroupID, cGroupName as GroupName;
        END IF;  
      END LOOP;
    
      CLOSE cursor1;
    
      SELECT * FROM log;
      DROP TABLE log;
    END
    
    DELIMITER ;
    

    这是 SQLFiddle