如何在 postgres 动态 SQL 中使用引用字符串中的变量

How to use variable inside quoted string in postgres dynamic SQL

我使用带有 3 个参数的 plpgsql 创建了以下函数。

CREATE OR REPLACE FUNCTION public.most_service_calls(
    comp_id integer,
    calls integer,
    months integer)
    RETURNS TABLE(state character varying, city character varying, cust_name character varying, num_calls bigint, cost numeric) 
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
    ROWS 1000
AS $BODY$

Begin
return query execute                   

'select * from 
(select l.state, l.city, l.cust_name, count(distinct a.svc_ord_nbr) num_calls, 
  round(avg(a.std_labr_net_amt_dcrncy) + avg(a.travel_net_amt_dcrncy), 2)
    from dmt_mas_svc_ord_fact a
    inner join dmt_mas_cust_dim b on a.shipto_cust_id = b.cust_id
    inner join store_location l on b.cust_name = l.cust_name
    inner join company co on b.cust_lvl_2_nbr = co.company_nbr
    where b.sap_sls_org_name like ''%Stanley US%''
       and a.create_dtm >= now() - interval ''  months''
       and co.company_id = 
    group by l.state, l.city, l.cust_name
    order by l.state, l.city, l.cust_name ) q
 where num_calls >= '
 using comp_id, calls, months;

 end;

$BODY$;

由于查询被引用,所有单引号字符串都被双引号。三个变量分别用表示。导致问题的是字符串中的变量。 a.create_dtm >= now() - interval '' months''

当我 运行 函数时,它似乎忽略了我提供的任何第三个参数。因此,以下所有return结果相同。

select * from most_service_calls(1,5,1)
select * from most_service_calls(1,5,12)
select * from most_service_calls(1,5,24)

事实证明,'' '' 中的 被视为 3,因为结果与查询中硬编码的 3 months 匹配。

在这样的引用查询中,将变量包含在字符串中的正确方法是什么?

您的问题不是动态 SQL 特有的 - 即使在正常的 SQL 查询中,您也不能引用带引号的字符串中的占位符。

您可以使用:

 * interval '1 month'

或:

( || ' months')::interval

第一种形式将您提供的数值乘以一个月的间隔。第二个构造一个指定月数的字符串,然后将其转换为一个间隔。