如何调用包中的函数

时间:2011-01-06 11:38:23

标签: sql database oracle plsql sys-refcursor

我正在做以下但是它不起作用

select package_name.function_name(param,param) from dual

我正在调用一个返回游标的函数,所以我猜测"from dual"就是问题

还有另一种方法吗?

3 个答案:

答案 0 :(得分:2)

我认为你的意思是参考光标。这是一个PL / SQL构造,它充当指向查询返回的一组记录的指针。这意味着它必须由运行查询的客户端解释。例如,我们可以将Ref Cursor映射到JDBC或ODBC ResultSet。

你的基本陈述当然没有错。这是一个类似于你自己的函数:

SQL> desc get_emps
FUNCTION get_emps RETURNS REF CURSOR
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 P_DNO                          NUMBER(2)               IN
 P_SORT_COL                     VARCHAR2                IN     DEFAULT
 P_ASC_DESC                     VARCHAR2                IN     DEFAULT

SQL> 

我可以在更广泛的PL / SQL块中轻松调用它:

SQL> declare
  2      rc sys_refcursor;
  3  begin
  4      rc := get_emps(50);
  5  end;
  6  /

PL/SQL procedure successfully completed.

SQL>

但是,SQL * PLus本身可以处理CURSOR结构:

SQL> select get_emps(50) from dual
  2  /

GET_EMPS(50)
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      8060 VERREYNNE  PLUMBER         8061 08-APR-08       4000                    50
      8061 FEUERSTEIN PLUMBER         7839 27-FEB-10       4500                    50
      8085 TRICHLER   PLUMBER         8061 08-APR-10       3500                    50
      8100 PODER      PLUMBER         8061                 3750                    50


SQL>

此语句也在SQL Developer中运行,尽管结果集以丑陋的方式布局。

因此,如果您的功能出现问题,那么问题是:

  1. 您使用的是哪种客户端环境?
  2. 以何种精确的方式“不起作用”?请描述观察到的行为,包括任何错误消息?
  3. 还提供环境详细信息,例如数据库版本,操作系统等。

  4. 在阅读了关于这个主题的其他问题后,我认为问题可能是由于使用了用户定义的参考光标(而不是内置的)。但是,这没有任何区别。这个打包的功能:

    SQL> create or replace package emp_rc_utils as
      2
      3      type emp_rc is ref cursor return emp%rowtype;
      4
      5      function       get_emps
      6          ( p_dno in emp.deptno%type
      7      )
      8      return emp_rc;
      9  end;
     10  /
    
    Package created.
    
    SQL> create or replace package body emp_rc_utils as
      2
      3      function       get_emps
      4          ( p_dno in emp.deptno%type
      5      )
      6          return emp_rc
      7      is
      8          return_value emp_rc_utils.emp_rc;
      9      begin
     10
     11          open return_value for select * from emp where deptno = p_dno;
     12
     13          return return_value;
     14      end get_emps;
     15
     16  end emp_rc_utils;
     17  /
    
    Package body created.
    
    SQL>
    

    仍然有效...

    SQL> declare
      2      rc sys_refcursor;
      3  begin
      4      rc := emp_rc_utils.get_emps(50);
      5  end;
      6  /
    
    PL/SQL procedure successfully completed.
    
    
    SQL> select emp_rc_utils.get_emps(50) from dual
      2  /
    
    EMP_RC_UTILS.GET_EMP
    --------------------
    CURSOR STATEMENT : 1
    
    CURSOR STATEMENT : 1
    
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
    ---------- ---------- --------- ---------- --------- ---------- ---------- ----------
          8085 TRICHLER   PLUMBER         8061 08-APR-10       3500                    50
          8060 VERREYNNE  PLUMBER         8061 08-APR-08       4000                    50
          8061 FEUERSTEIN PLUMBER         7839 27-FEB-10       4500                    50
          8100 PODER      PLUMBER         8061                 3750                    50
    
    
    SQL>
    

答案 1 :(得分:1)

您可以通过refcursor调用或填充用户定义的表来执行此操作,并按如下方式返回:

create or replace
function getRef return sys_refcursor
is
l_ref  sys_refcursor;
begin

    open l_ref for
    select 1 a, 'a' c from dual
    union all
    select 2 a, 'b' c from dual
    union all
    select 3 a, 'c' c from dual
    union all
    select 4 a, 'd' c from dual;

    return l_ref;

end getRef;
/

select getref() from dual;

GETREF() 
-------- 
A                      C  
---------------------- -  
1                      a  
2                      b  
3                      c  
4                      d  

--you'll notice this isn't the most user-friendly result set if you look at it in SQL Developer or whatno
--drop function getRef;

如果要传回一个表集合

,也可以使用'table'
create or replace type lookup_row as 
  object ( a number, c varchar2(20) );
  /
create or replace type lookups_tab as 
  table of lookup_row;
/

create or replace
function getUserDefinedTableType return lookups_tab
is
lTestTypeTable  lookups_tab;
begin

     SELECT lookup_row(a,c)
               bulk collect INTO lTestTypeTable
               from
    (select 1 a, 'a' c from dual
    union all
    select 2 a, 'b' c from dual
    union all
    select 3 a, 'c' c from dual
    union all
    select 4 a, 'd' c from dual);

    return lTestTypeTable;

end getUserDefinedTableType;
/


select * from table(getUserDefinedTableType());
--this returns it in a more user friendly manner
--http://www.oreillynet.com/pub/a/network/2003/01/22/feuerstein.html?page=2
--http://stackoverflow.com/questions/3150137/converting-oracle-query-into-user-defined-types-in-pl-sql/3152885#3152885
A                      C                    
---------------------- -------------------- 
1                      a                    
2                      b                    
3                      c                    
4                      d  

答案 2 :(得分:0)

你试过了吗?

myCursor := package_name.function_name(param,param);

这必须来自测试块或存储过程。