如何在函数中动态使用传递的模式名称?

How to use passed schema name dynamically in a function?

我有一个名为 list_customers 的函数,将 i_entity_id, i_finyear 作为输入参数。模式名称是从 i_finyear 构建的,我需要根据给定的模式执行查询。

我尝试了以下代码:

CREATE OR REPLACE FUNCTION list_customers(i_entity_id integer,
i_finyear integer) 
RETURNS TABLE(entity_id integer, client_id
integer, financial_yr integer) LANGUAGE 'plpgsql' AS 
$BODY$
declare finyear integer := i_finyear; 
    schema_1 text := 'tds'||''||i_finyear;
begin 
    set search_path to schema_1;
return query select
d.entity_id, d.client_id, d.financial_yr
from schema_1.deductor d where d.entity_id = 1331;
end; 
$BODY$;

然后:

select tds2020.list_customers(1331,2022);
   

imagelink

你需要动态 SQL 和 EXECUTE:

CREATE OR REPLACE FUNCTION list_customers(i_entity_id int, i_finyear int)
  RETURNS TABLE (entity_id int, client_id int, financial_yr int)
  LANGUAGE plpgsql AS
$func$
BEGIN
   RETURN QUERY EXECUTE 
     'SELECT d.entity_id, d.client_id, d.financial_yr
      FROM   tds' || i_finyear || '.deductor d
      WHERE  d.entity_id = '
   USING i_entity_id;
END
$func$;

由于输入参数 i_finyearinteger 类型,因此不存在 SQL 注入的危险,您可以使用普通连接来连接您的架构名称,例如 “tbl2016”。否则,您将使用 format() 来防御它。参见:

  • Table name as a PostgreSQL function parameter

可以 也连接(正确引用),但使用 [=15 传递值更安全、更高效=] 关键字。参见:

无需另外更改 search_path 。那只会增加一个昂贵的上下文切换。