尝试在 PostgreSQL 函数中执行动态 CTE

问题描述 投票:0回答:1

我正在尝试创建一个 Postgresql 函数,它将动态构建 CTE 并执行它来进行存档/清除。

上下文:主表中的记录必须归档到相应的归档表中,然后定期从原表中删除。为此,tbl_archive_master 表具有原始表 (from_tbl_name)、存档表 (arch_tbl_name) 和用于执行存档和清除的 where 条件 (where_clause) 的列。

下面是函数,但它似乎没有执行CTE...

CREATE OR REPLACE FUNCTION some_f() 
RETURNS text
AS
$func$
DECLARE
  r record;
  q text;
BEGIN
   for r in
        select concat(from_tbl_schema,'.',from_tbl_name)::text as main_t_name, concat(arch_schema,'.',arch_tbl_name)::text as  arch_t_name, where_clause::text
        from axis.tbl_archive_master t
        where t.from_tbl_name = 'tbl_req_tracking_arch' and t.arch_tbl_name='tbl_req_tracking_arch2'
   loop
    q := format('with deleted_rows as (delete from %s where %s returning * ) insert into %s select deleted_rows.* from deleted_rows ;',r.main_t_name, r.where_clause, r.arch_t_name);
    raise notice '%', q;
    execute q;  -- this line fails
   end loop;
   perform 'end';
END;
$func$
language plpgsql;

...即使“RAISE NOTICE”显示它已填充良好。


Axis=# select some_f();
NOTICE:  with deleted_rows as (delete from axis.tbl_req_tracking_arch where "CREATE_DATE" <= (current_date - 30) returning * ) insert into axis.tbl_req_tracking_arch2 select deleted_rows.* from deleted_rows ;
ERROR:  control reached end of function without RETURN
CONTEXT:  PL/pgSQL function some_f()

但是如果我直接运行cte,它运行得很好。在下面的情况下,axis.tbl_req_tracking_arch 中没有记录可供存档和清除。

Axis=# with deleted_rows as (delete from axis.tbl_req_tracking_arch where "CREATE_DATE" <= (current_date - 30) returning * ) insert into axis.tbl_req_tracking_arch2 select deleted_rows.* from deleted_rows ;
INSERT 0 0
Axis=#
postgresql function common-table-expression dynamic-sql
1个回答
0
投票

PostgreSQL 并不像您想象的那样抱怨

EXECUTE
行,而是抱怨缺少返回
RETURN
text
语句。另一方面,你的
PERFORM
声明没有做任何有用的事情。也许你想说的是

RETURN 'end';

而不是

PERFORM 'end';

后一条语句仅运行

SELECT 'end';
,然后丢弃结果。

© www.soinside.com 2019 - 2024. All rights reserved.