2017-01-16 44 views
0

我得到错误:的Oracle PL/SQL:功能光标

PLS-00231: function 'GET_NUM' may not be used in SQL

时执行以下代码

;

CREATE OR REPLACE PACKAGE BODY TESTJNSABC IS 

    -- FUNCTION IMPLEMENTATIONS 
    FUNCTION get_num(num IN NUMBER) 
    RETURN SYS_REFCURSOR AS 
    my_cursor SYS_REFCURSOR; 
    BEGIN 
    -- 
    OPEN my_cursor FOR 
    WITH ntable AS (
     SELECT 1 ID, 111 AGT, 'ABC' DESCRIP FROM DUAL 
     UNION ALL 
     SELECT 2 ID, 222 AGT, 'ABC' DESCRIP FROM DUAL 
     UNION ALL 
     SELECT 1 ID, 333 AGT, 'ABC' DESCRIP FROM DUAL 
    ) 
    SELECT AGT FROM ntable WHERE ID = num; 
    RETURN my_cursor; 

    END; 

    -- PROCEDURE IMPLEMENTATIONS 
    PROCEDURE testingabc AS 

    BEGIN 
     WITH xtable AS (
     SELECT 111 AGT, 'A' DESCRIP FROM DUAL 
     UNION ALL 
     SELECT 222 AGT, 'B' DESCRIP FROM DUAL 
     UNION ALL 
     SELECT 333 AGT, 'C' DESCRIP FROM DUAL 
    ) 
     SELECT DESCRIP FROM xtable WHERE COD_AGT IN get_num(1); 


    END testingabc; 

END TESTJNSABC; 

即使我将该函数调用为TESTJNSABC.get_num(1)我仍然会得到相同的错误。 --UPDATE。所以在现实生活中,我想从WHERE CLAUSE调用函数;该函数应该返回一组NUMBER值(这就是我使用IN子句的原因)。

+1

您这里有一些问题。如果你能解释你想要这些程序做什么,那么帮助你会容易些。 – Aleksej

+3

错误似乎很清楚?你不能在SQL语句中使用你的函数,你只能从其他PL/SQL上下文中调用它(至少直到12c)。 –

+1

您不能使用以这种方式返回引用游标的函数。它通常用于在PL/SQL中传递结果集指针的上下文中。你可以接近,但你需要使用流水线功能,而不知道你想要的答案,包括那是毫无意义的。 – BriteSponge

回答

0

in()要求或者一个子查询或逗号分隔值的列表,这样不行,你不能代替返回集合的函数。

假设函数在SQL查询的范围内(它可以是独立函数,也可以在包规范中声明),您可以在table()构造中使用它(这需要一个表函数,即它需要返回一个集合,不是光标):

where somecol in (select column_value from table(get_num(1))) 

(或等值内连接等)

演示在livesql.oracle.com/apex/livesql/file/content_EF2M0F1LV9LTP6PEII3BDFKAI.html

编辑:我刚刚注意到了问题的例子试图用一个REF CURSO河请注意,table()运算符用于集合,而不是ref游标。因此函数必须返回一个集合类型(嵌套表或varray)。

+0

这不起作用。我的确如你所说的那样。你能否演示一次演示 – XING

+0

添加到[LiveSQL演示]的链接(https://livesql.oracle.com/apex/livesql/file/content_EF2M0F1LV9LTP6PEII3BDFKAI.html)。 –

+0

当我用'SELECT DESCRIP FROM xtable WHERE AGT IN(从表中选择column_value(get_num(1))'替换'SELECT DESCRIP FROM xtable WHERE COD_AGT IN get_num(1);'时,它不在上面示例中的plsql块中工作) ' – XING

1

So is it possible then to create a variable on the Procedure and assign the Function values to the variable? Let's say

它不应该是一个问题,不管它是否可能,而应该是如果这是正确的方式。当然,你可以像你所做的那样去做,但正如专家建议的那样,这不是正确和有效的方式。看你如何做到这一点。 PS:未测试。

CREATE OR REPLACE PACKAGE BODY TESTJNSABC IS 

    -- FUNCTION IMPLEMENTATIONS 
    FUNCTION get_num(num IN NUMBER) 
    RETURN SYS_REFCURSOR AS 
    my_cursor SYS_REFCURSOR; 
    BEGIN 
    -- 
    OPEN my_cursor FOR 
    WITH ntable AS (
     SELECT 1 ID, 111 AGT, 'ABC' DESCRIP FROM DUAL 
     UNION ALL 
     SELECT 2 ID, 222 AGT, 'ABC' DESCRIP FROM DUAL 
     UNION ALL 
     SELECT 1 ID, 333 AGT, 'ABC' DESCRIP FROM DUAL 
    ) 
    SELECT AGT FROM ntable WHERE ID = num; 
    RETURN my_cursor; 

    END; 

    -- PROCEDURE IMPLEMENTATIONS 
    PROCEDURE testingabc AS 
    --Creating a collection to hold return of the function 
    type y is table of varchar2(1000) index by pls_integer; 
    var_z y; 
    var_1 varchar2(100); 

    BEGIN 

    Select get_num(1) 
    bulk collect into var_z 
    from dual; 

    For i in 1..var_z.count 
    loop 

    WITH xtable AS (
     SELECT 111 AGT, 'A' DESCRIP FROM DUAL 
     UNION ALL 
     SELECT 222 AGT, 'B' DESCRIP FROM DUAL 
     UNION ALL 
     SELECT 333 AGT, 'C' DESCRIP FROM DUAL 
    ) 
     SELECT DESCRIP 
     into var_1 
     FROM xtable 
     WHERE AGT = var_z(i) ; ---Check each record 

     dbms_output.put_line(var_1); 

    end loop; 

    END testingabc; 

END TESTJNSABC; 
+0

感谢@XING的帮助。执行此操作的最佳实践(更有效的方法)是什么? –

+0

您可以查看骨科医生建议的内容。 – XING

0

按@William罗伯逊回答,我试图实施该解决方案,但得到的问题:

[Error] ORA-22905 (18: 26): PL/SQL: ORA-22905: cannot access rows from a non-nested table item

-- FUNCTION IMPLEMENTATIONS 
create or replace FUNCTION get_num(num IN NUMBER) 
    RETURN SYS_REFCURSOR AS 
    my_cursor SYS_REFCURSOR; 
    BEGIN 
    -- 
    OPEN my_cursor FOR 
    SELECT AGT 
    FROM ntable 
    WHERE ID = num; 

    RETURN my_cursor; 

    END; 

- 过程实现

CREATE OR REPLACE PROCEDURE testingabc 
AS 
type var is table of xtable.DESCRIP%type;  
v_var var;  
BEGIN 
    SELECT DESCRIP 
    bulk collect into var 
    FROM xtable 
    WHERE AGT IN (SELECT COLUMN_VALUE 
        FROM TABLE (get_num (1))); 
END testingabc; 
+0

'table()'操作符对集合不起作用。我错过了原来的问题试图用ref cursor来做这件事。在我的回答中添加了一个注释。 –

+0

这就是我的想法。因为我从来没有见过这样的事情,并且如果发生这种事情更有兴趣学习.. – XING