W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
服務器代碼內(nèi)產(chǎn)生的錯誤、警告和日志消息應該使用ereport
或者更老的elog
生成。這個函數(shù)的使用有些復雜,因此有必要做一些解釋。
對于每一個消息都有兩個必要的元素:一個嚴重性級別(從DEBUG
到PANIC
)和一個主消息文本。此外還有一些可選元素,其中最常見的是一個遵守 SQL 規(guī)范中 SQLSTATE 習慣的錯誤標識符代碼。ereport
本身只是一個 shell 宏,它的存在主要是為了在語法習慣上讓消息的產(chǎn)生更像 C 源代碼中的單個函數(shù)調用而已。
ereport
直接接受的唯一參數(shù)是嚴重性級別。主消息文本和任何其他可選消息元素通過在ereport
調用中使用輔助函數(shù)產(chǎn)生,例如errmsg
。
對于ereport
的一次典型調用可能看起來像:
ereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));
這會指定錯誤嚴重性級別為ERROR
(一個普通錯誤)。errcode
調用使用src/include/utils/errcodes.h
中定義的一個宏指定 SQLSTATE 錯誤代碼。errmsg
調用提供主消息文本。
您還會經(jīng)??吹竭@種較舊的樣式,在輔助函數(shù)調用周圍有一組額外的圓括號:
ereport(ERROR,
(errcode(ERRCODE_DIVISION_BY_ZERO),
errmsg("division by zero")));
在 PostgreSQL 版本 12 之前需要額外的括號,但現(xiàn)在是可選的。
這里有一個更復雜的例子:
ereport(ERROR,
errcode(ERRCODE_AMBIGUOUS_FUNCTION),
errmsg("function %s is not unique",
func_signature_string(funcname, nargs,
NIL, actual_arg_types)),
errhint("Unable to choose a best candidate function. "
"You might need to add explicit typecasts."));
這展示了使用格式代碼把運行時值嵌入到一個消息文本中的方法,其中還提供了一個可選的“hint”消息。 輔助函數(shù)調用可以按任何順序寫入,但通常先出現(xiàn)errcode
和errmsg
。
如果嚴重級別是ERROR
或更高,ereport
會中止當前查詢的執(zhí)行并且不會返回到調用者。如果嚴重級別低于 ERROR
,ereport
會正常返回。
ereport
可用的輔助例程是:
errcode(sqlerrcode)
指定對于該情況的 SQLSTATE 錯誤標識符代碼。如果沒有調用這個例程,錯誤嚴重性級別是ERROR
或更高時錯誤標識符會默認成ERRCODE_INTERNAL_ERROR
,錯誤級別是WARNING
時標識符為ERRCODE_WARNING
,否則(對于
NOTICE
及以下的級別)標識符會被設置為ERRCODE_SUCCESSFUL_COMPLETION
。雖然這些默認值常常很方便,在忽略errcode()
調用之前請總是思考一下它們是否合適。
errmsg(const char *msg, ...)
指定主錯誤消息文本,以及需要插入其中的運行時值。這種插入以sprintf
-風格的格式代碼指定。除了sprintf
接受的標準格式代碼,格式代碼%m
可以用來插入由strerror
為
errno
的當前值返回的錯誤消息。 [14]
%m
不要求errmsg
參數(shù)列表中的任何對應項。注意在格式代碼被處理之前,消息字符串將通過
gettext
來進行可能的本地化。
errmsg_internal(const char *msg, ...)
與errmsg
相同,不過消息串將不會被翻譯,也不會被包括在國際化的消息字典中。這不應該被用于“不能發(fā)生”的情況中,因為那些情況下不值得花費精力去做翻譯。
errmsg_plural(const char *fmt_singular, const char *fmt_plural,
unsigned long n, ...)
很像errmsg
,但是支持消息的多種復數(shù)形式。fmt_singular
是英語單數(shù)格式,fmt_plural
是英語復數(shù)格式,n
是決定需要何種復數(shù)形式的整數(shù)值,剩下的參數(shù)會被根據(jù)選中的格式字符串進行格式化。詳見
第 54.2.2 節(jié)。
errdetail(const char *msg, ...)
提供了一個可選的“詳情”消息,如果有額外的信息但不適合放在主消息中時就可以使用這種方式。消息字符串的處理與errmsg
相同。
errdetail_internal(const char *msg, ...)
與errdetail
相同,不過消息串將不會被翻譯,也不會被包括在國際化的消息字典中。這應該被用于不值得花費精力翻譯的詳情消息上,例如它們對大部分用戶太過技術化而沒什么用處。
errdetail_plural(const char *fmt_singular, const char *fmt_plural,
unsigned long n, ...)
與errdetail
相似,但是支持消息的多種復數(shù)形式。詳見第 54.2.2 節(jié)。
errdetail_log(const char *msg, ...)
與errdetail
相同,除了這個字符串只會進入服務器的日志而不會發(fā)往客戶端。如果同時使用了errdetail
(或者上述的一種等效函數(shù))以及errdetail_log
,那么一個字符串會被發(fā)往客戶端而另一個會被發(fā)往日志。如果錯誤細節(jié)的安全性過于敏感或者體積過于龐大而不適合于發(fā)往客戶端,這個函數(shù)就非常有用。
errdetail_log_plural(const char *fmt_singular, const char
*fmt_plural, unsigned long n, ...)
與errdetail_log
相似,但是支持多種復數(shù)形式的消息。詳見第 54.2.2 節(jié)。
errhint(const char *msg, ...)
提供一個可選的“hint”消息,它被用來提供關于如何修復該問題的建議。該消息字符串以和errmsg
相同的方式處理。
errcontext(const char *msg, ...)
通常不會被直接從一個ereport
消息站點調用,它被用在error_context_stack
回調函數(shù)中來提供錯誤發(fā)生的上下文,例如一個 PL 函數(shù)中的當前位置。該消息字符串以和errmsg
相同的方式處理。不同于其他輔助函數(shù),在每次
ereport
調用中可以多次調用這個函數(shù),這樣提供的連續(xù)的字符串將被用單獨的新行串接在一起。
errposition(int cursorpos)
指定一個查詢字符串中錯誤的文本位置。當前,它只對查詢處理的詞法和語法分析階段中檢測到的錯誤有用。
errtable(Relation rel)
指定一個關系,它的名稱和模式名稱應該被包括在錯誤報告中作為輔助域。
errtablecol(Relation rel, int attnum)
指定一個列,它的名稱、表名和模式名稱應該被包括在錯誤報告中作為輔助域。
errtableconstraint(Relation rel, const char *conname)
指定一個約束,它的名稱、表名和模式名稱應該被包括在錯誤報告中作為輔助域。索引應當為考慮成用于這種目的的約束,不管它們有沒有一個相關聯(lián)的pg_constraint
項。要小心地以rel
傳遞底層堆關系而不是索引本身。
errdatatype(Oid datatypeOid)
指定一個數(shù)據(jù)類型,它的名稱和模式名稱應該被包括在錯誤報告中作為輔助域。
errdomainconstraint(Oid datatypeOid, const char *conname)
指定一個域約束,它的名稱、域名和模式名稱應該被包括在錯誤報告中作為輔助域。
errcode_for_file_access()
是一個便捷函數(shù),它可以在一個文件訪問相關的系統(tǒng)調用中為一個失敗選擇一個合適的 SQLSTATE 錯誤標識符。它使用保存下來的errno
來決定要差生哪種錯誤代碼。通常,應該把它和主錯誤消息文本中的%m
聯(lián)合使用。
errcode_for_socket_access()
是一個便捷函數(shù),它可以在一個套接字相關的系統(tǒng)調用中為一個失敗選擇一個合適的 SQLSTATE 錯誤標識符。
errhidestmt(bool hide_stmt)
可以被調用來指定 postmaster 日志中一個消息的STATEMENT:
部分的禁止。通常如果該消息文本已經(jīng)包括當前語句這就是合適的。
可以調用errhidecontext(bool hide_ctx)
來指示抑制 postmaster 日志中消息里的CONTEXT:
部分。這只應該被用于 verbose 模式的調試消息,這類消息中被重復包含的上下文信息會讓日志膨脹得非常厲害。
在一個ereport
調用中,最多可以使用一個errtable
、errtablecol
、errtableconstraint
、errdatatype
或者errdomainconstraint
函數(shù)。這些函數(shù)存在是為了允許應用抽取與錯誤情況相關的數(shù)據(jù)庫對象名,而不需要檢查可能已被本地化的錯誤消息文本。這些函數(shù)應該被用在應用需要對其進行自動錯誤處理的錯誤報告中。從
PostgreSQL9.3 開始,完整的覆蓋只為 SQLSTATE 類別 23 中的錯誤存在(完整性約束違背),但是在未來這些很可能會被擴展。
有一個還在大量使用的舊的函數(shù)elog
。一個elog
調用:
elog(level, "format string", ...);
完全等效于:
ereport(level, errmsg_internal("format string", ...));
注意 SQLSTATE 錯誤代碼總是被給予默認值,并且消息字符串不受翻譯限制。因此,elog
應該只被用于內(nèi)部錯誤和低層次的調試日志。任何普通用戶感興趣的消息應該通過ereport
。不管怎樣,在仍廣泛使用elog
的系統(tǒng)中,有足夠多的內(nèi)部“不可能發(fā)生”的錯誤檢查,出于記號簡潔的目的這更適合于那些消息。
有關編寫好的錯誤消息的建議可見第 53.3 節(jié)。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: