Рекурсивный в Postgresql 12,2 - PullRequest
0 голосов
/ 29 апреля 2020

Я использую инструмент Ora2Pg для перехода с Oracle на Postgresql. Мой oracle код

for rec_site in (select regexp_substr(p_site, '[^,]+', 1, level) site
                     from dual
            connnect by regexp_substr(p_site, '[^,]+', 1, level) is not null) 
loop

Инструмент преобразует этот коннект в предыдущий сценарий postgresql.

for rec_site in (WITH RECURSIVE cte AS (
             select (SELECT array_to_string(a, '') FROM regexp_matches(p_site, '[^,]+', 'g') AS foo(a) LIMIT 1 OFFSET (level - 1)) site

             (SELECT array_to_string(a, '') FROM regexp_matches(p_site, '[^,]+', 'g') AS foo(a) LIMIT 1 OFFSET (level - 1)) is not null  

UNION ALL

             select (SELECT array_to_string(a, '') FROM regexp_matches(p_site, '[^,]+', 'g') AS foo(a) LIMIT 1 OFFSET (level - 1)) site

             SELECT array_to_string(a, '') FROM regexp_matches(p_site, '[^,]+', 'g') AS foo(a) LIMIT 1 OFFSET (level - 1)) is not null JOIN cte c ON ()
) SELECT * FROM cte;
) loop

Этот код выдает синтаксическую ошибку. отсутствует "L OOP" в конце выражения SQL.

1 Ответ

0 голосов
/ 29 апреля 2020

Это действительно плохой перевод для взлома в Oracle (и еще раз показывает, что автоматический c перевод процедурного кода очень часто приводит к большему количеству работы, чем ручной перевод)

Оригинал Oracle запрос - это способ разбить список с разделителями на строки. Это можно сделать намного проще в Postgres:

select *
from unnest(string_to_array(p_site, ',')) as t(site)

Так что вы можете использовать это:

for rec_site in select *
                from unnest(string_to_array(p_site, ',')) as t(site)
                where site is not null
loop
   ....
end loop;

Это можно еще больше упростить, перебирая массив напрямую:

foreach site in array string_to_array(p_site, ',')
loop
  ...
end loop;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...