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.9. 錯誤和訊息 #

41.9.1. 報告錯誤和訊息 #

使用 RAISE 語句報告訊息和引發錯誤。

RAISE [ level ] 'format' [, expression [, ... ]] [ USING option { = | := } expression [, ... ] ];
RAISE [ level ] condition_name [ USING option { = | := } expression [, ... ] ];
RAISE [ level ] SQLSTATE 'sqlstate' [ USING option { = | := } expression [, ... ] ];
RAISE [ level ] USING option { = | := } expression [, ... ];
RAISE ;

level 選項指定錯誤嚴重級別。允許的級別有 DEBUGLOGINFONOTICEWARNINGEXCEPTION,其中 EXCEPTION 是預設值。 EXCEPTION 會引發一個錯誤(通常會中止當前事務);其他級別僅生成不同優先順序級別的訊息。特定優先順序的訊息是否報告給客戶端、寫入伺服器日誌或兩者都有,由 log_min_messagesclient_min_messages 配置變數控制。更多資訊請參見 第 19 章

在第一種語法變體中,如果 level 存在,後面跟著一個 format 字串(必須是簡單的字串字面量,而不是表示式)。格式字串指定要報告的錯誤訊息文字。格式字串後面可以跟可選的引數表示式,用於插入到訊息中。在格式字串內部,% 被替換為下一個可選引數的值的字串表示形式。要輸出字面量 %,請寫 %%。引數的數量必須與格式字串中的 % 佔位符數量匹配,否則會在函式編譯期間引發錯誤。

在此示例中,v_job_id 的值將替換字串中的 %

RAISE NOTICE 'Calling cs_create_job(%)', v_job_id;

在第二種和第三種語法變體中,condition_namesqlstate 分別指定一個錯誤條件名稱或一個五字元的 SQLSTATE 程式碼。請參見 附錄 A 瞭解有效的錯誤條件名稱和預定義的 SQLSTATE 程式碼。

以下是 condition_namesqlstate 用法的示例:

RAISE division_by_zero;
RAISE WARNING SQLSTATE '22012';

在任何這些語法變體中,您都可以透過寫入 USING 加上 option = expression 條目來附加額外資訊到錯誤報告。每個 expression 可以是任何字串值的表示式。允許的 option 關鍵字是:

MESSAGE #

設定錯誤訊息文字。此選項不能在第一種語法變體中使用,因為訊息已提供。

DETAIL #

提供錯誤詳細資訊訊息。

HINT #

提供提示訊息。

ERRCODE #

指定要報告的錯誤程式碼(SQLSTATE),可以透過條件名稱(如 附錄 A 所示)或直接作為一個五字元的 SQLSTATE 程式碼。此選項不能在第二種或第三種語法變體中使用,因為錯誤程式碼已提供。

COLUMN
CONSTRAINT
DATATYPE
TABLE
SCHEMA #

提供相關物件的名稱。

此示例將以給定的錯誤訊息和提示中止事務。

RAISE EXCEPTION 'Nonexistent ID --> %', user_id
      USING HINT = 'Please check your user ID';

這兩個示例展示了設定 SQLSTATE 的等效方法。

RAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation';
RAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505';

另一種產生相同結果的方法是:

RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id;

如第四種語法變體所示,也可以寫 RAISE USINGRAISE level USING,並將其他所有內容放入 USING 列表中。

RAISE 的最後一種變體沒有任何引數。此形式只能在 BEGIN 塊的 EXCEPTION 子句內使用;它會導致當前正在處理的錯誤被重新引發。

注意

PostgreSQL 9.1 之前,不帶引數的 RAISE 被解釋為重新引發來自包含活動異常處理程式的塊的錯誤。因此,即使 RAISE 在巢狀的 EXCEPTION 子句的塊內,巢狀在該處理程式內的 EXCEPTION 子句也無法捕獲它。這被認為令人驚訝,並且與 Oracle 的 PL/SQL 不相容。

如果在 RAISE EXCEPTION 命令中沒有指定條件名稱或 SQLSTATE,則預設使用 raise_exceptionP0001)。如果未指定訊息文字,則預設使用條件名稱或 SQLSTATE 作為訊息文字。

注意

當透過 SQLSTATE 程式碼指定錯誤程式碼時,您不限於預定義的錯誤程式碼,但可以選擇任何由五個數字和/或大寫 ASCII 字母組成的錯誤程式碼,除了 00000。建議您避免引發以三個零結尾的錯誤程式碼,因為這些是類別程式碼,只能透過捕獲整個類別來捕獲。

41.9.2. 檢查斷言 #

ASSERT 語句是方便地將除錯檢查插入 PL/pgSQL 函式的一種快捷方式。

ASSERT condition [ , message ];

condition 是一個布林表示式,預期它總是會計算為 true;如果為 true,則 ASSERT 語句不做任何其他操作。如果結果為 false 或 null,則會引發 ASSERT_FAILURE 異常。(如果在評估 condition 時發生錯誤,它將作為一個正常錯誤報告。)

如果提供了可選的 message,它是一個表示式,其結果(如果不是 null)將替換預設錯誤訊息文字“assertion failed”,以防 condition 失敗。在斷言成功(正常情況)時,message 表示式不會被評估。

斷言的測試可以透過配置引數 plpgsql.check_asserts 來啟用或停用,該引數接受一個布林值;預設值為 on。如果此引數為 off,則 ASSERT 語句不執行任何操作。

請注意,ASSERT 用於檢測程式錯誤,而不是報告普通錯誤條件。對於這種情況,請使用上面描述的 RAISE 語句。

提交更正

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