`

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

阅读更多

有如下存储过程:

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
分享到:
评论

相关推荐

    游标嵌套 STATUS 异常 存储过程

    一个存储过程的示例,简单展示了如下...3,游标嵌套。 4,对于嵌套游标STATUS的互相影响问题的解决办法《注意001和002的注释位置,fetch的位置》。 对于初学者,存储过程重要的几个方面,都有展示到,大虾们请忽略。

    精通SQL 结构化查询语言详解

    9.5 表连接的其他应用及注意问题  9.5.1 连接表进行聚合运算  9.5.2 多表连接的综合运用  9.5.3 多表连接注意事项  第10章 子查询  10.1 创建和使用返回单值的子查询  10.1.1 在多表查询中使用子查询...

    精通SQL--结构化查询语言详解

    9.5 表连接的其他应用及注意问题 183 9.5.1 连接表进行聚合运算 183 9.5.2 多表连接的综合运用 185 9.5.3 多表连接注意事项 186 第10章 子查询 187 10.1 创建和使用返回单值的子查询 187 10.1.1 在多表查询中...

    STL实践指南.rar

    涉及到了STL编写代码的方法、STL代码的编译和调试、命名空间(namespace)、STL中的ANSI / ISO字符串、各种不同类型的容器(container)、模板(template)、游标(Iterator)、算法(Algorithms)、分配器...

    WINDOWS STL编程

    ISO字符串、各种不同类型的容器(container)、模板(template)、游标(Iterator)、算法(Algorithms)、分配器(Allocator)、容器的嵌套等方面的问题,作者在这篇文章中对读者提出了一些建议,并指出了使用STL时...

    STL 入门最全的资料

    ISO字符串、各种不同类型的容器(container)、模板(template)、游标(Iterator)、算法(Algorithms)、分配器(Allocator)、容器的嵌套等方面的问题,作者在这篇文章中对读者提出了一些建议,并指出了使用STL时...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    认真听课、多思考问题、多动手操作、有问题一定要问、多参与讨论、多帮组同学 五、 体系结构 oracle的体系很庞大,要学习它,首先要了解oracle的框架。oracle的框架主要由物理结构、逻辑结构、内存分配、后台进程...

    mysql数据库的基本操作语法

    当主表的记录被从表参照时,主表的记录将不允许删除,如果要删除数据,需要先删除从表中依赖该记录的数据, 然后才可以删除主表的数据。还有一种就是级联删除子表数据。 注意:外键约束的参照列,在主表中引用的只能...

    JAVA面试题最全集

    使用StringBuffer类与String类进行字符串连接时有何区别? 57.调用Thread类的destroy()方法有什么后果? 58.多线程,用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用? 59.使用socket建立客户端...

    javascript中可能用得到的全部的排序算法

    排序算法可以称得上是我的盲点, 曾几何时当我知道Chrome的Array.prototype.sort使用了快速排序时, 我的内心是奔溃的(啥是快排, 我只知道冒泡啊?!), 要知道学习一门技术最好的时间是三年前, 但愿我现在补习还来得及...

    oracle数据库11G初学者指南.Oracle.Database.11g,.A.Beginner's.Guide

    主要内容——每章要介绍的具体内容列表 实践练习——演示如何应用在每章学到的关键技术 学习效果测试——对学习效果的快速自我评估 注意——与所介绍主题相关的额外信息 章节测验——每章结束时的测验测试读者对所学...

    Oracle9i的init.ora参数中文说明

    请注意所有用户均可读取或写入 UTL_FILE_DIR 参数中指定的所有文件。 值范围: 任何有效的目录路径。 默认值: 无 plsql_v2_compatibility: 说明: 设置 PL/SQL 兼容级。如果设置为 FALSE, 将执行 PL/SQL V3 行为, ...

    SQL语法大全

    COUNT(*|字段名) 对数据行数的统计或对某一栏有值的数据行数统计 MAX(字段名) 取得一个表格栏最大的值 MIN(字段名) 取得一个表格栏最小的值 SUM(字段名) 把数据栏的值相加 引用以上函数的方法: sql="select sum...

    Oracle Database 11g初学者指南--详细书签版

    CruiseYoung提供的带有详细书签的电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 Oracle Database 11g初学者指南 基本信息 原书名: Oracle Database 11g, A Beginner's Guide 原出版社: ...

    javaSE代码实例

    11.1.4 try、catch及finally语句块之间需要注意的问题 201 11.2 异常的层次结构 203 11.2.1 捕获异常 203 11.2.2 未捕获异常 205 11.3 再次抛出异常 206 11.3.1 什么是异常的再抛出 206 11.3.2 显性再...

    传智播客扫地僧视频讲义源码

    06_课堂答疑类中写成员函数_调用的时才会执行 07_程序设计方法发展历程 08_C语言和C++语言的关系_工作经验分享 09_namespace和iotream 10_实用性加强_register增强_检测增强 11_struct关键字类型增强 12_c++类型类型...

    sqlserver存储过程

    ------------查询一下是不是插入--------------- Select *from Users; -------------------------存储过程创建语法----------------------------------- /* 1.存储过程创建语法 create proc | procedure pro_name...

Global site tag (gtag.js) - Google Analytics