CTE的Oracle表功能

时间:2018-12-04 14:34:54

标签: oracle function plsql common-table-expression

我想通过以下查询在oracle中创建表函数:

 WITH A AS (
    SELECT * FROM PART_TABLE WHERE PART_NO LIKE part_num
 )
SELECT * FROM A;

'part_num'是传递给函数的参数。我在语法上遇到麻烦。这是我尝试过的:

CREATE OR replace FUNCTION part_test_f(search_part IN varchar2)
RETURN part_test_t PIPELINED 
AS 

    rec PART_TEST;

    CURSOR cur(part_num) IS 
         WITH A AS (
            SELECT * FROM PART_TABLE WHERE PART_NO LIKE part_num
         )
        SELECT * FROM A;
BEGIN
        FOR record IN cur(search_part) LOOP
        rec := PART_TEST(record);
        pipe row(rec);
        END LOOP;
return;
END;

我已经创建了表和行的类型。感谢您的帮助。

编辑:我又给了它一次。声明现在看起来像:

    create or replace FUNCTION part_test_f(search_part IN varchar2)
RETURN part_test_t PIPELINED
AS

    rec PART_TEST;

    CURSOR cur(part_num varchar2) RETURN PART_TEST IS
         WITH A AS (
            SELECT * FROM F6RD_PART WHERE PART_NO LIKE part_num
         )
        SELECT * FROM A;
BEGIN
        FOR rec IN cur(search_part) LOOP
        pipe row(rec);
        END LOOP;
return;
END;

现在我收到“没有更多数据要从套接字读取”错误

1 个答案:

答案 0 :(得分:2)

在处理Objects时,您要格外谨慎。您的代码中存在错误,导致出现问题。同样也不确定是否可以直接进行以下直接分配:

select

但是我在这里提出2种解决方案。首先带rec := PART_TEST(record);,其他不带。见下文:

-表和对象准备

Pipeline

-具有管道功能

CREATE TABLE part_table (
    part_no   NUMBER,
    col1      NUMBER
);

INSERT INTO PART_TABLE VALUES(1,11);
INSERT INTO PART_TABLE VALUES(1,33);
INSERT INTO PART_TABLE VALUES(2,22);

SELECT * FROM PART_TABLE;

CREATE OR REPLACE TYPE part_test IS OBJECT (
    part_no   NUMBER,
    col1      NUMBER
);

CREATE OR REPLACE TYPE part_test_t IS  TABLE OF part_test;
/

结果:

CREATE OR replace FUNCTION part_test_f(search_part IN number)
RETURN part_test_t PIPELINED 
AS 

 rec part_test; --<--Variable of type Object since we want to piperow.

 CURSOR cur(part_num number) IS 
      WITH A AS 
      (       --Make sure you cast your select statement of object type    
              SELECT part_test(PART_NO,col1) FROM PART_TABLE WHERE PART_NO LIKE part_num
       )
       SELECT * FROM A;        
BEGIN        
   OPEN cur(search_part) ;
    LOOP
      Fetch cur into rec;    --<-- Note here am not using `Bulk Collect` even though its being a collection since we are `piping` the rows.    
      exit when cur%NOTFOUND;
       pipe row(rec);         
    END LOOP;
RETURN ;
END;
/

-无管道

SQL> SELECT * FROM TABLE (PART_TEST_F(1));

     PART_NO       COL1
    ---------- ----------
      1            11
      1            33

结果:

CREATE OR REPLACE FUNCTION part_test_f (search_part IN NUMBER) 
RETURN part_test_t 
 AS
    rec   part_test_t;
    CURSOR cur ( part_num NUMBER) IS 
    WITH a AS 
    ( SELECT part_test( part_no,col1 )
       FROM part_table
       WHERE part_no LIKE part_num       
    ) 
    SELECT *  FROM a;
BEGIN
    OPEN cur(search_part);
    LOOP
        FETCH cur BULK COLLECT INTO rec;
        EXIT WHEN cur%notfound;      
    END LOOP;
    RETURN rec;
END;
/

选择最适合您的一个,但我们都知道使用SQL> Select * from table (part_test_f(1)); PART_NO COL1 ---------- ---------- 1 11 1 33 函数的优点,因此最适合。