MySQL游标只返回一条记录

MySQL游标只返回一条记录,mysql,phpmyadmin,cursor,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); DE

我使用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表的数据:

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

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

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

选择cGroupID作为GroupID,cGroupName作为GroupName;

插入日志(组id、组名称)
选择cGroupID作为GroupID,cGroupName作为GroupName;
您将看到,在调用您的过程之后,您将在
log
表中保存所有记录

这里是演示


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

  • 创建一个临时表
  • 在光标上迭代时插入所需的结果
  • 使用select将结果列表从临时表返回到客户端
  • 放下临时桌子
  • 为了说明这一点,假设您希望您的过程仅每隔一行返回一次。那么你的程序可能是这样的

    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 ;
    分隔符$$
    创建过程“TestCursor”()
    开始
    声明完成,计数器INT默认值为FALSE;
    声明cGroupID INT;
    声明cGroupName VARCHAR(50);
    声明cursor1 CURSOR用于选择GroupID,GroupName FROM Groups;
    声明未找到的继续处理程序SET done=TRUE;
    创建临时表日志
    (
    id int not null自动递增主键,
    组id int,
    组名称varchar(50)
    );
    打开游标1;
    读循环:循环
    将cursor1提取到cGroupID、cGroupName中;
    设置计数器=计数器+1;
    如果这样做的话
    离开read_循环;
    如果结束;
    如果计数器%2为0,则
    插入日志(组id、组名称)
    选择cGroupID作为GroupID,cGroupName作为GroupName;
    如果结束;
    端环;
    关闭游标1;
    从日志中选择*;
    下表日志;
    结束
    定界符
    
    这里是

    您是如何检查存储过程输出的?给出代码我在PHPMyAdmin中运行存储过程,这是唯一逻辑上相同的记录。我已经试过了,但没有任何改变。这非常有效。谢谢。我在Stack Overflow和其他一些论坛上看到了同样的问题,但实际上没有人解决这个问题。