带有FOREACH循环的PostgreSQL PL / pgSQL语法错误

时间:2019-03-13 05:50:00

标签: postgresql plpgsql

我正在尝试通过编写一些简单程序来学习PL / pgSQL。为了了解FOREACH循环,我编写了以下内容:

CREATE OR REPLACE FUNCTION test(int[]) RETURNS void AS $$  
DECLARE                                                     
    window INT;                                             
BEGIN                                                       
    FOREACH window IN ARRAY $1                              
    LOOP                                                    
        EXECUTE 'SELECT $1' USING window;                   
    END LOOP;                                               
$$ LANGUAGE plpgsql;                                        

SELECT test(ARRAY [30,60]);    

我希望此代码段将首先打印30,然后打印60。但是,出现以下错误。

psql:loop.sql:11: ERROR:  syntax error at end of input
LINE 7:         EXECUTE 'SELECT $1' USING window;
                                                ^
psql:loop.sql:13: ERROR:  function test(integer[]) does not exist
LINE 1: SELECT test(ARRAY [30,60]);
               ^
HINT:  No function matches the given name and argument types. You might need
 to add explicit type casts.

所以函数定义有一个语法错误,但是我不明白错误是什么以及如何解决。我将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

您的函数被声明为returns void,因此您无法从中返回任何内容。如果要返回多个值,则需要使用returns setof integer

但是它有更多的问题。

  1. 您应该给您的参数起一个名字(不是错误,而是好的编码风格)
  2. 要从函数返回值,您需要使用return。要返回多个值(由于returns setof),您需要使用return next
  3. 动态SQL无需返回值,您可以直接返回变量。
  4. 这也不是一个错误,但是:window是一个关键字,我不会使用具有该名称的变量。

应用所有内容后,您的函数应如下所示:

CREATE OR REPLACE FUNCTION test(p_input int[]) 
  RETURNS setof integer
as
$$  
DECLARE                                                     
  l_value INT;                                             
BEGIN                                                       
    FOREACH l_value IN ARRAY p_input                             
    LOOP                                                    
        return next l_value;
    END LOOP;                                               
end;
$$ 
LANGUAGE plpgsql;                                        

我不确定您是否知道,但是已经有一个内置函数可以实现相同的功能:unnest()