【问题标题】:Pass multiple values in single parameter在单个参数中传递多个值
【发布时间】:2013-10-12 17:27:31
【问题描述】:

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

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;

有人可以帮忙语法吗?甚至提供示例代码?

【问题讨论】:

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


    【解决方案1】:

    VARIADIC

    喜欢@mu providedVARIADIC 是你的朋友。还有一个重要的细节:

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

    SELECT * FROM  f_test(<b>VARIADIC</b> '{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(不带双引号)。这可能是不正确的。见:

    "DeleteFlag" = '0' 表示另一个问题。与其他 RDBMS 不同,Postgres 正确地支持 boolean 数据类型。如果标志包含 boolean 数据(true / false / NULL),则使用 boolean 类型。 character type like text 不合适/效率低下。

    适当的功能

    这里不需要 PL/pgSQL。您可以使用更简单的 SQL 函数:

    CREATE OR REPLACE FUNCTION f_test(VARIADIC int[])
      RETURNS TABLE (id int, reference int, job_title text, status text)
      LANGUAGE sql 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$;
    

    db小提琴here
    sqlfiddle

    【讨论】:

    • 谢谢@Erwin Brandstetter
    【解决方案2】:

    不要做奇怪和可怕的事情,比如将整数列表转换为 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 构建参数列表。

    我将把函数的内部作为练习留给读者。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-05
      • 2012-10-27
      • 1970-01-01
      • 2017-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多