将数组文字传递给PostgreSQL函数

Dev*_*evR 6 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--
Run Code Online (Sandbox Code Playgroud)

questions 表:

id ,title, code
1, "title1", "qcode1"
2, "title2", "qcode2"
3, "title3", "qcode3"
4, "title4", "qcode4"
Run Code Online (Sandbox Code Playgroud)

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

使用PostgreSQL 9.1.1,PHP 5.3.6 , pg_query_params.

Erw*_*ter 11

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;
Run Code Online (Sandbox Code Playgroud)

呼叫:

SELECT * FROM get_questions('{qcode2, qcode2}');
Run Code Online (Sandbox Code Playgroud)

或者(使用数组构造函数的替代语法):

SELECT * FROM get_questions(ARRAY['qcode2', 'qcode2']);
Run Code Online (Sandbox Code Playgroud)

或者您可以使用VARIADIC参数:

CREATE OR REPLACE FUNCTION get_questions(VARIADIC vcode text[]) ...
Run Code Online (Sandbox Code Playgroud)

...并传递值列表:

SELECT * FROM get_questions('qcode2', 'qcode2');
Run Code Online (Sandbox Code Playgroud)

细节:

主要观点:

  • 使用简单的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;
Run Code Online (Sandbox Code Playgroud)

此变体(与上面相反)忽略输入数组中的NULL值.