如何在 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
我是 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