如何调用包中的函数

Posted

技术标签:

【中文标题】如何调用包中的函数【英文标题】:How to call a function in a package 【发布时间】:2011-01-06 11:38:23 【问题描述】:

我正在执行以下操作,但它不起作用

select package_name.function_name(param,param) from dual

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

还有其他方法吗?

【问题讨论】:

“它不起作用”是什么意思 - 你得到什么错误?包装规范中如何定义您的“光标”?如果它是 sys_refcursor 并且该函数没有任何令人不快的副作用,那么从 dual 中选择应该可以工作... 我猜这个问题与您之前的问题有关:***.com/questions/4613973/… 不要发布您关于同一主题的问题。如果您没有得到满意的答案,请立即编辑您的问题以提供更多详细信息。 【参考方案1】:

我想你的意思是一个参考光标。这是一个 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 中运行,尽管结果集以一种的方式布局。

所以,如果您的功能有问题,问题是:

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

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

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>

【讨论】:

感谢您的帖子 APC,但我是新手,我不明白您建议我应该做什么 大多数情况下,您需要提供更多关于您现在正在做什么以及它是如何失败的详细信息。 APC 已证明它在原则上有效,因此您需要向我们提供足够的信息来帮助您找出问题所在。 @user521180 - 我的意思是:你想要做的事情应该起作用。因此,如果您遇到错误,它一定是特定于您的实现的东西。你需要回到你的代码并弄清楚。或在此处发布更多详细信息,以便我们为您发现。【参考方案2】:

您可以通过 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;

如果您要传回一个表格集合,您也可以使用“表格”

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://***.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  

【讨论】:

您能否多解释一下这两种解决方案是什么以及它们在做什么。【参考方案3】:

你试过了吗:

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

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

【讨论】:

以上是关于如何调用包中的函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在 R 包中正确使用其他包中的函数

调用包中的过程或函数

如何构造一个使用 Python 中其他包中的函数的函数?

通过 :: 调用包中的函数是一种好习惯吗

使用 evaluateJavaScript(..) 调用 javascript 函数,以读取应用程序包中的文本文件

YAMLException:找不到类试图调用不在模型包中的类的构造函数