我的代码如下,一般是进入 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; 

解决方案 »

  1.   

    它报 emp_cur "不是存储过程或尚未定义"但是我如果这样写的话就行了,我怀疑是不是我的游标变量没有赋值进去啊:
    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;
    这样是没有问题的。。
      

  2.   

    我觉得是emp_cur Pac_Select_GZ.mycursor;这一句并没有给游标实例化。declare 
    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;     
      

  3.   

    --测试表
    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
      

  4.   


     6 楼的方法我试过了,还是包 emp_cur "不是过程或尚未定义" 7 楼写的游标结构是只有一列 "open rst for select * from curTest;--返回curTest的内容 ",而我的游标结构是两张表的联合查询, 所以你的方法行不通,感谢各位的探讨,继续等待正解~!
      

  5.   

    一列都知道了,再加一列就不会了?
    动态游标与你几张表没有关系,返回的是一个查询的结果集
    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;
      

  6.   

    测试了,一列是没有问题的,“select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,dept.deptno from emp
                                  left join dept on emp.deptno = dept.deptno”我的列是这么多,那不是我要写很多列来接收游标?
      

  7.   

    for emp_row in emp_cur loop
    end loop;
    这种语句是用于隐式游标上的,它实际的操作过程是open emp_cur ,然后fetch emp_cur所有的记录,最后是close emp_cur ,而楼主在这条语句之前又open了一次emp_cur,因此会出错。
      

  8.   

    那你的意思是我在存储过程中 不 open 游标?
     那我怎么样将游标结构赋值到 mycursor 上呢?
      

  9.   

    如果想用隐式游标,那么就不要用
    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
    这种方法了
      

  10.   

    楼上的方法我知道,现在的问题就是
     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 中调用出来。当然如果有更好的方法,我会选择好的方法的!  看来我给的分是不够了,要加分了!
      

  11.   

    在存储过程中只需要open cursor for...就可以返回一个结果集了
    在Java中用ResultSet接收这个结果集
      

  12.   

    我现在就是想用隐式游标来实现我的功能:存储过程返回一个游标,此游标可在 java 中调用出来,也可在 PL/SQL 中调用出来。当然如果有更好的方法,我会选择好的方法的!  看来我给的分是不够了,要加分了!
      

  13.   

    在 JAVA 中可以正确的测试返回的游标, 我现在就是在 PL/SQL 中有疑问,因为在存储过程中我已经 open 一次游标了,那么我在 PL sql 块中就不需要 open
    ,那就只有用 loop fetch.. end loop。 问题就出在这里, 我  fetch into 的时候要将游标的结构 fetch 到一个结构中,我的游标结构是一个双表查询,那么我接受此游标就需要顶一个一个 type 来接收此游标,我想找到这个 type 要怎么样定义?
      

  14.   

    在package中定义: type ftType as recode(XXX VARCHAR2...);
    只要你事先知道游标的字段树木和类型,楼主的问题并不难解决。
      

  15.   

    定义类型报错,是不是 recode 这个关键字啊
      

  16.   

    我是这样定义的:type ftType as recode(empno VARCHAR2(40),ename VARCHAR2(40),job VARCHAR2(40),mgr VARCHAR2(40),hiredate VARCHAR2(40),deptno number(10)); 它报:Compilation errors for PACKAGE SCOTT.PAC_SELECT_GZError: PLS-00103: 出现符号 "RECODE"在需要下列之一时:
            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));
      

  17.   

    在package中定义如下:
    TYPE RtnRcd IS RECORD (
          A VARCHAR2(100),
          B VARCHAR2(100));
    在packagebody中直接使用这个类型即可。
      

  18.   


    你这个方法还是不行哟! 我按照你的重新建了一个 type ,但是当我把游标 fetch 到这个类型时,报错:RECORD 不能作为 fetch/select 的赋值目标。如果真的没有解决我这样的办法,那我真的要放弃????
      

  19.   

    看看这个,写得比较简单。
    由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;
      

  20.   

    为什么一定要“fetch into 的时候要将游标的结构 fetch 到一个结构中”,fetch到多个变量也可以啊.
    难道不fetch到一个结构中,不能完成业务?
      

  21.   

    1,根据select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,dept.deptno from emp
                                  left join dept on emp.deptno = dept.deptno
     建视图vv
    2,然后游标:cursor emp_cur is select * from vv where ....;
    3,然后fetch到vv的rowtype就OK了 
      

  22.   

    http://blog.csdn.net/zhpsam109/archive/2008/03/25/2215490.aspx
      

  23.   

    http://blog.csdn.net/zhpsam109/archive/2006/02/23/607021.aspx
      

  24.   


    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!
      

  25.   


     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;
    我感觉我的代码写的没有问题啊!
    注意:这个游标是多表查询的结果集!
      

  26.   

    据我的记忆,这种调用的方法不正确。
    使用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了。
      

  27.   

    刚才查了一下Onlinebook
    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;
      

  28.   

    “存储过程名称' 不是过程或尚未定义”OracleCommand的Parameters集合中的参数个数与存储过程中定义的数量不一致,你可能漏了某个Parameter没有创建
      

  29.   

    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;唉...是你的FOR循环写的有问题. emp_row定义标量了么.
    for循环的格式for i in 1..结果集的行数 loop
    执行体
    end loop;还有使用FOR循环游标打开和关闭是自动的不需要手动打开.