19

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

4

1 回答 1

30

SQLNOT IN适用于集合。由于您要传递一个数组,请使用<> 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}');

或者(带有数组构造函数的替代语法):

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返回类型。

使用位置参数引用 in 参数,$1因为按名称引用仅在 9.2 版中针对 SQL 函数引入(与现在某些版本已经存在的 plpgsql 函数相反)。

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

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 值。

于 2013-06-17T02:44:42.503 回答