您的位置:首页 > 数据库 > Oracle

Oracle游标

2016-08-22 15:55 176 查看


一、静态游标

(一)、隐式游标

-- 在PL/SQL中使用DML语句时自动创建隐式游标

---隐式游标自动声明、打开和关闭,其名为 SQL

--单行数据

select job,sal from emp where ename='SCOTT';

declare

v_ename emp.ename%type:=&name;

v_job emp.job%type;

v_sal emp.sal%type;

begin

select job,sal into v_job,v_sal from emp where ename=v_ename; --隐式游标

dbms_output.put_line(v_job||'-->'||v_sal);

--处理异常

exception

when no_data_found then

dbms_output.put_line('没有找到数据!');

when others then

dbms_output.put_line('error:'||sqlcode||'-->'||sqlerrm);

end;

(二)、显示游标

/*说明光标语法:

CURSOR 光标名 [ (参数名 数据类型[,参数名 数据类型]...)] IS SELECT 语句;

 用于存储一个查询返回的多行数据

例如: cursor c1 is select ename from emp;

 打开光标: open c1; (打开光标执行查询)

 取一行光标的值:fetch c1 into pjob; (取一行到变量中)

 关闭光标: close c1;(关闭游标释放资源)*/

/*%FOUND – SQL 语句影响了一行或多行时为 TRUE

%NOTFOUND – SQL 语句没有影响任何行时为TRUE

%ROWCOUNT – SQL 语句影响的行数

%ISOPEN - 游标是否打开,始终为FALSE*/

--(1)简单显式游标

select * from emp;

declare

v_emp emp%rowtype; --一行记录类型变量

--1)声明游标

cursor c1 is select * from emp;

begin

--2)打开游标

open c1;

--3)提取每一行的数据 (循环)

loop

fetch c1 into v_emp; --select * into v_emp from emp;

exit when c1%notfound; --退出循环

dbms_output.put_line(c1%rowcount||': '||v_emp.empno||'-->'||v_emp.ename||'-->'||v_emp.job||'-->'||v_emp.sal); ---输出结果

end loop;

--4)关闭游标

close c1;

end;

select ename,sal from emp where deptno=10;

declare

v_ename emp.ename%type; --一行记录类型变量

v_sal emp.sal%type;

--1)声明游标

cursor c1 is select ename,sal from emp where deptno=10;

begin

--2)打开游标

open c1;

--3)提取每一行的数据 (循环)

loop

fetch c1 into v_ename,v_sal; --select * into v_emp from emp;

exit when c1%notfound; --退出循环

dbms_output.put_line(c1%rowcount||': '||v_ename||'-->'||v_sal); ---输出结果

end loop;

--4)关闭游标

close c1;

end;

--(2)基于游标定义记录变量

select * from emp;

declare

-- v_emp emp%rowtype; --一行记录类型变量

--1)声明游标

cursor c1 is select * from emp;

--游标定义记录变量

v_emp c1%rowtype;

begin

--2)打开游标

open c1;

--3)提取每一行的数据 (循环)

loop

fetch c1 into v_emp; --select * into v_emp from emp;

exit when c1%notfound; --退出循环

dbms_output.put_line(c1%rowcount||': '||v_emp.empno||'-->'||v_emp.ename||'-->'||v_emp.job||'-->'||v_emp.sal||'-->'||v_emp.deptno); ---输出结果

end loop;

--4)关闭游标

close c1;

end;

--(3)带参数显式游标

-- CURSOR 光标名 [ (参数名 数据类型[,参数名 数据类型]...)] IS SELECT 语句;

select ename,sal from emp where deptno=20 and sal>2000

declare

v_ename emp.ename%type; --一行记录类型变量

v_sal emp.sal%type;

--1)声明游标 有参数时数据类型不能写大小number(5)

cursor c1(v_deptno number,v_sal number) is select ename,sal from emp where deptno=v_deptno and sal>v_sal;

begin

--2)打开游标(传参数值)

open c1(20,2000);

--3)提取每一行的数据 (循环)

loop

fetch c1 into v_ename,v_sal; --select * into v_emp from emp;

exit when c1%notfound; --退出循环

dbms_output.put_line(c1%rowcount||': '||v_ename||'-->'||v_sal); ---输出结果

end loop;

--4)关闭游标

close c1;

end;

--(4)使用显式游标更新行

-- 给所有的部门销售员加薪500

select *from emp where job='SALESMAN'and sal<1800

select * from emp2;

--复制数据

insert into emp2 select * from emp where job='SALESMAN'and sal<1800

declare

--1)声明游标

cursor c1 is select *from emp2 where job='SALESMAN' for update; --for udpate

--游标记录类型变量

v_emp c1%rowtype;

begin

--2)打开游标

open c1;

--3)更新数据

loop

fetch c1 into v_emp;

exit when c1%notfound;

--每一行

update emp2 set sal = sal+500 where current of c1; --where current of c1 在当前游标中

end loop;

--4)关闭游标

close c1;

end;

select * from emp2;

--将所有的部门销售员的工资小宇2200的全部删除?

--(5)循环游标

--PL/SQL语言提供了游标FOR循环语句,自动执行游标的OPEN、FETCH、CLOSE语句和循环语句的功能;

当进入循环时,游标FOR循环语句自动打开游标,并提取第一行游标数据;

当程序处理完当前所提取的数据而进入下一次循环时,游标FOR循环语句自动提取下一行数据供程序处理;

当提取完结果集合中的所有数据行后结束循环,并自动关闭游标。

格式:

/* FOR index_variable IN cursor_name[(value[, value]…)] LOOP

-- 游标数据处理代码

END LOOP;*/

-- 给所有的部门销售员-500

declare

--1)声明游标

cursor c1 is select *from emp2 where job='SALESMAN' for update; --for udpate

begin

--3)更新数据

for v_emp in c1 loop

--每一行

update emp2 set sal = sal-500 where current of c1; --where current of c1 在当前游标中

end loop;

end;

select * from emp2;

--查询所有的数据

declare

--1)声明游标

cursor c1 is select *from emp2;

begin

for v_emp in c1 loop

dbms_output.put_line(c1%rowcount||v_emp.ename||'-->'||v_emp.job);

end loop;

end;

二、动态游标

/*

什么是动态游标?

动态游标也称REF游标

经常用于处理运行时动态执行的 SQL 查询*/

/*声明 REF 游标类型

例:TYPE REF_CURSOR_TYPE IS REF CURSOR;

声明 REF 游标类型的变量

例:cv_ref REF_CURSOR_TYPE;*/

/* 打开游标变量时使用的是OPEN…FOR 语句

例:OPEN cursor_name FOR select_statement;*/

declare

--1)定义一个游标数据类型

type emp_cursor_type is ref cursor;

--游标变量

c1 emp_cursor_type;

v_emp emp%rowtype; --记录类型变量

v_dept dept%rowtype; --记录类型变量

begin

--2)打开游标

open c1 for select * from emp where deptno=20;

--3)提取数据

loop

fetch c1 into v_emp;

exit when c1%notfound;

dbms_output.put_line(c1%rowcount||': '||v_emp.empno||'-->'||v_emp.ename||'-->'||v_emp.job||'-->'||v_emp.sal||'-->'||v_emp.deptno); ---输出结果

end loop;

--用同一个游标指向另一个查询语句

open c1 for select * from dept where deptno in (10,20);

--3)提取数据

loop

fetch c1 into v_dept;

exit when c1%notfound;

dbms_output.put_line(c1%rowcount||': '||v_dept.dname||'-->'||v_dept.loc); ---输出结果

end loop;

--4)关闭游标

close c1;

end;

三、静态SQL与动态SQL


什么是静态SQL?


需要在编写PL/SQL程序时就确定的SQL语句

什么是动态SQL?


动态
SQL 是指在PL/SQL程序执行时生成的
SQL 语句


DDL
语句命令和会话控制语句不能在 PL/SQL
中直接使用,但是可以通过动态 SQL
来执行


编译程序对动态
SQL 不做处理,而是在程序运行时动态构造语句、对语句进行语法分析并执行



使用EXECUTE IMMEDIATE
语句执行:




DDL
语句、DCL
语句、非查询的DML
语句、单行查询的SELECT
语句


 --(1)、EXECUTE IMMEDIATE 语句执行。

本地动态SQL执行DML语句



select * from dept;

--添加部门信息

insert into dept values(?,?,?)

declare

v_deptno dept.deptno%type:=&no;

v_dname dept.dname%type:=&name;

v_loc dept.loc%type:=&loc;

--save sql

v_sql varchar2(500);

begin

v_sql:='insert into dept values(:no,:name,:loc)';

--execute sql

execute immediate v_sql using v_deptno,v_dname,v_loc;

--exception

exception

when others then

null;

end;

--查询部门的个数有具体返回的值

select count(1) from dept;

declare

v_count number;

--save sql

v_sql varchar2(500);

begin

v_sql:='select count(1) from dept';

--execute sql

execute immediate v_sql into v_count;

dbms_output.put_line(v_count);

--exception

exception

when others then

null;

end;

--(2)通过游标实现



通过游标实现:




多行查询的SELECT语句


select * from emp where deptno=20;

declare

type emp_cursor_type is ref cursor;

c1 emp_cursor_type;

v_emp emp%rowtype;

begin

--OPEN cursor_name FOR dynamic_sql_string [USING bind_argument_list];

--打开

open c1 for 'select * from emp where deptno=:x'using 10;

--提取数据

loop

fetch c1 into v_emp;

exit when c1%notfound;

dbms_output.put_line(c1%rowcount||': '||v_emp.empno||'-->'||v_emp.ename||'-->'||v_emp.sal||'-->'||v_emp.deptno); ---输出结果

end loop;

--关闭

close c1;

end;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: