我正在尝试创建一个函数,该函数将在提供的文本数组中基于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函数。任何人都可以解释发生了什么,并建议一个可行的替代方案吗?
答案 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 |
+----+