2016-08-25 151 views
0

我有一个存储过程:PostgreSQL的存储过程的错误

CREATE OR REPLACE FUNCTION postalcode_lookup(ccode character(6)) 
RETURNS SETOF postalcode AS $BODY$ 
BEGIN 
    WITH RECURSIVE tblParent AS 
    (
     SELECT * 
     FROM postalcode 
     WHERE postalcode.code = ccode 

     UNION ALL 

     SELECT postalcode.* 
     FROM postalcode 
     JOIN tblParent ON postalcode.code = tblParent.parent 
    ) 
    SELECT * FROM tblParent; 

END;$BODY$ LANGUAGE plpgsql; 

编译成功,但运行时,我有

error: query has no destination for result data;SQL state: 42601;

Hint:> If you want to discard the results of a SELECT, use PERFORM instead. Context: PL/pgSQL function postalcode_lookup(character) line 3 at SQL statement

请帮我解决。非常感谢。

+0

[RETURN NEXT and RETURN QUERY](https://www.postgresql.org/docs/current/static/plpgsql-control-structures.html#AEN62624) – Abelisto

回答

0

在功能的情况下,我们如果我们写如下,我们可以得到想要在执行此功能结果

CREATE OR REPLACE FUNCTION postalcode_lookup(ccode character(6)) 
    RETURNS refcursor AS $BODY$ 
    DECLARE 
    cur_postalcode refcursor; 
    BEGIN 
Open cur_postalcode for 
     WITH RECURSIVE tblParent AS 
     (
      SELECT * 
      FROM postalcode 
      WHERE postalcode.code = ccode 

      UNION ALL 

      SELECT postalcode.* 
      FROM postalcode 
      JOIN tblParent ON postalcode.code = tblParent.parent 
     ) 
     SELECT * FROM tblParent; 
    return cur_postalcode; 

    END;$BODY$ LANGUAGE plpgsql; 

函数返回值

,你会得到一个光标。从给定查询的游标运行中获取值。

SELECT postalcode_lookup(--ccode); 

fetch all "<unnamed portal 1>"; 

希望它有帮助。

+0

返回游标可能会有效,但是要复杂得多然后一个简单的'返回查询...' –

+0

我按照上面描述的方式创建,但会出错ERROR:语法错误处于“Open”或接近“打开” LINE 16:打开cur_postalcode for ^ ******** **错误********** 错误:在“打开”处或附近的语法错误 SQL状态:42601 字符:412 – anhdv

+0

结果集非常奇怪。无论如何,非常感谢您的帮助。 – anhdv

-1

当你没有任何程序代码,使用普通的SQL函数:

CREATE OR REPLACE FUNCTION postalcode_lookup(ccode character(6)) 
    RETURNS SETOF postalcode AS 
$BODY$ 
    WITH RECURSIVE tblParent AS 
    (
     SELECT * 
     FROM postalcode 
     WHERE postalcode.code = ccode 

     UNION ALL 

     SELECT postalcode.* 
     FROM postalcode 
     JOIN tblParent ON postalcode.code = tblParent.parent 
    ) 
    SELECT * 
    FROM tblParent; 
$BODY$ LANGUAGE sql; 

为了完整,在此PL/pgSQL的版本将需要使用RETURN QUERY

CREATE OR REPLACE FUNCTION postalcode_lookup(ccode character(6)) 
    RETURNS SETOF postalcode AS 
$BODY$ 
BEGIN 
    RETURN QUERY --<< this does the magic 
    WITH RECURSIVE tblParent AS 
    (
     SELECT * 
     FROM postalcode 
     WHERE postalcode.code = ccode 

     UNION ALL 

     SELECT postalcode.* 
     FROM postalcode 
     JOIN tblParent ON postalcode.code = tblParent.parent 
    ) 
    SELECT * 
    FROM tblParent; 
END; 
$BODY$ LANGUAGE plpgsql; 

但是,普通的SQL函数应该是首选的,因为它会更快(并且可以在更复杂的语句中使用时更好地进行优化,例如,使用连接或使用其他条件。

在这两种情况下,该功能可以使用像一个表:

select * 
from postalcode_lookup('ABCDEF'); 

无关,而是:在使用character数据类型几乎总是一个坏的选择。改为使用varchartext

+0

非常感谢。它运作良好。 – anhdv

+0

@anhdv:如果这解决了您的问题,请接受答案,以便您的问题被标记为已解决 –