【问题标题】:No-Data error in stored procedure存储过程中的无数据错误
【发布时间】:2012-12-07 02:34:54
【问题描述】:

我正在将 SQL Server 2005 数据库转换为 MySQL,并且遇到了存储过程的问题。我是 MySQL 存储过程的新手,所以我确定这是我的转换问题,但我没有看到它。

存储过程应该生成一个临时表,用于在 vb.net 应用程序中填充数据网格视图。但是,我收到错误“数据无数据 - 提取、选择或处理了零行。”。看起来很简单,但是如果我只是将存储过程中的选择过程作为查询运行,它就会获取数据,这就是为什么我不明白为什么会出错。

我真的希望有人能告诉我原因,因为我有数百个存储过程要转换,而我在第一个过程中就遇到了这个问题。

这是存储过程:

DELIMITER $$

DROP PROCEDURE IF EXISTS `usp_get_unassigned_media`$$

CREATE DEFINER=`showxx`@`67.111.11.110` PROCEDURE `usp_get_unassigned_media`()
BEGIN
    /* GET CURSOR WITH LOCAL LOCATIONS */
    DECLARE intKey INT; 
    DECLARE dteDateInserted DATETIME;
    DECLARE vchIdField VARCHAR(200); 
    DECLARE vchValueField VARCHAR(200); 
    DECLARE intLastKey INT;


/*TAKE OUT SPECIFIC PLAYLIST ITEMS IF TOO SLOW*/
DECLARE csrMediaToBeAssigned CURSOR FOR
SELECT
  `media`.`key`             AS `key`,
  `media`.`date_inserted`   AS `date_inserted`,
  `media_detail_types`.`id` AS `id`,
  `media_details`.`value`   AS `value`
FROM (`media`
   LEFT JOIN (`media_detail_types`
          JOIN `media_details`
        ON ((`media_detail_types`.`key` = `media_details`.`detail_key`)))
     ON ((`media_details`.`media_key` = `media`.`key`)))

WHERE ((`media`.`is_assigned` = 0)
       AND ((`media_detail_types`.`id` = 'Volume Name')
         OR (`media_detail_types`.`id` = 'Drive Id')))
ORDER BY `media`.`key`,`media`.`date_inserted`,`media_detail_types`.`id`;

OPEN csrMediaToBeAssigned;

DROP TEMPORARY TABLE IF EXISTS temp_unassigned_media;
CREATE TEMPORARY TABLE temp_unnassigned_media 
    (temp_key INT, DateInserted DATETIME, IdField VARCHAR(200), ValueField VARCHAR (200)) 
    ENGINE=MEMORY;
SET intLastKey = 0;
/*--GET FIRST RECORD */

FETCH FROM csrMediaToBeAssigned
    INTO intKey, dteDateInserted, vchIdField, vchValueField;
/*--LOOP THROUGH CURSOR */
WHILE intLastKey = 0 DO
    /*--DATA SHOULD BE IN DRIVE ID THEN VOLUME NAME */

    INSERT INTO  temp_unnassigned_media
        VALUES (intKey, dteDateInserted, vchValueField, '');
    FETCH NEXT FROM csrMediaToBeAssigned
        INTO intKey, dteDateInserted, vchIdField, vchValueField;

    UPDATE temp_unnassigned_media
        SET IdField = vchValueField
        WHERE temp_key = temp_key;
    FETCH NEXT FROM csrMediaToBeAssigned
        INTO intKey, dteDateInserted, vchIdField, vchValueField;

END WHILE;
SELECT * 
    FROM temp_unnassigned_media 
    ORDER BY date_inserted; 
CLOSE csrMediaToBeAssigned;     
/*DEALLOCATE csrMediaToBeAssigned   */
/*DROP TABLE #temp_unnassigned_media    */

END$$

DELIMITER ;

【问题讨论】:

    标签: mysql stored-procedures


    【解决方案1】:

    你永远不会遇到 WHILE 循环退出的条件;您初始化 intLastKey 变量,但它永远不会改变,因此您获取整个结果集。在最后一条记录之后再次获取时会引发异常。

    规范的模式是声明一个CONTINUE HANDLER,当NOT FOUND条件被触发时MySQL会执行。处理程序通常用于设置一个变量,然后您可以对其进行测试,以便您知道何时退出循环。

    在您的情况下,看起来只需在您的 DECLARE CURSOR 语句之后和 OPEN 语句之前添加这一行就足够了:

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET intLastKey = 1;
    

    【讨论】:

    • 我知道这会很愚蠢,通常是 - 非常感谢!
    猜你喜欢
    • 2014-03-26
    • 2018-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多