2025年9月25日: PostgreSQL 18 釋出!
支援的版本: 當前 (18) / 17 / 16 / 15 / 14 / 13
開發版本: devel
不支援的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2

41.2. PL/pgSQL 結構 #

用 PL/pgSQL 編寫的函式透過執行 CREATE FUNCTION 命令定義給伺服器。這樣的命令通常看起來像這樣,舉個例子:

CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'function body text'
LANGUAGE plpgsql;

CREATE FUNCTION 的角度來看,函式體只是一個字串字面量。與使用普通的單引號語法相比,使用美元引用(參見 第 4.1.2.4 節)來編寫函式體通常很有用。如果不使用美元引用,函式體中的任何單引號或反斜槓都必須透過加倍來轉義。本章中的幾乎所有示例都使用美元引用字面量作為它們的函式體。

PL/pgSQL 是一種塊結構語言。函式體的完整文字必須是一個 。塊定義為:

[ <<label>> ]
[ DECLARE
    declarations ]
BEGIN
    statements
END [ label ];

塊中的每個宣告和每個語句都以分號結束。如上所示,出現在另一個塊內的塊在 END 之後必須有一個分號;然而,結束函式體的最終 END 不需要分號。

提示

一個常見的錯誤是在 BEGIN 之後立即寫一個分號。這是不正確的,並且會導致語法錯誤。

只有當你想用 EXIT 語句標識該塊,或者限定塊中宣告的變數的名稱時,才需要 label。如果在 END 之後給出了標籤,它必須與塊開頭的標籤匹配。

所有關鍵字都不區分大小寫。識別符號會被隱式轉換為小寫,除非被雙引號括起來,這與普通 SQL 命令中的情況一樣。

註釋在 PL/pgSQL 程式碼中的工作方式與在普通 SQL 中相同。雙破折號 (--) 啟動一個註釋,該註釋一直延伸到行尾。一個 /* 啟動一個塊註釋,該註釋一直延伸到匹配的 */。塊註釋是巢狀的。

塊的語句部分中的任何語句都可以是 子塊。子塊可用於邏輯分組或將變數限定在少數語句中。在子塊中宣告的變數會掩蓋子塊持續期間內任何同名但屬於外部塊的變數;但是,您仍然可以透過使用其塊標籤來限定名稱來訪問外部變數。例如:

CREATE FUNCTION somefunc() RETURNS integer AS $$
<< outerblock >>
DECLARE
    quantity integer := 30;
BEGIN
    RAISE NOTICE 'Quantity here is %', quantity;  -- Prints 30
    quantity := 50;
    --
    -- Create a subblock
    --
    DECLARE
        quantity integer := 80;
    BEGIN
        RAISE NOTICE 'Quantity here is %', quantity;  -- Prints 80
        RAISE NOTICE 'Outer quantity here is %', outerblock.quantity;  -- Prints 50
    END;

    RAISE NOTICE 'Quantity here is %', quantity;  -- Prints 50

    RETURN quantity;
END;
$$ LANGUAGE plpgsql;

注意

在任何 PL/pgSQL 函式的主體周圍實際上有一個隱藏的“外部塊”。這個塊提供了函式引數(如果有)的宣告,以及一些特殊變數,例如 FOUND(參見 第 41.5.5 節)。外部塊用函式名標記,這意味著引數和特殊變數可以用函式名限定。

重要的是不要將 PL/pgSQL 中用於對語句進行分組的 BEGIN/END 與用於事務控制的同名 SQL 命令混淆。PL/pgSQLBEGIN/END 僅用於分組;它們不會啟動或結束事務。有關在 PL/pgSQL 中管理事務的資訊,請參見 第 41.8 節。此外,包含 EXCEPTION 子句的塊實際上構成了一個子事務,該子事務可以在不影響外部事務的情況下回滾。有關更多資訊,請參見 第 41.6.8 節

提交更正

如果您在文件中發現任何不正確、與您在使用特定功能時的體驗不符或需要進一步說明的內容,請使用 此表單 來報告文件問題。