我的代码如下,一般是进入 scott/tiger 用户下创建即可:
create or replace package Pac_Select_GZ is
type mycursor is ref cursor;
procedure Pro_Select_GZ(ret_cursor out mycursor,ISCheck_ varchar2,time_ varchar2);
end Pac_Select_GZ;
create or replace package body Pac_Select_GZ is
procedure Pro_Select_GZ(ret_cursor out mycursor,ISCheck_ varchar2,time_ varchar2) as
time_temp varchar2(20); -- 这个长度依据你传入 time_ 的长度而定
IsCheck_temp varchar2(20);
begin
if time_ ='' or time_ is null then
time_temp := '_' ;
else
time_temp := time_ ;
end if;
if ISCheck_ ='' or ISCheck_ is null then
IsCheck_temp := '_' ;
else
IsCheck_temp := ISCheck_;
end if;
open ret_cursor for select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,dept.deptno from emp
left join dept on emp.deptno = dept.deptno
where emp.ename like'%'||IsCheck_temp||'%' and dept.deptno like'%'||time_temp||'%';
end Pro_Select_GZ;
end Pac_Select_GZ;
declare
emp_cur Pac_Select_GZ.mycursor;
begin
Pac_Select_GZ.Pro_Select_GZ(emp_cur,'10','L');
for emp_row in emp_cur loop
dbms_output.put_line(emp_row.empno);
exit when emp_cur%notfound;
end loop;
end;
create or replace package Pac_Select_GZ is
type mycursor is ref cursor;
procedure Pro_Select_GZ(ret_cursor out mycursor,ISCheck_ varchar2,time_ varchar2);
end Pac_Select_GZ;
create or replace package body Pac_Select_GZ is
procedure Pro_Select_GZ(ret_cursor out mycursor,ISCheck_ varchar2,time_ varchar2) as
time_temp varchar2(20); -- 这个长度依据你传入 time_ 的长度而定
IsCheck_temp varchar2(20);
begin
if time_ ='' or time_ is null then
time_temp := '_' ;
else
time_temp := time_ ;
end if;
if ISCheck_ ='' or ISCheck_ is null then
IsCheck_temp := '_' ;
else
IsCheck_temp := ISCheck_;
end if;
open ret_cursor for select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,dept.deptno from emp
left join dept on emp.deptno = dept.deptno
where emp.ename like'%'||IsCheck_temp||'%' and dept.deptno like'%'||time_temp||'%';
end Pro_Select_GZ;
end Pac_Select_GZ;
declare
emp_cur Pac_Select_GZ.mycursor;
begin
Pac_Select_GZ.Pro_Select_GZ(emp_cur,'10','L');
for emp_row in emp_cur loop
dbms_output.put_line(emp_row.empno);
exit when emp_cur%notfound;
end loop;
end;
declare
cursor emp_cur is select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,dept.deptno from emp
left join dept on emp.deptno = dept.deptnobegin
Pac_Select_GZ.Pro_Select_GZ(emp_cur,'10','L');
for emp_row in emp_cur loop
dbms_output.put_line(emp_row.empno);
exit when emp_cur%notfound;
end loop;
end;
这样是没有问题的。。
type mycursor is ref cursor;
emp_cur mycursor;
begin
Pac_Select_GZ.Pro_Select_GZ(emp_cur,'10','L');
for emp_row in emp_cur loop
dbms_output.put_line(emp_row.empno);
exit when emp_cur%notfound;
end loop;
end;
create table curTest(i number);
--测试数据
insert into curTest select 1 from dual union all select 2 from dual;
--测试包
create or replace package sp_test is
type ResultData is ref cursor;
procedure getcurTest(rst out ResultData);
end sp_test;
/
create or replace package body sp_test is
procedure getcurTest(rst out ResultData) is
begin
open rst for select * from curTest;--返回curTest的内容
end;
end sp_test;
/
--调试包中的getcurTest
declare
cur sp_test.ResultData;
i number;
begin
sp_test.getcurTest(cur);
loop
fetch cur into i;
exit when cur%notfound;
dbms_output.put_line(i);
end loop;
end;
--输出结果
1
2
6 楼的方法我试过了,还是包 emp_cur "不是过程或尚未定义" 7 楼写的游标结构是只有一列 "open rst for select * from curTest;--返回curTest的内容 ",而我的游标结构是两张表的联合查询, 所以你的方法行不通,感谢各位的探讨,继续等待正解~!
动态游标与你几张表没有关系,返回的是一个查询的结果集
declare
cur sp_test.ResultData;
i number;
j number;--添加一列
begin
sp_test.getcurTest(cur);
loop
fetch cur into i,j;--这样
exit when cur%notfound;
dbms_output.put_line(i);
end loop;
end;
left join dept on emp.deptno = dept.deptno”我的列是这么多,那不是我要写很多列来接收游标?
end loop;
这种语句是用于隐式游标上的,它实际的操作过程是open emp_cur ,然后fetch emp_cur所有的记录,最后是close emp_cur ,而楼主在这条语句之前又open了一次emp_cur,因此会出错。
那我怎么样将游标结构赋值到 mycursor 上呢?
for emp_row in emp_cur loop
end loop;
这种语句,使用另外的循环语句。你可以定义一个record_type,里面的字段是(emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,dept.deptno ),
再定义一个类型为record_type的table_type,用
open ret_cursor for select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,dept.deptno from emp
left join dept on emp.deptno = dept.deptno
where emp.ename like'%'||IsCheck_temp||'%' and dept.deptno like'%'||time_temp||'%';
fetch ret_cursor bulk collect into vtable_table;
循环读取vtable_table就可以了。
如果用显示游标,只能用
cursor emp_cur is select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,dept.deptno from emp
left join dept on emp.deptno = dept.deptno
这种方法了
1. 如果我用隐式游标,按照你的意思是说我要专门定义一个 table_type 来配合我的游标结构,这样就可以读出值,这个我知道,但是我就是想没有必要的情况下不定义一个接收游标的结构,直接循环打印出来。 2.如果是用显示游标的话就是
cursor emp_cur is select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,dept.deptno from emp
left join dept on emp.deptno = dept.deptno
这个游标的值我还要在 java 中接收,通过一个游标把查询的结构返回,做具体操作!我现在就是想用隐式游标来实现我的功能:存储过程返回一个游标,此游标可在 java 中调用出来,也可在 PL/SQL 中调用出来。当然如果有更好的方法,我会选择好的方法的! 看来我给的分是不够了,要加分了!
在Java中用ResultSet接收这个结果集
,那就只有用 loop fetch.. end loop。 问题就出在这里, 我 fetch into 的时候要将游标的结构 fetch 到一个结构中,我的游标结构是一个双表查询,那么我接受此游标就需要顶一个一个 type 来接收此游标,我想找到这个 type 要怎么样定义?
只要你事先知道游标的字段树木和类型,楼主的问题并不难解决。
object opaque
符号 "object在 "RECODE" 继续之前已插入。
Line: 3
Text: type ftType as recode(empno VARCHAR2(40),ename VARCHAR2(40),job VARCHAR2(40),mgr VARCHAR2(40),hiredate VARCHAR2(40),deptno number(10));
TYPE RtnRcd IS RECORD (
A VARCHAR2(100),
B VARCHAR2(100));
在packagebody中直接使用这个类型即可。
你这个方法还是不行哟! 我按照你的重新建了一个 type ,但是当我把游标 fetch 到这个类型时,报错:RECORD 不能作为 fetch/select 的赋值目标。如果真的没有解决我这样的办法,那我真的要放弃????
由doerclcur调TT。CREATE OR REPLACE PROCEDURE DOERCLCUR
IS
type trd is record(str1 varchar2(100),str2 varchar2(100),str3 varchar2(100));
aaa sys_refcursor;
rd trd;
BEGIN
tt(aaa);
fetch aaa into rd;
close aaa;
dbms_output.put_line(rd.str1);
END;CREATE OR REPLACE PROCEDURE TT(val in out sys_refcursor)
IS
BEGIN
open val for 'select ''col1'',''col2'',''col3'' from dual';
END;
难道不fetch到一个结构中,不能完成业务?
left join dept on emp.deptno = dept.deptno
建视图vv
2,然后游标:cursor emp_cur is select * from vv where ....;
3,然后fetch到vv的rowtype就OK了
create table userTabel(
userid number(10),
username varchar2(100),
constraint PK_USERID PRIMARY KEY(userid)
);
commit; insert into userTabel values(1,'Albert');
insert into userTabel values(2,'reboot') ;
insert into userTabel values(3,'Jeff');
create or replace package pkg_BB is
-- Author : ADMINISTRATOR
-- Created : 2008-07-17 8:35:52
-- Purpose :
-- Public type declarations
type mycur is ref cursor;
type myrecord is record(
myid usertabel.userid%type,
myname usertabel.username%type);
procedure pro_GetCur(cur_return out mycur);
end pkg_BB;create or replace package body pkg_BB is
-- Function and procedure implementations
procedure pro_GetCur(cur_return out mycur)
is
begin
open cur_return for select * from Usertabel;
end pro_GetCur;
end pkg_BB;------------------------测试代码:declare
rec pkg_bb.myrecord;
cur pkg_bb.mycur;
begin
pkg_bb.pro_GetCur(cur);
/*;
close cur;
dbms_output.put_line(rec.myid);
dbms_output.put_line(rec.myname);*/
loop
fetch cur into rec;
exit when cur%notfound;
dbms_output.put_line(rec.myid);
dbms_output.put_line(rec.myname);
end loop;
close cur;
end;输出结果:
1
Albert
2
reboot
3
Jeff-------------------------------------------------------
有关游标的在程序中的调用问题:
Java程序中调用我不太明白;
在C#中请参见我的帖子:http://topic.csdn.net/u/20080714/11/feac98eb-9b20-42dc-b628-2c81a0e9381b.html希望对你有用!! Good Luck!
33 楼的,你的方法跟上面介绍的方法是一样的,我就是不明白我的程序它为什么抱 emp_cur "不是存储过程或尚未定义",我建立的程序包再 java 程序中是可以调用的 ,再 PL/SQL 中测试就出现了上诉的问题,以下是我的程序包建立以及调用create or replace package Pac_Select_GZ is
type mycursor is ref cursor;
procedure Pro_Select_GZ(ret_cursor out mycursor,ISCheck_ varchar2,time_ varchar2);
end Pac_Select_GZ;
create or replace package body Pac_Select_GZ is
procedure Pro_Select_GZ(ret_cursor out mycursor,ISCheck_ varchar2,time_ varchar2) as
time_temp varchar2(20); -- 这个长度依据你传入 time_ 的长度而定
IsCheck_temp varchar2(20);
begin
if time_ ='' or time_ is null then
time_temp := '_' ;
else
time_temp := time_ ;
end if;
if ISCheck_ ='' or ISCheck_ is null then
IsCheck_temp := '_' ;
else
IsCheck_temp := ISCheck_;
end if;
open ret_cursor for select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,dept.deptno from emp
left join dept on emp.deptno = dept.deptno
where emp.ename like'%'||IsCheck_temp||'%' and dept.deptno like'%'||time_temp||'%';
end Pro_Select_GZ;
end Pac_Select_GZ;
调用: declare
emp_cur Pac_Select_GZ.mycursor;
begin
Pac_Select_GZ.Pro_Select_GZ(emp_cur,'10','L');
for emp_row in emp_cur loop
dbms_output.put_line(emp_row.empno);
end loop;
end;
我感觉我的代码写的没有问题啊!
注意:这个游标是多表查询的结果集!
使用cursor的for循环不需要在之前打开光标,
但是必须说明cursor,也就是说这个cursor的说明不能是动态的。
可以
for xxx in (select * from tablename)
loop
xxx.colname...
end loop;
但是不支持 for xxx in 'select * from tablename'
for xxx in 这里只接受sql语句和cursor变量,不接受cursor指针 loop
所以你的调用是不正确的,LZ的这种情况,大概只能fetch了。
oracle好像只支持两种方式的cursor for
1、
cursor xxx is select * from tablename;
for aaa in xxx loop ... end loop;
2、
for aaa in (select * from tablename) loop ... end loop;
emp_cur Pac_Select_GZ.mycursor;
begin
Pac_Select_GZ.Pro_Select_GZ(emp_cur,'10','L');
for emp_row in emp_cur loop
dbms_output.put_line(emp_row.empno);
end loop;
end;唉...是你的FOR循环写的有问题. emp_row定义标量了么.
for循环的格式for i in 1..结果集的行数 loop
执行体
end loop;还有使用FOR循环游标打开和关闭是自动的不需要手动打开.