我正在尝试创建一个 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 并不像您想象的那样抱怨
EXECUTE
行,而是抱怨缺少返回 RETURN
的 text
语句。另一方面,你的 PERFORM
声明没有做任何有用的事情。也许你想说的是
RETURN 'end';
而不是
PERFORM 'end';
后一条语句仅运行
SELECT 'end';
,然后丢弃结果。