PL / SQL Функция - Групповой сбор в ряды труб - PullRequest
0 голосов
/ 11 июля 2020

Я новичок в PL / SQL у меня проблема с выходным значением функции.

Я хочу выполнить оператор SQL в функции и вернуть результаты. Функция будет выполнена с помощью следующей команды: select * from table(mypkg.execute_query('1'));

Я использовал следующую статью в качестве ссылки «Bulk Collect Into» и «Execute Immediate» в Oracle, но безуспешно.

Кажется, я использую неправильный тип данных. Система возвращает ошибку в следующей строке: PIPE Row(results)

create or replace package mypkg
as 
    type node is table of edges%ROWTYPE;
    function execute_query (startNode in varchar2) RETURN node PIPELINED;
end;


create or replace package body mypkg
as
   function execute_query(startNode in varchar2) RETURN node PIPELINED
    AS
        results node;
        my_query VARCHAR2(100);
        output VARCHAR2(1000);
        c sys_refcursor;
    BEGIN
        my_query := 'SELECT DISTINCT * FROM EDGES WHERE src='|| startNode;
        
        open c for my_query;
        loop
            fetch c bulk collect into results limit 100;
            exit when c%notfound;
                PIPE Row(results);
        end loop;
        close c;
    END;
end;

Я пробовал несколько вариантов с курсором, но не смог вернуть значение. Если у вас есть идея, как вернуть данные с помощью чего-то еще, кроме PIPELINED, дайте мне знать.

Спасибо за вашу поддержку!

1 Ответ

2 голосов
/ 11 июля 2020

Фиксированное тело:

create or replace package body mypkg
as
   function execute_query(startNode in varchar2) RETURN node PIPELINED
    AS
        results node;
        my_query VARCHAR2(100);
        output VARCHAR2(1000);
        c sys_refcursor;
    BEGIN -- don't use concatenation, it leads to sql injections:
        my_query := 'SELECT DISTINCT * FROM EDGES WHERE src=:startNode';
        -- use bind variables and bind them using cluase "using":
        open c for my_query using startNode;
        loop
            fetch c bulk collect into results limit 100;
            -- "results" is a collection, so you need to iterate it to pipe rows:
            for i in 1..results.count loop
                PIPE Row(results(i));
            end loop;
            exit when c%notfound;
        end loop;
        close c;
    END;
end;
/
...