博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Oracle --游标
阅读量:7025 次
发布时间:2019-06-28

本文共 4172 字,大约阅读时间需要 13 分钟。

hot3.png

为了处理SQL语句得到的信息,oracle必须要分配一片叫做上下文的区域来处理如上信息。游标是一个指向上下文的句柄或指针,通过游标,pl/sql可以控制上下文区域所得到的信息。

1.对于不同的SQL语句,游标的使用情况也不同

SQL语句                              游标

非查询语句                           隐式游标

结果是单行的查询语句           隐式或显示游标

结果是多行的查询语句           显示的

2.处理显示游标

declare        --定义游标类型        cursor c_cursor is select user_name,age from t_user;        --定义两个变量        v_userName t_user.user_name%type;        v_age            t_user.age%type; begin        --打开游标        open c_cursor;        --提取游标数据,即检索结果集中的数据行,放入到指定的输出变量中        fetch c_cursor into v_userName,v_age;        --这里可以理解c_cursor就是select user_name,age from t_user        --即下面的c_cursor可以用select user_name,age from t_user代替        --当select语句找得到值时,就loop        while c_cursor%found loop                dbms_output.put_line('执行自己的操作');                fetch c_cursor into v_userName,v_age;        end loop;        --关闭游标        close c_cursor;        end;

3.游标属性

%found  布尔型属性,当最近一次读记录成功时返回true

%notfound  与%found相反

%isopen  布尔型属性,当游标已打开时返回true

%rowcount  数字型属性,返回已从游标中读取的记录数

例如:给工资低于4000员工增加工资800

declare        v_empNo emp.empNo%type;        v_salary emp.salary%type;        cursor c_cursor is select empNo,salary from emp;begin        open c_cursor;        loop            fetch c_cursor into v_empNo,v_salary;            --当游标没有找到数据时,停止            exit when c_cursor%notfound;            if v_salary <=4000 then                update emp                 set salary=salary+800                where empNo=v_empNo;             end if;        end loop;          close c_cursor;  end;

 4.游标for循环

pl/sql语言提供了游标for循环语句,它会自动执行游标的open、fetch、close语句。当进入循环时,for循环语句自动打开游标,并提取第一行的游标数据,当程序处理完当前所提取的数据进入下一次循环时,游标for循环语句自动提取下一行数据进行处理,当提取完结果集中所有数据行后结束循环,并自动关闭游标。

declare        cursor c_cursor is select empNo,empName,empSalary from emp;begin        --隐含打开游标        for v_salary in c_cursor loop        --隐含执行fetch语句        dbms_output.put_line('执行自己的操作');         --隐含监测c_cursor%notfound语句        end loop;        --隐含关闭游标end;

5.隐式游标处理

显示游标主要是用于对查询语句的处理,尤其是在查询结果为多条记录的情况。而对于非查询语句,如修改、删除操作等,则由oracle系统自动的为这些操作设置游标并创建其工作区,这些由系统隐含创建的游标称为隐式游标,隐式游标的名字为SQL,这是由oracle系统定义的。对于隐式游标的操作,如定义、打开、取值及关闭操作,都由oracle系统自动完成,用户只能通过隐式游标的相关属性来完成相应的操作。

实际例子

删除emp表中某部门的所有员工,如果该部门中没有员工,则在dept表中删除该部门。

declare        v_deptNo emp.deptNo%type;begin        delete from emp where deptNo = v_deptNo;        --如果如上where语句不成立,即v_deptNo字段中没有员工        if SQL%notfound then            --在部门表中删除该部门号            delete from dept where deptNo = v_deptNo;        end if;end;

6.no_data_found与%notfound的区别

select ... into 语句会触发no_data_found;

当一个显示游标的where子句未找到时会触发%notfound;

当update或delete语句的where子句未找到时会触发SQL%notfound。

7.游标变量

游标变量是一个指向多行查询结果集中当前数据行的指针。

1>游标变量是动态的,游标是静态的。

2>游标只能与指定的查询相连,即固定指向一个查询的内存处理区域;而游标变量是动态的,它可以与不同的查询语句相连,它可以指向不同的查询语句的内存处理区域(同一时刻只能与一个查询语句相连,且要求这些查询语句的返回类型兼容)。

在定义游标变量时,有强类型定义和弱类型定义两种。强类型定义必须指定游标变量的返回值类型,而弱类型定义则不用说明返回类型。

例如,创建两个强类型、一个弱类型游标变量

--定义一个游标变量,返回类型是表t_dept类型type c_deptType is ref cursor return t_dept%rowtype; --定义一个游标变量,返回类型是t_dept表字段type c_deptType2 is ref cursor return t_dept.deptName%type;--定义一个游标变量,无返回类型type c_deptType3 is ref cursor;

 强类型游标变量举例

declare        type emp_rec is record(        empId emp.empNo%type;        empName emp.empName%type;        empJob emp.empJob%type        );        --定义游标变量,返回类型emp_rec        type empRefcurType is ref cursor return emp_rec;        --定义游标变量,类型为empRefcurType         emp_refcur empRefcurType;        --定义变量,类型为emp_rec        emp_job emp_rec;begin        open emp_refcur for        select empNo,empName,empJob from emp;        fetch emp_refcur into emp_job;        while emp_refcur%found loop                dbms_output.put_line('执行自己的操作');                    fetch emp_refcur into emp_job;        end loop;        end;

弱类型游标变量举例

declare        type c_refcur if ref cursor;        refcur c_refcur;        type sample_refType is record(        v_id number(2);        v_description varchar2(30)        );        sample sample_refType;begin        open refcur for        select deptNo,deptName from dept;        fetch refcur into sample;        while refcur%found loop               dbms_output.put_line('执行自己的操作');                 fetch refcur into sample;          end loop;         close refcur;                   end;

                             

转载于:https://my.oschina.net/u/2312022/blog/489064

你可能感兴趣的文章
Wijmo 更优美的jQuery UI部件集:活动日历控件(Event Calendar)
查看>>
艾伟_转载:面向对象封装了啥
查看>>
与马克&#183;扎克伯格共事,互联网营销
查看>>
.NET 动态脚本语言Script.NET 入门指南 Quick Start
查看>>
[观点]微软报告称开源更昂贵
查看>>
Greplin:搜索你的所有在线社交内容
查看>>
Linux内核Makefile编译生成内核目标文件的过程
查看>>
基于ArcGIS10.0和Oracle10g的空间数据管理平台五(C#开发)-通用工具类
查看>>
android游戏开发框架libgdx的使用(九)—在libgdx中使用Box2d
查看>>
山西高速公路规划图
查看>>
PHP面试题集
查看>>
深入理解JavaScript系列(2):揭秘命名函数表达式
查看>>
ITS Mobile Template interpretation failed. Template does not exist
查看>>
boost bimap 学习笔记 - 胜者,为王!!! - 博客频道 - CSDN.NET
查看>>
nyoj429 骨牌铺方格
查看>>
2011年十大新兴企业级技术
查看>>
c# 智能设备应用程序不显示在任务栏以及最小化窗体
查看>>
Windows下使用pthread库(GCC CL编译器都可以使用)
查看>>
ASP.NET MVC集成EntLib实现“自动化”异常处理[实现篇]
查看>>
去掉viewstate保持在页面中的一大串字符的方法
查看>>