2016-08-25 38 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:如果這解決了您的問題,請接受答案,以便您的問題被標記爲已解決 –