sql >> Databasteknik >  >> RDS >> Oracle

Oracle Table Function från CTE

När du hanterar Objects du är extra försiktig när du gör select . Det fanns fel i din kod som ledde till problem. Jag är inte heller säker på om direkt tilldelning som utförs nedan faktiskt är tillåten:

rec := PART_TEST(record);

Men jag föreslår två lösningar här. Först med Pipeline och andra utan det. Se nedan:

--Tabell- och objektförberedelser

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;
/

--Funktion med Pipeline

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;
/

Resultat:

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

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

--utan pipeline

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;
/

Resultat:

SQL> Select * from table (part_test_f(1));

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

Välj det som passar dig men vi känner alla till fördelarna med att använda Pipeline fungerar därför som skulle vara bäst lämpad.




  1. Kombinera fält från olika rader på skick

  2. MySql skillnad mellan två tidsstämplar i sekunder?

  3. Använder OUTPUT-satsen för att infoga värde som inte är INSERTED

  4. Oracle som lösning på muterande tabeller