如何在 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
第一种形式将您提供的数值乘以一个月的间隔。第二个构造一个指定月数的字符串,然后将其转换为一个间隔。
我使用带有 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
第一种形式将您提供的数值乘以一个月的间隔。第二个构造一个指定月数的字符串,然后将其转换为一个间隔。