如何在 plpgsql 中执行 WHERE x IN (val1, val2,...)

Dav*_*ave 3 postgresql plpgsql array

我想更新表中的行选择;这有效...

UPDATE t1 SET col1 = 'newvalue' WHERE col0 in (2, 4, 5);
Run Code Online (Sandbox Code Playgroud)

但是我怎么能在 plpgsql 函数中做同样的事情呢?下面给出了一个语法错误...

CREATE OR REPLACE FUNCTION foo(intarray int[])
RETURNS VOID AS 
$BODY$

BEGIN
  UPDATE t1 SET col1 = 'newvalue'
  WHERE col0 in intarray;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
Run Code Online (Sandbox Code Playgroud)

错误...

ERROR:  syntax error at or near "intarray"
LINE 7:       WHERE col0 in intarray;
Run Code Online (Sandbox Code Playgroud)

编辑:

如果我们更换in intarray;in (intarray);的功能被记录,但在运行时SELECT * FROM foo(ARRAY[1,3,5])的误差变...

ERROR:  operator does not exist: integer = integer[]
LINE 2:       WHERE col0 in (intarray)
Run Code Online (Sandbox Code Playgroud)

Cra*_*ger 5

IN (...) 需要一个字面值列表。

如果您编写,x IN (some_array)那么 PostgreSQLx也希望是一个数组,因为您正在测试该数组是否x出现在数组的单元素列表中(some_array)

如果您想查看该值是否x显示为数组元素,则some_array必须编写:

x = ANY (some_array)
Run Code Online (Sandbox Code Playgroud)

(请注意,您可以使用ANY与几乎所有的运营商,而不仅仅是=,而且有一个ALL,以及一个ANY。)


Erw*_*ter 5

@a_horse 已经指出:使用x = ANY (array_value)而不是x IN (set of values). 阅读关于 的手册ANY

对于长数组(100 多个元素,视情况而定),可以更快地unnest()加入。使用VARIADIC函数可能更方便:

CREATE OR REPLACE FUNCTION foo(VARIADIC intarray int[])
  RETURNS void AS 
$func$
BEGIN
  UPDATE t1
  SET    col1 = 'newvalue'
  FROM   unnest (intarray) a(elem)
  WHERE  t1.col0 = a.elem;
END
$func$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

然后你可以调用该函数:

SELECT foo(1,2,3);
Run Code Online (Sandbox Code Playgroud)

但是您仍然可以提交整个数组:

SELECT foo(VARIADIC intarray := '{1,2,3}');
Run Code Online (Sandbox Code Playgroud)

此处此处的手册中的详细信息。