Postgresql

帶有 SELECT 的 SQL 函式與帶有 RETURN QUERY SELECT 的 PLPGSQL 函式?

  • November 17, 2021

執行 SQL 查詢的普通 SQL 函式之間是否有區別:

create function get_sports() returns setof sport as
$body$
   select * from sport;
$body$
language sql stable;

和 PLPGSQL 函式返回相同的 SQL 查詢:

create function get_sports() returns setof sport as
$body$
begin
   return query select * from sport;
end
$body$
language plpgsql stable;

關於性能?在什麼情況下應該使用哪個版本?

如果我們傳遞參數,那會改變什麼嗎?如:

create function get_sports(status int) returns setof sport as
$body$
   select * from sport where status = $1;
$body$
language sql stable;

create function get_sports(status int) returns setof sport as
$body$
begin
   return query select * from sport where status = $1;
end
$body$
language plpgsql stable;

有各種細微的差別。

簡單的 SQL 函式可以在嵌套在外部查詢中時內聯- 只要它們滿足一些先決條件。不能用於 PL/pgSQL 函式。

同一 SQL 函式中的所有語句在呼叫時立即計劃,而 PL/pgSQL 函式將嵌套的 SQL DML 語句視為準備好的語句 - 僅在第一次執行時計劃每個語句,並可能在一個持續時間內保存查詢計劃會議。這是影響行為和表現的主要區別。

例如,您不能創建(臨時)表並稍後在同一個 SQL 函式中使用它,因為它必須在呼叫時存在才能計劃後面的語句。為此,您需要 PL/pgSQL。

PL/pgSQL 函式中未到達並因此從未計劃或執行的程式碼分支可能會隱藏未檢測到的錯誤,直到最終執行。PL/pgSQL 函式僅在創建時進行表面測試。

此外,SQL 函式僅返回最後一個查詢的輸出。手冊:

當一個 SQL 函式被聲明為返回SETOF***sometype***時,函式的最終查詢被執行完成,並且它輸出的每一行都作為結果集的一個元素返回。

大膽強調我的。(您可以使用UNION( ALL) 組合多個查詢結果。)

RETURN QUERY,另一方面,附加到結果並且可以被多次呼叫。手冊:

RETURN NEXT並且RETURN QUERY實際上並不從函式返回——它們只是將零或多行附加到函式的結果集。然後繼續執行 PL/pgSQL 函式中的下一條語句。隨著連續RETURN NEXTRETURN QUERY命令的執行,結果集被建立起來。finalRETURN應該沒有參數,導致控制退出函式(或者你可以讓控製到達函式的末尾)。

有關的:

對於任何一個 PL,傳遞參數的工作方式幾乎相同。(以前舊版本有更多差異,比如 SQL 函式不能引用參數名稱。但那是歷史。)

還有其他或多或少的細微差別。看:

引用自:https://dba.stackexchange.com/questions/217665