Как перенести конвейерную функцию оракула в PostgreSQL - PullRequest
0 голосов
/ 20 декабря 2018

Поскольку я новичок в plpgSQL,

Я застрял при переносе запроса Oracle в PostgreSQL.

Запрос Oracle:

create or replace FUNCTION employee_all_case(
   p_ugr_id IN integer,
   p_case_type_id IN integer
)
RETURN number_tab_t PIPELINED
--       LANGUAGE 'plpgsql'
--     COST 100
--     VOLATILE 
--     AS $$
--     DECLARE
is
  l_user_id        NUMBER;
  l_account_id     NUMBER;
BEGIN
  l_user_id      := p_ugr_id;
  l_account_id   := p_case_type_id;
  FOR cases IN
    (SELECT ccase.case_id, ccase.employee_id
     FROM ct_case ccase
       INNER JOIN ct_case_type ctype
         ON (ccase.case_type_id=ctype.case_type_id)
     WHERE ccase.employee_id = l_user_id)
  LOOP
    IF cases.employee_id IS NOT NULL THEN
      PIPE ROW (cases.case_id);
    END IF;
  END LOOP;
  RETURN;
END;
--$$

Когда я выполняю эту функцию,Я получаю следующий результат

select * from table(select employee_all_case(14533,1190) from dual)

enter image description here

Мой вопрос здесь: я действительно не понимаю конвейерную функцию и как я могу получить тот же результатв PostgreSQL как запрос Oracle?

Пожалуйста, помогите.

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

Конвейерные функции лучше всего переводить в простую функцию SQL, возвращающую таблицу.

Примерно так:

create or replace function employee_all_case(p_ugr_id integer, p_case_type_IN integer)
   returns table (case_id integer)
as
$$
  SELECT ccase.case_id
  FROM ct_case ccase
     INNER JOIN ct_case_type ctype ON ccase.case_type_id = ctype.case_type_id
  WHERE ccase.employee_id = p_ugr_id
    and cases.employee_id IS NOT NULL;
$$
language sql;

Обратите внимание, что в вашем примере кода не использовался второй параметр p_case_type_id.

Использование также более простое:

select * 
from employee_all_case(14533,1190);
0 голосов
/ 20 декабря 2018

Спасибо, ребята, ваше решение было очень полезным.

Я нашел желаемый результат:

-- select * from employee_all_case(14533,1190);

-- drop function employee_all_case

  create or replace FUNCTION employee_all_case(p_ugr_id IN integer ,p_case_type_id IN integer)
returns table (case_id double precision)
  -- PIPELINED
   LANGUAGE 'plpgsql'
COST 100
 VOLATILE 
 AS $$
 DECLARE
 -- is
  l_user_id        integer;
  l_account_id     integer;
BEGIN
  l_user_id      := cp_lookup$get_user_id_from_ugr_id(p_ugr_id);
  l_account_id   := cp_lookup$acctid_from_ugr(p_ugr_id);
  RETURN QUERY SELECT ccase.case_id
    FROM ct_case ccase
    INNER JOIN ct_case_type ctype ON ccase.case_type_id = ctype.case_type_id
    WHERE ccase.employee_id = p_ugr_id
    and ccase.employee_id IS NOT NULL; 
    --return NEXT;
END;
$$

enter image description here

0 голосов
/ 20 декабря 2018

Вы бы переписали это в установить возвращаемую функцию :

  • Измените тип возврата на

    RETURNS SETOF integer
    

    и покончите сPIPELINED.

  • Измените оператор PIPE ROW на

    RETURN NEXT cases.case_id;
    

Конечно, вам придется внести очевидные синтаксические измененияНапример, используя integer вместо NUMBER и ставя IN перед именем параметра.

Но на самом деле для этого нет необходимости писать функцию.Выполнение этого в одном выражении SELECT будет проще и быстрее.

...