在单个参数中传递多个值

时间:2013-10-05 21:17:46

标签: sql postgresql stored-procedures parameter-passing plpgsql

我想通过在单个参数上传递多个值来调用函数,如下所示:

SELECT * FROM jobTitle('270,378');

这是我的功能。

CREATE OR REPLACE FUNCTION test(int)
RETURNS TABLE (job_id int, job_reference int, job_job_title text
                                            , job_status text) AS
$$
BEGIN
RETURN QUERY
select jobs.id,jobs.reference, jobs.job_title,
       ltrim(substring(jobs.status,3,char_length(jobs.status))) as status
FROM jobs ,company c
WHERE jobs."DeleteFlag" = '0'
and c.id= jobs.id and c.DeleteFlag = '0' and c.active = '1' 
and (jobs.id = $1 or -1 = $1)
order by jobs.job_title;
END;
$$ LANGUAGE plpgsql;

有人可以帮助解决语法问题吗?甚至提供示例代码?

2 个答案:

答案 0 :(得分:4)

不要做一些奇怪而可怕的事情,例如将整数列表转换为CSV字符串,这个:

jobTitle('270,378')

不是你想要的。你想说这样的话:

jobTitle(270, 378)
jobTitle(array[270, 378])

如果您打算手动拨打jobTitle,那么variadic function可能最容易使用:

create or replace function jobTitle(variadic int[])
returns table (...) as $$
    -- $1 will be an array if integers in here so UNNEST, IN, ANY, ... as needed

然后,您可以根据需要jobTitle(6)jobTitle(6, 11)jobTitle(6, 11, 23, 42),...

如果您要在SQL中构建jobTitle参数,那么显式数组版本可能更容易使用:

create or replace function jobTitle(int[])
returns table (...) as $$
    -- $1 will be an array if integers in here so UNNEST, IN, ANY, ... as needed

然后您可以jobTitle(array[6])jobTitle(array[6, 11]),......根据需要,您可以使用所有常用的array operators and functions来构建jobTitle的参数列表。

我将把函数的内部结构作为读者的练习。

答案 1 :(得分:4)

@mu already provided一样,VARIADIC是您的朋友。一个更重要的细节:

也可以直接使用带有数组类型的VARIADIC参数调用函数。在函数调用中添加关键字VARIADIC

SELECT * FROM  f_test(VARIADIC '{1,2,3}'::int[]);

相当于:

SELECT * FROM  f_test(1,2,3);

其他建议

  • 在Postgres 9.1 + right()中,长度更快更简单地修剪字符串中的前导字符:

    right(j.status, -2)
    

    相当于:

    substring(j.status, 3, char_length(jobs.status))
    
  • 您的查询中包含j."DeleteFlag"以及j.DeleteFlag(不带双引号)。 This is probably incorrect.

  • "DeleteFlag" = '0'表示另一个问题。与其他RDBMS不同,Postgres完全正确地支持boolean数据类型。 如果该标志包含布尔数据(是/否/可能为NULL),请使用boolean类型。 character type like text不合适。

  • 这里你不需要plpgsql。您可以使用更简单的SQL函数:

正常功能

所有这些放在一起,你的功能可能如下所示:

CREATE OR REPLACE FUNCTION f_test(VARIADIC int[])
  RETURNS TABLE (id int, reference int, job_title text, status text) AS
$func$

SELECT j.id, j.reference, j.job_title
      ,ltrim(right(j.status, -2)) AS status
FROM   company c
JOIN   job     j USING (id)
WHERE  c.active
AND    NOT c.delete_flag
AND    NOT j.delete_flag
AND   (j.id = ANY($1) OR '{-1}'::int[] = $1)
ORDER  BY j.job_title

$func$ LANGUAGE sql;

-> SQLfiddle demo.