【问题标题】:Oracle: Return multiple values in a functionOracle:在函数中返回多个值
【发布时间】:2012-06-06 04:08:21
【问题描述】:

我正在尝试从使用两个表(员工和部门)的函数返回 %rowtype 中的多个值,但它对我不起作用。

create or replace function get_employee
 (loc in number)
return mv_emp%rowtype
as  
   emp_record mv_emp%rowtype;
begin
   select a.first_name, a.last_name, b.department_name into emp_record 
   from employees a, departments b 
   where a.department_id=b.department_id and location_id=loc;

   return(emp_record);  
end;

【问题讨论】:

    标签: sql oracle function plsql views


    【解决方案1】:

    上面的函数编译没有任何错误? MV_EMP 的类型是什么?理想情况下,它应该如下所示。

    create or replace type emp_type
    (
    first_name varchar2(20)
    , last_name varchar2(20)
    , depart_name varchar2(20)
    )
    /
    create or replace function get_employee
     (loc in number)
    return emp_type
    as  
       emp_record emp_type;
    begin
       select a.first_name, a.last_name, b.department_name into emp_record 
       from employees a, departments b 
       where a.department_id=b.department_id and location_id=loc;
    
       return(emp_record);  
    end;
    

    【讨论】:

    • 在我的 oracle 版本 11g 中,当这样指定时,类型声明不会编译。我必须声明类型为对象
    • 我还必须编写这个语法(在 11g 中):SELECT x.some_field, y.something_else INTO myobject.field1, myobject.field2 FROM ...
    • 我还必须先初始化对象,如下所示:myobject mytype := mytype('', '');
    • 谢谢@andersand。我在 10g 中做到了这一点并且成功了。
    【解决方案2】:
    create type t_row as object (a varchar2(10));
    
    create type t_row_tab as table of t_row;
    

    我们现在将创建一个分割输入字符串的函数。

    create or replace function get_number(pv_no_list in varchar2) return t_row_tab is
    lv_no_list t_row_tab := t_row_tab();
    begin
    
      for i in (SELECT distinct REGEXP_SUBSTR(pv_no_list, '[^,]+', 1, LEVEL) no_list FROM dual
      CONNECT BY REGEXP_SUBSTR(pv_no_list, '[^,]+', 1, LEVEL) IS NOT NULL)
      loop
      lv_no_list.extend;
      lv_no_list(lv_no_list.last) := t_row(i.no_list);
      end loop;
    
      return lv_no_list;
    
    end get_number;
    

    一旦函数到位,我们就可以使用 sql 语句的 table 子句来获得所需的结果。根据需要,我们从函数中返回了多个值。

    SQL> select * from table(get_number('1,2,3,4'));
    
    
    A
    ----------
    1
    3
    2
    4
    

    所以现在我们的函数只是表现得像一张桌子。可能存在您希望这些逗号分隔值成为“IN”子句的一部分的情况。

    例如:

    select * from dummy_table where dummy_column in ('1,2,3,4');
    

    但上面的查询将不起作用,因为 '1,2,3,4' 是一个字符串,而不是单个数字。要解决这个问题,您可以简单地使用以下查询。

    select * from dummy_table where dummy_column in ( select * from table(get_number('1,2,3,4')) );
    

    参考:http://www.oraclebin.com/2012/12/returning-multiple-values-from-function.html

    【讨论】:

      【解决方案3】:
      CREATE OR replace FUNCTION Funmultiple(deptno_in IN NUMBER)
        RETURN NUMBER AS v_refcursur SYS_REFCURSOR;
        BEGIN
          OPEN v_refcursor FOR
          SELECT *
          FROM   emp
          WHERE  deptno = deptno_in;
          
          retun v_refcursor;
        END;
      

      要调用它,请使用:

      variable x number
      exec :x := FunMultiple(10);
      print x 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-14
        • 1970-01-01
        相关资源
        最近更新 更多