将数组文字传递给 PostgreSQL 函数
Posted
技术标签:
【中文标题】将数组文字传递给 PostgreSQL 函数【英文标题】:Pass array literal to PostgreSQL function 【发布时间】:2013-06-12 21:24:07 【问题描述】:我有一个包含 select 语句的 Postgres 函数。我需要使用包含字符串值数组的传入变量添加条件。
CREATE OR REPLACE FUNCTION get_questions(vcode text)
RETURN return_value as $f$
DECLARE vresult return_value;
BEGIN
--snip--
SELECT id, title, code
FROM questions WHERE code NOT IN (vcode);
--snip--
questions
表:
id ,title, code
1, "title1", "qcode1"
2, "title2", "qcode2"
3, "title3", "qcode3"
4, "title4", "qcode4"
vcode
文字在 php 中应该如何格式化,条件的语法应该是什么?
使用 PostgreSQL 9.1.1、PHP 5.3.6、pg_query_params
。
【问题讨论】:
PostgreSQL 和 PHP 版本?您使用的是 PDO 还是pg_
函数?
@CraigRinger 我正在使用 pg_ 函数。 pg_query_params($db, $SQL, $input)
@user2254435:PostgreSQL and PHP versions
的哪一部分不清楚?
@CraigRinger Postgres 9.1.1,PHP 5.3.6
@user2254435 好吧,首先,您很容易受到重大安全漏洞的影响,请更新。 postgresql.org/support/security/faq/2013-04-04
【参考方案1】:
SQL NOT IN
与 sets 一起使用。由于您要传递一个数组,因此请使用<> ALL
。
您必须小心不要将任何NULL
值与此类表达式相关联,因为NULL <> anything
永远不会计算为TRUE
,因此永远不会在WHERE
子句中限定。
您的函数可能如下所示:
CREATE OR REPLACE FUNCTION get_questions(vcode text[])
RETURNS TABLE(id int, title text, code text)
LANGUAGE sql AS
$func$
SELECT q.id, q.title, q.code
FROM questions q
WHERE q.code <> ALL ($1);
$func$;
呼叫:
SELECT * FROM get_questions('qcode2, qcode2');
或者(带有array constructor 的替代语法):
SELECT * FROM get_questions(ARRAY['qcode2', 'qcode2']);
或者您可以使用VARIADIC
参数:
CREATE OR REPLACE FUNCTION get_questions(VARIADIC vcode text[]) ...
... 并传递一个 list 值:
SELECT * FROM get_questions('qcode2', 'qcode2');
详情:
Return rows matching elements of input array in plpgsql function要点:
使用简单的 SQL 函数,因为您的问题中没有任何内容需要 PL/pgSQL 的过程元素。
输入参数是一个文本数组:text[]
要从查询中返回多行,请使用 RETURNS TABLE
作为返回类型。
使用位置参数 $1
引用 in 参数,因为按名称引用仅在 9.2 版中针对 SQL 函数引入(与现在在某些版本中已经存在的 plpgsql 函数相反)。
表限定列名,否则会与RETURNS
子句中定义的同名参数OUT
冲突。
LEFT JOIN unnest($1)
/ IS NULL
长数组更快(> ~ 80 个元素,视情况而定):
SELECT q.id, q.title, q.code
FROM questions q
LEFT JOIN unnest($1) c(code) USING (code)
WHERE c.code IS NULL;
此变体(与上述不同)忽略输入数组中的 NULL 值。
【讨论】:
感谢您的回复。将 IN 列类型设置为“text[]”是我没有尝试过的。我以为我可以传入一组文本值,但显然不行。 @user2254435:如果您更容易将逗号分隔的字符串作为text
传递,您可以这样做,并使用string_to_array()
将其转换为函数内部的数组。如果您的列表很长,使用LEFT JOIN
/ IS NULL
的性能会更好。我在答案中添加了演示代码。
你可以使用WHERE q.code = ANY($1)
获取q.code IN [...]
的行为以上是关于将数组文字传递给 PostgreSQL 函数的主要内容,如果未能解决你的问题,请参考以下文章
在 Java 中创建一个 bytea 数组以传递给 Postgresql 存储过程
将数组值从 JPA/Hibernate 传递给 PostgreSQL
将表传递给 postgreSQL 函数,执行 select 语句,返回表