PostgreSQL 錯(cuò)誤和消息

2021-09-03 17:33 更新
42.9.1. 報(bào)告錯(cuò)誤和消息
42.9.2. 檢查斷言

42.9.1. 報(bào)告錯(cuò)誤和消息

使用RAISE語句報(bào)告消息以及拋出錯(cuò)誤。

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選項(xiàng)指定了錯(cuò)誤的嚴(yán)重性。允許的級(jí)別有DEBUGLOG、INFO、NOTICE, WARNING以及EXCEPTION,默認(rèn)級(jí)別是 EXCEPTIONEXCEPTION會(huì)拋出一個(gè)錯(cuò)誤(通常會(huì)中止當(dāng)前事務(wù))。其他級(jí)別僅僅是產(chǎn)生不同優(yōu)先級(jí)的消息。不管一個(gè)特定優(yōu)先級(jí)的消息是被報(bào)告給客戶端、還是寫到服務(wù)器日志、亦或是二者同時(shí)都做,這都由log_min_messagesclient_min_messages配置變量控制。詳見 第 19 章。

如果有level, 在它后面可以寫一個(gè)format( 它必須是一個(gè)簡單字符串而不是表達(dá)式)。該格式字符串指定要被報(bào)告的 錯(cuò)誤消息文本。在格式字符串后面可以跟上可選的要被插入到該消息的 參數(shù)表達(dá)式。在格式字符串中,%會(huì)被下一個(gè)可選參數(shù) 的值所替換。寫%%可以發(fā)出一個(gè)字面的 %。參數(shù)的數(shù)量必須匹配格式字符串中% 占位符的數(shù)量,否則在函數(shù)編譯期間就會(huì)發(fā)生錯(cuò)誤。

在這個(gè)例子中,v_job_id的值將替換字符串中的%

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

通過寫一個(gè)后面跟著option = expression項(xiàng)的USING,可以為錯(cuò)誤報(bào)告附加一些額外信息。每一個(gè)expression可以是任意字符串值的表達(dá)式。允許的option關(guān)鍵詞是:

MESSAGE

設(shè)置錯(cuò)誤消息文本。這個(gè)選項(xiàng)可以被用于在USING之前包括一個(gè)格式字符串的RAISE形式。

DETAIL

提供一個(gè)錯(cuò)誤的細(xì)節(jié)消息。

HINT

提供一個(gè)提示消息。

ERRCODE

指定要報(bào)告的錯(cuò)誤代碼(SQLSTATE),可以用附錄 A中所示的條件名,或者直接作為一個(gè)五字符的 SQLSTATE 代碼。

COLUMN
CONSTRAINT
DATATYPE
TABLE
SCHEMA

提供一個(gè)相關(guān)對(duì)象的名稱。

這個(gè)例子將用給定的錯(cuò)誤消息和提示中止事務(wù):

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

這兩個(gè)例子展示了設(shè)置 SQLSTATE 的兩種等價(jià)的方法:

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

還有第二種RAISE語法,在其中主要參數(shù)是要被報(bào)告的條件名或 SQLSTATE,例如:

RAISE division_by_zero;
RAISE SQLSTATE '22012';

在這種語法中,USING能被用來提供一個(gè)自定義的錯(cuò)誤消息、細(xì)節(jié)或提示。另一種做前面的例子的方法是

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

仍有另一種變體是寫RAISE USING或者RAISE level USING并且把所有其他東西都放在USING列表中。

RAISE的最后一種變體根本沒有參數(shù)。這種形式只能被用在一個(gè)BEGIN塊的EXCEPTION子句中,它導(dǎo)致當(dāng)前正在被處理的錯(cuò)誤被重新拋出。

注意

PostgreSQL 9.1 之前,沒有參數(shù)的RAISE被解釋為重新拋出來自包含活動(dòng)異常處理器的塊的錯(cuò)誤。因此一個(gè)嵌套在那個(gè)處理器中的EXCEPTION子句無法捕捉它,即使RAISE位于嵌套EXCEPTION子句的塊中也是這樣。這種行為很奇怪,也并不兼容 Oracle 的 PL/SQL。

如果在一個(gè)RAISE EXCEPTION命令中沒有指定條件名以及 SQLSTATE,默認(rèn)是使用ERRCODE_RAISE_EXCEPTION (P0001)。如果沒有指定消息文本,默認(rèn)是使用條件名或 SQLSTATE 作為消息文本。

注意

當(dāng)用 SQLSTATE 代碼指定一個(gè)錯(cuò)誤代碼時(shí),你不會(huì)受到預(yù)定義錯(cuò)誤代碼的限制,而是可以選擇任何由五位以及大寫 ASCII 字母構(gòu)成的錯(cuò)誤代碼,只有00000不能使用。我們推薦盡量避免拋出以三個(gè)零結(jié)尾的錯(cuò)誤代碼,因?yàn)檫@些是分類代碼并且只能用來捕獲整個(gè)類別。

42.9.2. 檢查斷言

ASSERT語句是一種向 PL/pgSQL函數(shù)中插入調(diào)試檢查的方便方法。

ASSERT condition [ , message ];

condition是一個(gè)布爾 表達(dá)式,它被期望總是計(jì)算為真。如果確實(shí)如此, ASSERT語句不會(huì)再做什么。但如果結(jié)果是假 或者空,那么將發(fā)生一個(gè)ASSERT_FAILURE異常(如果在計(jì)算 condition時(shí)發(fā)生錯(cuò)誤, 它會(huì)被報(bào)告為一個(gè)普通錯(cuò)誤)。

如果提供了可選的message, 它是一個(gè)結(jié)果(如果非空)被用來替換默認(rèn)錯(cuò)誤消息文本 assertion failed的表達(dá)式(如果 condition失?。?。 message表達(dá)式在 斷言成功的普通情況下不會(huì)被計(jì)算。

通過配置參數(shù)plpgsql.check_asserts可以啟用或者禁用斷言測(cè)試, 這個(gè)參數(shù)接受布爾值且默認(rèn)為on。如果這個(gè)參數(shù)為off, 則ASSERT語句什么也不做。

注意ASSERT是為了檢測(cè)程序的 bug,而不是 報(bào)告普通的錯(cuò)誤情況。如果要報(bào)告普通錯(cuò)誤,請(qǐng)使用前面介紹的 RAISE語句。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)