如何在 PostgreSQL 中使用 'in' 运算符将 varchar 转换为 int[]

How to cast a varchar into an int[] using 'in' operator in PostgreSQL

我很难过。 我正在尝试将包含数字列表的 varchar 转换为 int array,以便在 where 子句上为 in 运算符提供服务。 这是我的代码的最后一个版本。

create or replace function is_product_in_categories (
    _product_id integer,
    _cat_list   varchar
)
returns boolean
as $$
declare
    _n integer;
begin
    _n = 0;

    select count(*) 
    into _n
    from category_products 
    where product_id = _product_id and category_id in (_cat_list::int[]);

  return _n > 0;
end;
$$ language plpgsql;


select is_product_in_categories(1, '1, 2, 3');

错误是

 SQL Error [42883]: ERROR: operator does not exist: integer = integer[]
  Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
  Where: PL/pgSQL function is_product_in_categories(integer,character varying) line 7 at SQL statement

我试过几个参数,如'1, 2, 3''(1, 2, 3)''[1, 2, 3]'。同时删除 in 运算符附近的括号等

有什么想法吗?

使用string_to_array()将字符串转换为(文本)数组:

SELECT string_to_array('1, 2, 3', ', ')::int[]; -- use ::int[] to cast to an int array
+---------------+
|string_to_array|
+---------------+
|{1,2,3}        |
+---------------+

如果您控制字符串(例如您自己构造它),您可以使用这两个中的任何一个:

SELECT ARRAY[1, 2, 3]      -- no need to cast this one
     , '{1, 2, 3}'::int[]; -- you have to specify that it's an array, not simply a string value
+-------+-------+
|array  |int4   |
+-------+-------+
|{1,2,3}|{1,2,3}|
+-------+-------+

in 运算符的问题是它不接受数组作为参数。相反,它需要一个简单的标量列表。请在此处查看 PostgreSQL 文档 https://www.postgresql.org/docs/9.0/functions-comparisons.html#AEN16964

为了避免这种限制,= any 组合接受一个数组作为参数。 代码就这样结束了。

create or replace function is_product_in_categories (
  _product_id integer,
  _cat_list   varchar
)
returns boolean
as $$
declare
  _n integer;
begin
  _n = 0;

  select count(*) 
  into _n
  from of_category_products 
  where product_id = _product_id and category_id = any (_cat_list::int[]);

  return _n > 0;
end;
$$ language plpgsql;

select is_product_in_categories(1, '{1, 2, 3}')

此外,在 Bergi 评论之后,已经观察到使用 {} 的文字数组语法。

修改函数声明并定义为可变整数数组:

create or replace function is_product_in_categories (
    _product_id integer,
    Variadic _cat_list  integer[] )
    

或者作为整数数组:

create or replace function is_product_in_categories (
_product_id integer,
_cat_list  integer[] )

无论哪种方式,您都可以将函数缩减为单个语句。

create or replace function is_product_in_categories3 (
    _product_id integer,
      _cat_list integer[]
)
returns  boolean
language sql
as $$
    select 
      exists (select null 
               from category_products
              where product_id = _product_id and category_id = any(_cat_list)
             ); 
$$; 

有关两者的完整示例,请参阅 here