Postgres 函数 return 每个模式删除的行数
Postgres function to return number of rows deleted per schema
我正在尝试将 Postgres 存储过程改编为函数,以便向调用者提供一些反馈。
该过程有条件地删除特定模式中的行,我希望该函数执行相同的操作,而且 return 每个模式删除的行数。
原来的存储过程是:
create or replace procedure clear_tenants()
language plpgsql as $function$
declare
tenant text;
begin
for tenant in
select tenant_schema
from public.tenant_schema_mappings
loop
execute format($ex$
delete from %I.parent
where expiration_date_time < now()
$ex$, tenant);
end loop;
end
$function$;
我目前转换成一个函数是:
CREATE OR REPLACE FUNCTION testfun()
RETURNS TABLE(tsname varchar, amount numeric) AS
$BODY$
declare
tenant text;
trow record;
BEGIN
for tenant in
select tenant_schema
from public.tenant_schema_mappings
loop
execute format($ex$
WITH deleted AS (
delete from %I.parent
where expiration_date_time < now()
IS TRUE RETURNING *
)
tsname := tenant;
amount := (SELECT * FROM deleted;);
return next;
$ex$, tenant);
end loop;
END
$BODY$ language plpgsql;
这可能在各方面都是错误的。我真的很困惑。
使用 SELECT * FROM testfun()
执行此操作时,出现以下错误:
ERROR: syntax error at or near "tsname"
LINE 7: tsname := tenant;
^
QUERY:
WITH deleted AS (
delete from anhbawys.parent
where expiration_date_time < now()
IS TRUE RETURNING *
)
tsname := tenant;
amount := (SELECT * FROM deleted;);
return next;
CONTEXT: PL/pgSQL function testfun() line 9 at EXECUTE
SQL state: 42601
很明显我没有正确分配行的列,但我不确定如何分配。
我发现 this question 看起来很相似,但我的理解有点复杂。
如果答案像您的问题一样简单,那么有一个系统目录。
select schemaname , count(n_tup_del)
from pg_catalog.pg_stat_all_tables psat
group by schemaname
您可以使用 get diagnostics(noddy 函数来表达我的观点)
create or replace function delfunc()
returns void
as $$
declare
affected_rows int ;
begin
delete from atable where a > 998 ;
GET DIAGNOSTICS affected_rows = ROW_COUNT;
insert into logtable values(affected_rows);
end $$
language plpgsql
您可以在 DELETE 语句后使用 GET DIAGNOSTICS 来获取删除的行数:
CREATE OR REPLACE FUNCTION testfun()
RETURNS TABLE(tsname varchar, amount bigint) AS
$BODY$
declare
tenant text;
BEGIN
for tenant in
select tenant_schema
from tenant_schema_mappings
loop
execute format(
'delete from %I.parent
where expiration_date_time < now()', tenant);
tsname := tenant;
GET DIAGNOSTICS amount := ROW_COUNT;
return next;
end loop;
END
$BODY$
language plpgsql;
我正在尝试将 Postgres 存储过程改编为函数,以便向调用者提供一些反馈。
该过程有条件地删除特定模式中的行,我希望该函数执行相同的操作,而且 return 每个模式删除的行数。
原来的存储过程是:
create or replace procedure clear_tenants()
language plpgsql as $function$
declare
tenant text;
begin
for tenant in
select tenant_schema
from public.tenant_schema_mappings
loop
execute format($ex$
delete from %I.parent
where expiration_date_time < now()
$ex$, tenant);
end loop;
end
$function$;
我目前转换成一个函数是:
CREATE OR REPLACE FUNCTION testfun()
RETURNS TABLE(tsname varchar, amount numeric) AS
$BODY$
declare
tenant text;
trow record;
BEGIN
for tenant in
select tenant_schema
from public.tenant_schema_mappings
loop
execute format($ex$
WITH deleted AS (
delete from %I.parent
where expiration_date_time < now()
IS TRUE RETURNING *
)
tsname := tenant;
amount := (SELECT * FROM deleted;);
return next;
$ex$, tenant);
end loop;
END
$BODY$ language plpgsql;
这可能在各方面都是错误的。我真的很困惑。
使用 SELECT * FROM testfun()
执行此操作时,出现以下错误:
ERROR: syntax error at or near "tsname"
LINE 7: tsname := tenant;
^
QUERY:
WITH deleted AS (
delete from anhbawys.parent
where expiration_date_time < now()
IS TRUE RETURNING *
)
tsname := tenant;
amount := (SELECT * FROM deleted;);
return next;
CONTEXT: PL/pgSQL function testfun() line 9 at EXECUTE
SQL state: 42601
很明显我没有正确分配行的列,但我不确定如何分配。
我发现 this question 看起来很相似,但我的理解有点复杂。
如果答案像您的问题一样简单,那么有一个系统目录。
select schemaname , count(n_tup_del)
from pg_catalog.pg_stat_all_tables psat
group by schemaname
您可以使用 get diagnostics(noddy 函数来表达我的观点)
create or replace function delfunc()
returns void
as $$
declare
affected_rows int ;
begin
delete from atable where a > 998 ;
GET DIAGNOSTICS affected_rows = ROW_COUNT;
insert into logtable values(affected_rows);
end $$
language plpgsql
您可以在 DELETE 语句后使用 GET DIAGNOSTICS 来获取删除的行数:
CREATE OR REPLACE FUNCTION testfun()
RETURNS TABLE(tsname varchar, amount bigint) AS
$BODY$
declare
tenant text;
BEGIN
for tenant in
select tenant_schema
from tenant_schema_mappings
loop
execute format(
'delete from %I.parent
where expiration_date_time < now()', tenant);
tsname := tenant;
GET DIAGNOSTICS amount := ROW_COUNT;
return next;
end loop;
END
$BODY$
language plpgsql;