PostgreSQL - 数组值必须以“{”或维度信息

时间:2016-02-25 16:08:10

标签: sql arrays postgresql any

我正在尝试创建一个函数,该函数将在提供的文本数组中基于ANY进行过滤。该函数引发了以下内容:“错误:当尝试在pgplsql函数中执行查询时,数组值必须以”{“或维度信息”开头。当在查询窗口中运行确切的SQL语句时,查询工作正常。

以下说明了简化示例的问题。

鉴于表格定义:

CREATE TABLE b
(
    id serial NOT NULL,
    item_id character varying(2) NOT NULL,
    CONSTRAINT b_pkey PRIMARY KEY (id)
);

样本数据:

id  item_id
1      A
2      B
3      D
4      T
5      G
6      T
7      B

功能:

CREATE OR REPLACE FUNCTION get_item_ids() RETURNS integer[] AS
$BODY$DECLARE
    qry text;
    ids integer[];
    items text[];
BEGIN
    items := ARRAY['A','B','C']::text[];
    qry := format('SELECT id FROM b WHERE item_id = ANY(%L)', items);
    raise notice '%', qry;
    execute qry into ids;
    raise notice 'ids:%', ids;
    return ids;
END$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

运行该功能时,将生成以下输出:

NOTICE:  SELECT id FROM b WHERE item_id = ANY('{A,B,C}')

ERROR:  array value must start with "{" or dimension information
CONTEXT:  PL/pgSQL function get_item_ids() line 9 at EXECUTE statement

********** Error **********
ERROR: array value must start with "{" or dimension information
SQL state: 22P02
Context: PL/pgSQL function get_item_ids() line 9 at EXECUTE statement

将“SELECT id FROM b WHERE item_id = ANY('{A,B,C}')”语句复制并粘贴到查询窗口中会产生以下预期结果:

id integer
   1
   7
   2

我尝试了很多其他选项,包括类型转换,不同的引用,以及使用array_to_string和unexst函数。任何人都可以解释发生了什么,并建议一个可行的替代方案吗?

2 个答案:

答案 0 :(得分:3)

在你的函数中尝试这个语句:

EXECUTE 'SELECT ARRAY(SELECT id FROM b WHERE item_id = ANY($1))' INTO ids USING items;
  • 使用USING安全地执行动态语句。此方法最好将数据值作为文本插入命令字符串(使用format)。
  • 您需要使用ARRAY构造函数包装返回的行以生成integer[](或重构您的函数以返回SETOF integer,如果这是什么 你真的想要。)。

答案 1 :(得分:0)

给出以下功能:

CREATE OR REPLACE FUNCTION get_item_ids(items text[]) RETURNS integer[] AS
$BODY$
BEGIN
    RETURN ARRAY(SELECT id FROM b WHERE item_id = ANY (items));
END
$BODY$
LANGUAGE plpgsql VOLATILE;

以下查询:

SELECT get_item_ids('{"A",  "B"}'::text[])

显示:

{1,2,7}

另一方面,功能:

CREATE TYPE id_record AS (id integer);

CREATE OR REPLACE FUNCTION get_item_ids2(text[]) RETURNS SETOF id_record AS
$BODY$
 SELECT id FROM b WHERE item_id = ANY ($1);
$BODY$
LANGUAGE SQL VOLATILE;

查询:

SELECT id FROM get_item_ids2('{"A",  "B"}'::text[])

给你:

+----+
| Id |
+----+
|  1 |
|  2 |
|  7 |
+----+