Oracle --游标

为了处理SQL语句获得的信息,oracle必需要分配一片叫作上下文的区域来处理如上信息。游标是一个指向上下文的句柄或指针,经过游标,pl/sql能够控制上下文区域所获得的信息。sql

1.对于不一样的SQL语句,游标的使用状况也不一样
oracle

SQL语句                              游标oop

非查询语句                           隐式游标fetch

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

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

2.处理显示游标ip

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  布尔型属性,当最近一次读记录成功时返回trueit

%notfound  与%found相反io

%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;
相关文章
相关标签/搜索