如何在 for 循环内实现执行命令 - postgres, dbeaver

How to implement execute command inside for loop - postgres, dbeaver

我是 postgres 的新手。我需要创建一个函数,该函数将获取数据库中名称存储在一个 table 中的所有 table 的列表,然后删除所有 table 的记录超过 x 天并且有一定的 row_status。有些 table 没有 row_status 列。 当我尝试在 dbeaver 中保存编写的函数时出现错误 -> 错误:“||”处或附近的语法错误

create function delete_old_records1(day1 int, row_status1 character default null, row_status2 character default null)
returns void 
language plpgsql
as $$
declare 
    c all_tables1%rowtype; 
begin
    
    
            for c in select * from all_tables1 loop 
                if exists(SELECT column_name FROM  information_schema.columns 
                WHERE  table_schema = 'yard_kondor' AND  table_name =c.table_name AND  column_name = 'row_status') then 
                    execute 'delete from '||c.table_name||' where row_create_datetime>current_date-day1+1 and 
                    row_status in (coalesce(row_status1,''P''), row_status2)'; 
                else 
                    execute 'delete from '||c.table_name||' where row_create_datetime>current_date-day1+1'; 
                    raise notice 'Table '||c.table_name||' does not have row_status column'; 
                end if; 
            end loop;       
        return; 
    commit;
end; 
$$

你的直接问题是这一行:

raise notice 'Table '||c.table_name||' does not have row_status column'; 

should be:

raise notice 'Table % does not have row_status column', c.table_name; 

不过,您的功能还有待改进。一般来说,强烈建议使用 format() 生成动态 SQL 以正确处理标识符。您也不能在函数中使用 commit。如果您真的需要,请使用程序。

create function delete_old_records1(day1 int, row_status1 character default null, row_status2 character default null)
returns void 
language plpgsql
as $$
declare 
    c all_tables1%rowtype; 
begin
  for c in select * from all_tables1 
  loop 
    if exists (SELECT column_name FROM  information_schema.columns 
               WHERE table_schema = 'yard_kondor' 
                 AND table_name = c.table_name 
                 AND column_name = 'row_status') then 
      execute format('delete from %I 
                      where row_create_datetime > current_date - %J + 1 
                      and row_status in (coalesce(row_status1,%L), row_status2)', c.table_name, day1, 'P'); 
    else 
      execute format('delete from %I where row_create_datetime > current_date - day1 + 1', c.table_name); 
      raise notice 'Table % does not have row_status column', c.table_name; 
    end if; 
  end loop;       
  return; 
  -- you can't commit in a function
end; 
$$

谢谢您的回答。现在我可以保存函数了,但是目前我遇到了 运行 函数的问题。

我用以下函数启动了函数:

DO $$ BEGIN
    PERFORM "delete_old_records1"(31,'P','N');
END $$;

我用 ALT+X 启动了脚本(也试过 select delete_old_records1(31,'P','N');)并出现了这个错误:

SQL错误[42703]:错误:列“day1”不存在 其中: PL/pgSQL function delete_old_records1(integer,character,character) line 11 at EXECUTE statement SQL 语句“SELECT “delete_old_records1”(31,'P','N')” PL/pgSQL 函数 inline_code_block 第 2 行在 PERFORM