`

游标中嵌套有其他查询时要注意的问题

阅读更多

有如下存储过程:

BEGIN
    DECLARE assetId VARCHAR(16);

	DECLARE loadAverage1 FLOAT(10,2) DEFAULT 0;
	DECLARE loadAverage15 FLOAT(10,2) DEFAULT 0;
	DECLARE loadAverageCount INT;
    
    DECLARE loadResult_Tmp VARCHAR(8192) DEFAULT '';

    DECLARE LoadAverageCursorDone INT DEFAULT 0;
    DECLARE LoadAverageCursor CURSOR FOR SELECT Asset_Id, Load_Average_1, Load_Average_15, Load_Average_Count from Load_Average_Info_Tmp;
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET LoadAverageCursorDone = 1;

    OPEN LoadAverageCursor;
    LoadAverageCursorLoop:LOOP
        FETCH LoadAverageCursor INTO assetId, loadAverage1, loadAverage15, loadAverageCount;
        IF LoadAverageCursorDone = 1 THEN
            LEAVE LoadAverageCursorLoop;
        END IF;

        SELECT Check_Result INTO loadResult_Tmp FROM Stat_CPU_All_Info_Tmp WHERE Asset_Id = assetId;

        /*
        ...
        */

    END LOOP;
    CLOSE LoadAverageCursor;
END;

 定义了一个游标用来遍历Load_Average_Info_Tmp表,每取得其中的一条数据根据取得的assetId查询Stat_CPU_All_Info_Tmp表。

 

此时遇到一个问题,Load_Average_Info_Tmp表没有遍历完提前退出了循环。

 

问题在游标里面的那条select语句:

SELECT Check_Result INTO loadResult_Tmp FROM Stat_CPU_All_Info_Tmp WHERE Asset_Id = assetId;

当游标中的这条SELECT语句查询结果为空时,会抛出一个'02000'状态而使得LoadAverageCursorDone=1,从而使得循环结束。

 

解决办法:

1.修改引起问题的SELECT语句,使其查询结果永远不为空:

SELECT Check_Result, COUNT(*) INTO loadResult_Tmp, infoCnt FROM Stat_CPU_All_Info_Tmp WHERE Asset_Id = assetId;

 将COUNT(*)查询出来,即使结果集为空,也会输出一条记录。

 修改后的完整语句:

BEGIN
    DECLARE assetId VARCHAR(16);

	DECLARE loadAverage1 FLOAT(10,2) DEFAULT 0;
	DECLARE loadAverage15 FLOAT(10,2) DEFAULT 0;
	DECLARE loadAverageCount INT;
    
    DECLARE loadResult_Tmp VARCHAR(8192) DEFAULT '';
	DECLARE infoCnt INT;

    DECLARE LoadAverageCursorDone INT DEFAULT 0;
    DECLARE LoadAverageCursor CURSOR FOR SELECT Asset_Id, Load_Average_1, Load_Average_15, Load_Average_Count from Load_Average_Info_Tmp;
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET LoadAverageCursorDone = 1;

    OPEN LoadAverageCursor;
    LoadAverageCursorLoop:LOOP
        FETCH LoadAverageCursor INTO assetId, loadAverage1, loadAverage15, loadAverageCount;
        IF LoadAverageCursorDone = 1 THEN
            LEAVE LoadAverageCursorLoop;
        END IF;

        SELECT Check_Result, COUNT(*) INTO loadResult_Tmp, infoCnt FROM Stat_CPU_All_Info_Tmp WHERE Asset_Id = assetId;

        /*
        ...
        */

    END LOOP;
    CLOSE LoadAverageCursor;
END;
 

2.第二种办法是不使用游标,改用临时表替代,方法请见Mysql存储过程优化——使用临时表代替游标

0
0
分享到:
评论

相关推荐

    mysql游标嵌套[文].pdf

    MySQL 游标嵌套实践 本文档旨在介绍 MySQL 游标嵌套的概念和实践,通过对游标的嵌套使用,演示如何实现复杂的数据操作。 一、游标嵌套简介 ...但是,也需要注意游标嵌套的注意事项,避免出现问题。

    游标嵌套 STATUS 异常 存储过程

    本示例提供了一个关于存储过程、异常处理、错误消息返回、游标嵌套及其相关问题解决的综合案例。通过这些知识点的学习,初学者可以更好地理解和掌握如何编写健壮、高效的数据库应用程序。同时,对于更高级的应用场景...

    SqlServer存储过程、游标讲解

    声明游标时可以使用简单的查询,也可以是复杂的连接查询或者嵌套查询。游标被声明后,必须先打开才能从中读取数据。读取数据时,可以逐行进行。操作完成后,需要关闭游标以释放系统资源,并且最后通过删除操作彻底...

    oracle游标优化

    9. **避免游标嵌套**:尽量减少游标嵌套的深度,因为每一层嵌套都会增加额外的开销。 通过上述方法,可以在一定程度上优化Oracle游标的性能,从而提高应用程序的整体响应时间和资源利用率。需要注意的是,每种优化...

    mysql游标详解

    在使用游标时,需要注意错误处理。在 MySQL 中,可以使用 CONTINUE HANDLER 语句来处理 NOT FOUND 错误,例如: DECLARE CONTINUE HANDLER FOR NOT FOUND SET fetchSeqOk = TRUE; 这将在游标遍历溢出时设置 ...

    SQL游标原理和使用方法

    游标在数据库编程中扮演着重要角色,尤其是在处理分步数据操作时。游标允许开发者逐行处理查询结果,提供了一种灵活的方式来控制数据的读取、修改和更新。SQL游标主要有三种类型:Transact-SQL游标、API服务器游标和...

    【最新精选】数据库实验六:游标使用.doc

    游标是数据库管理系统中一种非常重要的机制,它允许程序员或数据库管理员逐条处理查询结果集,而不仅仅是一次性获取所有记录。在本实验“数据库实验六:游标使用”中,我们将深入学习如何在SQL中操作游标,以及如何...

    Oracle 游标使用大全.doc

    - **作用域问题**:在嵌套的 PL/SQL 块中使用变量时需要注意变量的作用范围。 #### 四、隐式游标属性 - **概念解释**:当执行 DML 语句时,PL/SQL 会自动创建一个隐式游标来处理 SQL 语句的结果。虽然这个游标是不...

    Mysql的游标的定义使用及关闭深入分析

    MySQL中的游标是一种在数据库操作中...记住,游标虽然提供了逐行处理数据的能力,但也需要注意性能影响,因为它们通常比一次性加载所有数据的查询效率低。在设计数据库操作时,应权衡使用游标的好处和潜在的性能损失。

    基于Oracle数据库的分页显示中SQL复杂查询结果集总行与数据正确性控制.pdf

    需要特别注意的是,当Rownum用在where子句中时,不能单独使用大于(>)、大于等于(>=)和between and等条件,因为这些条件对Rownum不起作用。例如,对于条件Rownum>5,Oracle实际读取的第一条记录的Rownum为1,不...

    批量创建数据库中所有表的触发器,删除所有触发器

    总的来说,批量创建和删除数据库中的触发器是一项有助于提高效率的任务,尤其当数据库表数量庞大时。通过熟练运用游标、动态SQL和系统视图,我们可以自动化这些过程,减轻数据库管理员的工作负担。但同时,也应理解...

    SQL 学习5

    在使用嵌套游标时,需要注意性能优化,因为它们可能会增加CPU和内存的使用。合理的设计和优化,如限制游标返回的行数,或者使用索引提升查询速度,都是必要的。 总的来说,"SQL学习5"可能涉及了SQL高级查询技巧、PL...

    sql.rar_sql

    “防止SQL注入(嵌套游标).sql”文件很可能包含了一个示例,展示了如何在SQL查询中使用嵌套游标来安全地处理用户输入,同时避免SQL注入攻击。具体实现可能涉及到创建存储过程,使用参数,以及在存储过程中使用嵌套...

    《老旧电商系统升级改造日记 - 2》一文中用到的数据库脚本

    硬编码通常指的是将数据库连接字符串、查询语句或其他敏感信息直接写入代码中,这种方式不利于代码的维护和安全。在改造过程中,应该将这些信息抽取出来,存储在配置文件或环境变量中,以实现更灵活的管理和更高的...

    基于ADO接口技术的Oracle数据库嵌套表的开发研究.pdf

    文章中还提到了ODBC、MFCODBC、DAO和OLEDB等其他数据库访问技术,并指出了这些技术在处理带有嵌套表的数据库开发中存在的缺陷。其中,OLEDB和ADO是适用于嵌套表开发的接口技术。开发者可以根据具体需求和环境选择...

    Oracle数据库迁移到DB2数据库的技巧和注意点.doc

    10. 存储过程中嵌套存储过程的申明:在DB2数据库中,不支持在存储过程中申明临时的存储过程,只能单独申明。 11. 使用 DBMS_SQL 函数创建一个带 insert ... select ... 语句的游标,并能够计算插入的记录个数:在...

    详细的T-SQL 语句。

    然而,需要注意的是,虽然游标提供了灵活性,但在某些情况下可能会导致性能下降,因此应谨慎使用,并尽可能优化查询以避免不必要的游标操作。通过深入学习和实践,你可以更加有效地利用这些工具来解决实际的数据库...

    千万级数据库快速查询解决方案

    25. **游标的使用**:在必要的情况下使用游标,因为它们可以按需加载数据,但要注意其潜在的性能开销。 26. **查询提示的使用**:合理使用查询提示可以帮助优化查询计划。 27. **SET NOCOUNT ON/OFF**:在执行循环或...

    Oracle分页查询(很不错的介绍)

    Oracle数据库在处理大数据量时,分页查询是一个非常重要的功能,它可以帮助用户高效地获取数据集的一部分,而不是一次性加载所有结果。本篇文章将详细介绍Oracle中的分页查询,并提供一种常用的分页查询语句格式和一...

Global site tag (gtag.js) - Google Analytics