Как вызвать функцию в пакете - PullRequest
3 голосов
/ 06 января 2011

Я делаю следующее, но это не работает

select package_name.function_name(param,param) from dual

Я вызываю функцию, которая возвращает курсор, поэтому я предполагаю, "from dual" это проблема

есть ли другаяспособ сделать это?

Ответы [ 3 ]

2 голосов
/ 06 января 2011

Полагаю, вы имеете в виду Ref Cursor.Это конструкция 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. Также сообщите нам подробности среды, такие как версия базы данных, ОС и т. Д.

Прочитав ваш другой вопрос по этой теме, я подумал, что проблема может бытьиз-за использования пользовательского Ref Cursor (а не встроенного).Однако это не имеет никакого значения.Эта упакованная функция:

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 голос
/ 06 января 2011

Вы можете сделать это с помощью вызова 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://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  
0 голосов
/ 06 января 2011

пытались ли вы:

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

это должно быть внутри тестового блока или хранимой процедуры.

...