在Postgresql 12.2中递归

时间:2020-04-29 11:44:10

标签: postgresql

我正在使用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

这段代码给我语法错误。 SQL表达式末尾缺少“ LOOP”。

1 个答案:

答案 0 :(得分:0)

对于Oracle中的黑客来说,这是一个非常糟糕的翻译(并且再次显示,过程代码的自动翻译通常比人工翻译需要更多的工作)

原始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;