如何将Oracle存储过程包装在由标准SELECT查询执行的函数中?

时间:2009-05-14 17:37:12

标签: oracle stored-procedures function

我正在执行这些步骤,但我仍然遇到错误并且没有看到问题:

1)创建一个自定义Oracle数据类型,表示要检索的数据库列:

CREATE TYPE my_object AS OBJECT
     (COL1       VARCHAR2(50),
      COL2       VARCHAR2(50),
      COL3       VARCHAR2(50));

2)创建另一个数据类型,它是您刚刚创建的对象的表:


    TYPE MY_OBJ_TABLE AS TABLE OF my_object;

3)创建一个返回该表的函数。还使用管道子句,以便将结果流水线化回调用SQL,例如:


    CREATE OR REPLACE
    FUNCTION MY_FUNC (PXOBJCLASS varchar2)
    RETURN MY_OBJ_TABLE pipelined IS
    TYPE ref1 IS REF CURSOR
    Cur1 ref1,
    out_rec_my_object := my_object(null,null,null);
    myObjClass VARCHAR2(50);
    BEGIN
    myObjClass := PXOBJCLASS
    OPEN Cur1 For ‘select PYID, PXINSNAME, PZINSKEY from PC_WORK where PXOBJCLass = ;1’USING myObjClass,
    LOOP
        FETCH cur1 INTO out_rec.COL1, out_rec.COL2, out_rec.COL3;
        EXIT WHEN Cur1%NOTFOUND;
        PIPE ROW (out_rec);
    END LOOP;
    CLOSE Cur1;
    RETURN;
    END MY_FUNC; 

注意:在上面的示例中,您可以通过调用另一个返回游标变量的存储过程轻松替换select语句。

4)在您的应用程序中,使用以下SQL语句将此函数作为表函数调用:

select COL1, COL2, COL3 from TABLE(MY_FUNC('SomeSampletask'));

3 个答案:

答案 0 :(得分:1)

没有必要使用动态sql(动态sql总是有点慢)并且声明了太多变量。 for循环也更容易。我将函数的参数从pxobjclass重命名为p_pxobjclass。

试试这个:

create or replace function my_func (p_pxobjclass in varchar2)
return my_obj_table pipelined
is 
begin
  for r_curl in (select pyid,pxinsname,pzinskey 
                 from   pc_work
                 where  pxobjclass = p_pxobjclass) loop
    pipe row (my_object(r_curl.pyid,r_curl.pxinsname,r_curl.pzinskey));          
  end loop;
  return; 
end; 

<强> EDIT1:

返回引用游标而不是返回嵌套表的流水线函数的方式更快:

create or replace function my_func2 (p_pxobjclass in varchar2)
return sys_refcursor
is 
  l_sys_refcursor sys_refcursor; 
begin
  open l_sys_refcursor for 
    select pyid,pxinsname,pzinskey 
    from   pc_work
    where  pxobjclass = p_pxobjclass;
  return l_sys_refcursor;  
end;

这更快,因为创建对象(my_object)需要一些时间。

答案 1 :(得分:0)

我看到两个问题:

  1. 动态查询无法正常运行,请尝试以下方法:

    '从PC_WORK中选择PYID,PXINSNAME,PZINSKEY,其中PXOBJCLass ='''|| PXOBJCLASS ||'''

  2. 你不需要myObjClass,似乎所有引号都错了。

    1. 引用'SomeSampletask'......

      从TABLE中选择COL1,COL2,COL3(MY_FUNC('SomeSampletask'));

答案 2 :(得分:0)

也许我在这里误解了一些东西,但似乎你想要使用VIEW。