【问题标题】:PostgreSQL PL/pgSQL syntax error with FOREACH loopPostgreSQL PL/pgSQL 语法错误与 FOREACH 循环
【发布时间】:2019-03-13 05:49:59
【问题描述】:

我正在尝试通过编写一些简单的程序来学习 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]);    

我希望这段代码 sn-p 将首先打印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.

所以函数定义有语法错误,但我不明白错误是什么以及如何修复它。我会很感激任何帮助。谢谢!

【问题讨论】:

    标签: postgresql plpgsql


    【解决方案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()

    【讨论】:

    • 感谢您的帮助 :) 我也需要获得 EXECUTE... USING 才能工作。你知道我的代码中EXECUTE... USING 有什么问题吗?
    • 更新:这是因为 WINDOW 关键字。在我更改变量名后它可以工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多