将数组文字传递给PostgreSQL函数

时间:2013-06-16 23:48:10

标签: php sql arrays postgresql parameter-passing

我有一个包含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"

如何在PHP中格式化vcode文字以及该条件的语法应该是什么?

使用PostgreSQL 9.1.1,PHP 5.3.6,pg_query_params

1 个答案:

答案 0 :(得分:8)

SQL NOT IN适用于。由于您传入数组,请使用<> ALL

您必须格外小心,不要让任何NULL值包含此类表达式,因为NULL <> anything永远不会计算为TRUE,因此永远不会符合WHERE子句的条件

您的功能可能如下所示:

CREATE OR REPLACE FUNCTION get_questions(vcode text[])
  RETURNS TABLE(id int, title text, code text) AS
$func$

SELECT q.id, q.title, q.code
FROM   questions q
WHERE  q.code <> ALL ($1);

$func$ LANGUAGE sql;

呼叫:

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[]) ...

...并传递列表值:

SELECT * FROM get_questions('qcode2', 'qcode2');

详细说明:

主要观点:

  • 使用简单的SQL函数,因为您的问题中没有任何内容需要PL / pgSQL的过程元素。

  • 输入参数是一个文本数组:text[]

  • 要从查询中返回多行,请使用RETURNS TABLE作为返回类型。

  • 引用带有位置参数$1的in参数,因为通过名称引用仅在版本9.2中引入了SQL函数(与plpgsql函数相反,现在某些版本已经存在)。

  • 表限定列名,否则会与OUT子句中定义的同名RETURNS参数冲突。

LEFT JOIN unnest($1) / IS NULL

对于长数组更快(&gt; ~~ 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值。