具有 IN 条件的存储过程语法

Stored procedure syntax with IN condition

(1)

=>CREATE TABLE T1(id BIGSERIAL PRIMARY KEY, name TEXT);
CREATE TABLE

(2)

=>INSERT INTO T1
(name) VALUES
('Robert'),
('Simone');
INSERT 0 2

(3)

SELECT * FROM T1;
 id |  name  
----+--------
  1 | Robert
  2 | Simone
(2 rows)

(4)

CREATE OR REPLACE FUNCTION test_me(id_list BIGINT[]) 
RETURNS BOOLEAN AS
$$
BEGIN
  PERFORM * FROM T1 WHERE id IN ();
  IF FOUND THEN
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;
END;
$$
  LANGUAGE 'plpgsql';
CREATE FUNCTION

我的问题是在调用过程时。我无法在网上找到一个示例来说明如何传递 BIGINT(或整数)类型的值列表。

我尝试了以下方法但没有成功(语法错误):

第一种语法:

eway=> SELECT * FROM test_me('{1,2}'::BIGINT[]);
ERROR:  operator does not exist: bigint = bigint[]
LINE 1: SELECT * FROM T1 WHERE id IN ()
                                  ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
QUERY:  SELECT * FROM T1 WHERE id IN ()
CONTEXT:  PL/pgSQL function test_me(bigint[]) line 3 at PERFORM

第二种语法:

eway=> SELECT * FROM test_me('{1,2}');
ERROR:  operator does not exist: bigint = bigint[]
LINE 1: SELECT * FROM T1 WHERE id IN ()
                                  ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
QUERY:  SELECT * FROM T1 WHERE id IN ()
CONTEXT:  PL/pgSQL function test_me(bigint[]) line 3 at PERFORM

第三种语法:

eway=> SELECT * FROM test_me(ARRAY [1,2]);
ERROR:  operator does not exist: bigint = bigint[]
LINE 1: SELECT * FROM T1 WHERE id IN ()
                                  ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
QUERY:  SELECT * FROM T1 WHERE id IN ()
CONTEXT:  PL/pgSQL function test_me(bigint[]) line 3 at PERFORM

关于有效语法的任何线索?

这就像解析器试图在 PEFORM REQUEST 中将 BIGINT 转换为 BIGINT[],但这对我来说没有任何意义...

检查某个项目是否在数组中的最简单方法是 = ANY:

CREATE OR REPLACE FUNCTION test_me(id_list BIGINT[]) 
RETURNS BOOLEAN AS
$$
BEGIN
  PERFORM * FROM T1 WHERE id = ANY ();
  IF FOUND THEN
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;
END;
$$
LANGUAGE 'plpgsql';

你传递数组的所有语法变体都是正确的

  • Pass array literal to PostgreSQL function

问题出在函数内部的表达式上。您可以使用 ANY construct like 或许多其他语法变体进行测试。在任何情况下 运行 使用 EXISTS 表达式的测试:

CREATE OR REPLACE FUNCTION test_me(id_list bigint[]) 
  RETURNS bool AS
$func$
BEGIN
   IF EXISTS (SELECT 1 FROM t1 WHERE id = ANY ()) THEN
      RETURN true;
   ELSE
      RETURN false;
   END IF;
END
$func$ LANGUAGE plpgsql STABLE;

备注

  • EXISTS最短效率最高:

    • PL/pgSQL checking if a row exists - SELECT INTO boolean
  • 应用于数组的 ANY 结构仅对小数组有效。对于 更长的数组 ,其他语法变体更快。喜欢:

    IF EXISTS (SELECT 1 FROM unnest() id JOIN t1 USING (id)) THEN ...
    
  • 不要引用语言名称,它是标识符,不是字符串:LANGUAGE plpgsql

简单变体

当您返回 boolean 值时,它可以更简单。它可能只是为了演示,但作为概念证明:

CREATE OR REPLACE FUNCTION test_me(id_list bigint[]) 
  RETURNS bool AS
$func$
SELECT EXISTS (SELECT 1 FROM t1 WHERE id = ANY ())
$func$ LANGUAGE sql STABLE;

相同的结果。