使用带有IN()的多值参数

时间:2017-05-08 10:38:44

标签: postgresql parameter-passing filtering

我使用多值(逗号分隔)参数作为过滤器在我的where子句中使用IN()时遇到了这个postgres函数的问题。

CREATE FUNCTION company_sites_report( company_list text )
  RETURNS TABLE(company text, num_suppliers BIGINT)
LANGUAGE SQL
AS $$

SELECT company, count(supplier_id) num_suppliers
FROM MySitesTable
WHERE company IN ($1)
GROUP BY company;

$$; 

所以当我调用函数时:

SELECT * 
FROM company_sites_report( 'Company1,Company2' );

似乎将参数值视为一个完整的字符串,而不是将其拆分为特定的字符串(csv)。我如何让它按照我的需要行事?

2 个答案:

答案 0 :(得分:4)

考虑using VARIADIC,例如:

t=# CREATE FUNCTION f1( a variadic text[] )
  RETURNS TABLE(t text)
LANGUAGE SQL
AS $$

SELECT tablename::text
FROM pg_tables
WHERE tablename = ANY ($1)
;
$$;

示例:

t=# select * from f1('so4','s111','so2');
  t
------
 so2
 so4
 s111
(3 rows)

答案 1 :(得分:2)

您正在传递字符串,因此条件将其用作单个值。

您需要将公司名称作为数组传递:

CREATE FUNCTION company_sites_report( company_list text[] )
  RETURNS TABLE(company text, num_suppliers BIGINT)
LANGUAGE SQL
AS $$

SELECT company, count(supplier_id) num_suppliers
FROM MySitesTable
WHERE company = ANY ($1)
GROUP BY company;
$$; 

select *
from company_sites_report(array['Company1', 'Company2']);

或将逗号分隔的字符串转换为过程中的数组:

CREATE FUNCTION company_sites_report( company_list text)
  RETURNS TABLE(company text, num_suppliers BIGINT)
LANGUAGE SQL
AS $$

SELECT company, count(supplier_id) num_suppliers
FROM MySitesTable
WHERE company = ANY (string_to_array($1, ','))
GROUP BY company;
$$; 

select *
from company_sites_report('Company1,Company2');

我更喜欢第一种解决方案,因为您不必担心包含分隔符的公司名称