游标的个人使用理解
来源:互联网 发布:mac怎么延长待机时间 编辑:程序博客网 时间:2024/06/14 06:25
---------------静态显式游标
declare
cursor A_cursor is
select * from emp; ---直接声明游标
begin
for emp_rec in A_cursor loop
dbms_output.put_line(emp_rec.ename || emp_rec.empno || emp_rec.sal ||
emp_rec.comm || emp_rec.deptno);
end loop;
end;
与
declare
cursor A_cursor is
select * from emp; ---直接声明游标
emp_rec emp%rowtype;
begin
open A_cursor;
loop
fetch A_cursor
into emp_rec;
exit when A_cursor%notfound;
dbms_output.put_line(emp_rec.ename || emp_rec.empno || emp_rec.sal ||
emp_rec.comm || emp_rec.deptno);
end loop;
close A_cursor;
end;
与
declare
begin
for emp_rec in (select * from emp) ---隐式 游标
loop
dbms_output.put_line(emp_rec.ename || emp_rec.empno || emp_rec.sal ||
emp_rec.comm || emp_rec.deptno);
end loop;
end;
-----↑上面这三个游标的结果出来是一样的。
------------------------------------动态强类型游标 适应性强,而且可以打开多次,而且条件与记录数是不相同的情况下。
declare
type emp_cur_type is ref cursor return emp%rowtype;
emp_cur emp_cur_type;
emp_record emp%rowtype;
begin
open emp_cur for
select * from emp where deptno = 30;
loop
fetch emp_cur
into emp_record;
exit when emp_cur%notfound;
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.sal);
dbms_output.put_line('-------------------------------------');
dbms_output.put_line(emp_cur%rowcount);
end loop;
close emp_cur;
--open emp_cur for select * from dept;错误的,类型不一致。
--close emp_cur;
open emp_cur for
select * from emp where deptno = 20;
loop
fetch emp_cur
into emp_record;
exit when emp_cur%notfound;
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.sal);
dbms_output.put_line('********************');
dbms_output.put_line(emp_cur%rowcount);
end loop;
close emp_cur;
end;
------------------------------------------------------动态弱类型游标 一个emp_cur可以对应 emp_record用完也可以对应dept_record
declare
type emp_cur_type is ref cursor;
emp_cur emp_cur_type;
emp_record emp%rowtype;
dept_record dept%rowtype;
begin
open emp_cur for
select * from emp;
loop
fetch emp_cur
into emp_record;
exit when emp_cur%notfound;
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.sal);
end loop;
close emp_cur;
open emp_cur for
select * from dept; --可再次打开,不同类型的
loop
fetch emp_cur
into dept_record;
exit when emp_cur%notfound;
dbms_output.put_line('dname is:' || dept_record.dname);
end loop;
close emp_cur;
end;
/
----------------强、弱游标在同一过程中
declare
type cur1 is ref cursor;
type cur2 is ref cursor return emp%rowtype;
r_cur1 cur1;
r_cur2 cur2;
emp_record emp%rowtype;
dept_record dept%rowtype;
begin
dbms_output.put_line('Cur2_强*******************************************emp');
open r_cur2 for
select * from emp where deptno = 30;
loop
fetch r_cur2
into emp_record;
exit when r_cur2%notfound;
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.sal);
dbms_output.put_line('-------------------------------------');
dbms_output.put_line(r_cur2%rowcount);
end loop;
close r_cur2;
dbms_output.put_line('Cur1_弱**************************************************emp');
open r_cur1 for
select * from emp where deptno = 30;
loop
fetch r_cur1
into emp_record;
exit when r_cur1%notfound;
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.sal);
dbms_output.put_line('-------------------------------------');
dbms_output.put_line(r_cur1%rowcount);
end loop;
close r_cur1;
dbms_output.put_line('Cur1_弱**************************************************dept');
open r_cur1 for
select * from dept;
loop
fetch r_cur1
into dept_record;
exit when r_cur1%notfound;
dbms_output.put_line('name is:' || dept_record.deptno ||
' and sal is:' || dept_record.dname);
dbms_output.put_line('-------------------------------------');
dbms_output.put_line(r_cur1%rowcount);
end loop;
close r_cur1;
end;
-------只使用表里面某几例的游标
declare
type emp_cur_type is ref cursor;
emp_cur emp_cur_type;
type emp_record1 is record(
ename emp.ename%type,
sal emp.sal%type); ----使用type record 必须在下面声明赋值
----TYPE SalList IS TABLE OF emp.sal%TYPE; 别一种使用方式 or tyep sallist is table of emp%rowtype
emp_record emp_record1; ---这里就是声明与赋值
begin
open emp_cur for
select ename, sal from emp where deptno = 30;
loop
fetch emp_cur
into emp_record;
exit when emp_cur%notfound;
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.sal);
dbms_output.put_line('-------------------------------------');
dbms_output.put_line(emp_cur%rowcount);
end loop;
close emp_cur;
end;
---------------使用弱类型游标,对应两个不现表,不字段类型
declare
type emp_cur_type is ref cursor;
emp_cur emp_cur_type;
type emp_record1 is record(
ename varchar2(10),
job varchar2(10));
emp_record emp_record1;
begin
open emp_cur for
select ename, job from emp where deptno = 30;
loop
fetch emp_cur
into emp_record;
exit when emp_cur%notfound;
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.job);
dbms_output.put_line('-------------------------------------');
dbms_output.put_line(emp_cur%rowcount);
end loop;
close emp_cur;
open emp_cur for
select ename, to_char(sal) sal from emp where deptno = 30;
loop
fetch emp_cur
into emp_record;
exit when emp_cur%notfound;
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.job);
dbms_output.put_line('-------------------------------------');
dbms_output.put_line(emp_cur%rowcount);
end loop;
close emp_cur;
end;
----------------------sys_refcursor 可多次打开,直接声明此类型的变量,不用先定义类型再声明变量。
declare
emp_cur sys_refcursor;
emp_record emp%rowtype;
dept_record dept%rowtype;
begin
open emp_cur for
select * from emp;
loop
fetch emp_cur
into emp_record;
exit when emp_cur%notfound;
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.sal);
end loop;
close emp_cur;
open emp_cur for
select * from dept; --可再次打开,不同类型的
loop
fetch emp_cur
into dept_record;
exit when emp_cur%notfound;
dbms_output.put_line('dname is:' || dept_record.dname);
end loop;
close emp_cur;
end;
------------------其他总结:
1、游标可以用for循环,但只限于cursor cur_var is……这种类型,用在其他的里面都是错误的;for本身就包含了打开、关闭游标,此时再显示打开关闭都是错误的。
declare
cursor emp_cur is
select * from emp;
begin
--open emp_cur; --;是错误的,因为for本身就包含了打开、关闭
for emp_record in emp_cur loop
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.sal);
end loop;
--close emp_cur; ---是错误的,for本身包含了关闭。
end;
*******************************************************************************
--是不是表示:ref cursor变量不支持for打开并循环?
declare
type emp_cur_type is ref cursor return emp%rowtype;
emp_cur emp_cur_type;
begin
open emp_cur for
select * from emp; --怎么都是错,for已经打开了。
for emp_record in emp_cur --不管前面有没有打开语句,for都不承认这种类型
loop
dbms_output.put_line('name is:' || emp_record.ename || ' and sal is:' ||
emp_record.sal);
end loop;
end;
2、游标可以带参数
DECLARE
CURSOR c1(ename VARCHAR2, sal NUMBER) IS
SELECT * FROM emp WHERE sal > 800;
BEGIN
FOR person IN c1(1213, 11111) ----c1里面带了两参数,不知道做啥用的
LOOP
DBMS_OUTPUT.PUT_LINE('ename = ' || person.ename || ', sal = ' ||
person.sal || '------' || c1%rowcount);
END LOOP;
END;
3、bulk collect批量赋值
declare
type emp_cur_type is ref cursor;
emp_cur emp_cur_type;
type name_list is table of emp.ename%type;
type sal_list is table of emp.sal%type;
names name_list;
sals sal_list;
begin
open emp_cur for select ename,sal from emp;
fetch emp_cur bulk collect into names,sals;
close emp_cur;
for i in names.first .. names.last
loop
dbms_output.put_line('name is:'||names(i)||' and sal is:'||sals(i));
end loop;
end;
oracle学习之bulk collect用法
通过bulk collect减少loop处理的开销,使用Bulk Collect提高Oracle查询效率
Oracle8i中首次引入了Bulk Collect特性,该特性可以让我们在PL/SQL中能使用批查询,批查询在某些情况下能显著提高查询效率。
采用bulk collect可以将查询结果一次性地加载到collections中。
而不是通过cursor一条一条地处理。
可以在select into,fetch into,returning into语句使用bulk collect。
注意在使用bulk collect时,所有的into变量都必须是collections.
举几个简单的例子:
View Code
--在select into语句中使用bulk collect
DECLARE
TYPE SalList IS TABLE OF emp.sal%TYPE;
sals SalList;
BEGIN
-- Limit the number of rows to 100.
SELECT sal BULK COLLECT INTO sals FROM emp
WHERE ROWNUM <= 100;
for i in sals.first .. sals.last
loop
dbms_output.put_line('name is:'||sals(i)||' and sal is:'||sals(i));
end loop;
-- Retrieve 10% (approximately) of the rows in the table.
dbms_output.put_line('-------------------------');
SELECT sal BULK COLLECT INTO sals FROM emp where deptno=10;
for i in sals.first .. sals.last
loop
dbms_output.put_line('name is:'||sals(i)||' and sal is:'||sals(i));
end loop;
END;
/
--在fetch into中使用bulk collect
DECLARE
TYPE DeptRecTab IS TABLE OF dept%ROWTYPE;
dept_recs DeptRecTab;
CURSOR c1 IS
SELECT deptno, dname, loc FROM dept WHERE deptno > 10;
BEGIN
OPEN c1;
FETCH c1 BULK COLLECT INTO dept_recs;
END;
/
--在returning into中使用bulk collect
CREATE TABLE emp2 AS SELECT * FROM employees;
DECLARE
TYPE NumList IS TABLE OF employees.employee_id%TYPE;
enums NumList;
TYPE NameList IS TABLE OF employees.last_name%TYPE;
names NameList;
BEGIN
DELETE FROM emp2 WHERE department_id = 30
RETURNING employee_id, last_name BULK COLLECT INTO enums, names;
dbms_output.put_line('Deleted ' || SQL%ROWCOUNT || ' rows:');
FOR i IN enums.FIRST .. enums.LAST
LOOP
dbms_output.put_line('Employee #' || enums(i) || ': ' || names(i));
END LOOP;
END;
/
DROP TABLE emp2;
通过上面的测试和分析,我们可以看到Bulk
Collect批查询在某种程度上可以提高查询效率,它首先将所需数据读入内存,然后再统计分析,这样就可以提高查询效率。但是,如果Oracle数据库的内存较小,Shared
Pool Size不足以保存Bulk Collect批查询结果,那么该方法需要将Bulk Collect的集合结果保存在磁盘上,在这种情况下,Bulk
Collect方法的效率反而不如其他两种方法,有兴趣的读者可以进一步测试。
另外,除了Bulk Collect批查询外,我们还可以使用FORALL语句来实现批插入、删除和更新,这在大批量数据操作时可以显著提高执行效率。
----------以下未验证
4、cursor变量的位置
CREATE PACKAGE emp_data AS
TYPE EmpCurTyp IS REF CURSOR RETURN employees%ROWTYPE;
-- emp_cv EmpCurTyp; -- not allowed
PROCEDURE open_emp_cv;
END emp_data;
/
CREATE PACKAGEBODY emp_data AS
-- emp_cv EmpCurTyp; -- not allowed
PROCEDURE open_emp_cv IS
emp_cv EmpCurTyp;-- this is legal
BEGIN
OPEN emp_cvFOR SELECT *FROM employees;
END open_emp_cv;
END emp_data;
/
5、嵌套cursor
打开父cursor时,子cursor隐含打开;当
语法格式:cursor(subquery)
A nestedcursorisimplicitly openedwhenthecontainingrowisfetchedfromtheparentcursor.
Thenestedcursorisclosedonlywhen:
Thenestedcursorisexplicitly closedbytheuser
Theparentcursorisreexecuted
Theparentcursorisclosed
Theparentcursoriscanceled
示例;
declare
type emp_cur_type is ref cursor;
type dept_cur_type is ref cursor;
v_ename emp.ename%type;
v_dname dept.dname%type;
emp_cur emp_cur_type;
dept_cur dept_cur_type;
begin
open dept_cur for
select d.dname,
cursor(select e.ename from emp e where e.deptno=d.deptno )emp s from dept d;
loop
fetch dept_cur into v_dname,emp_cur;
exit when dept_cur%notfound;
dbms_output.put_line('dname is : '||v_dname);
loop
fetch emp_cur into v_ename;
exit when emp_cur%notfound;
dbms_output.put_line('--ename is : '||v_ename);
end loop;
end loop;
close dept_cur;
end;
- 游标的个人使用理解
- 理解游标(3)隐式游标的使用
- MS-SQL游标的使用及理解
- MS-SQL游标的使用及理解
- MS-SQL游标的使用及理解
- 理解游标(1):游标的概述
- Java个人理解之时间的使用
- spring的AOP个人理解和使用
- DataGridView 使用个人理解
- HandlerThread使用个人理解
- 关于游标的使用
- 游标的使用
- 游标的使用
- 游标的使用
- 游标的使用
- 游标的使用
- 游标的使用
- 游标的使用问题
- Makefile经典教程(掌握这些足够)
- C#性能优化实践
- android中 MediaStore提取缩略图和原始图像
- asp.Net 读取,删除(包括父节点)配置文件
- CYPEESS USB3.0程序解读之---同步FIFO(slaveFifoSync)
- 游标的个人使用理解
- CYPEESS USB3.0程序解读之---SPI读写
- hdu(2167)Pebbles
- 安卓书籍推荐
- 11个免费的Web安全测试工具
- 黑马程序员--JAVA基础复习之泛型
- andorid 调试心得小结
- ubuntu12.04 redmine 搭建
- 有参数的父类构造函数