使用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选项指定错误的严重程度。允许的级别有 DEBUG, LOG, INFO, NOTICE,WARNING, 和 EXCEPTION, 默认的是EXCEPTION 。EXCEPTION 抛出一个错误 (通常终止当前错误);其他level只能生成不同优先级的消息。是否要把一个特定的优先级的消息报告给客户,写入服务器日志,是由log_min_messages和client_min_messages配置变量控制。
任何level你都可以写一个格式(必须是一个简单的字符串文字,而不是一个简单的表达式)。格式字符串指定要报告的错误消息文本。该格式字符串可以跟可选的要被插入到消息中的参数表达式。在格式字符串中,%被替换为下一个可选参数的字符串表示形式,写两个%%发出一个%。
在这个例子中,v_job_id的值将替换字符串中的%:
RAISE NOTICE ’Calling cs_create_job(%)’, v_job_id;
通过写USING后跟着option =expression可以添加额外的信息到错误报告中,每个表达式都可以是任意字符串值的表达式。允许的option关键字如下:
MESSAGE:设置错误信息文本。此选项不能用于在USING之前包含一个格式串的RAISE格式。
DETAIL:提供一个错误的详细信息。
HINT:提供一个提示信息。
ERRCODE:指定要报告的错误码(SQLSTATE),通过条件名,或者直接是一五个字符的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语法,主要参数是条件名或者要报告的SQLSTATE ,例如:
RAISE division_by_zero;
RAISE SQLSTATE ’22012’;
在这个语法中,USING可用于提供自定义错误信息 ,细节或者提示。实现前面例子的另外一种方法是:
RAISE unique_violation USING MESSAGE = ’Duplicate user ID: ’ || user_id;
还有一个变体是写RAISE USING或者RAISE level USING,把所有的一切都放在USING列表中。
RAISE的最后一个变体是没有任何参数。此表单只用于BEGIN块的EXCEPTION子句中。它会导致当前正在处理的错误被重新抛出。
如果RAISE EXCEPTION命令中既不指定条件名也不指定SQLSTATE,默认使用RAISE_EXCEPTION (P0001)。如果不指定消息文本,默认使用条件名或者SQLSTATE作为消息文本。
SELECT * INTO myrec FROM emp WHERE empname = myname;
IF NOT FOUND THEN
RAISE EXCEPTION ’employee % not found’, myname;
END IF;
BEGIN
SELECT * INTO STRICT myrec FROM emp WHERE empname = myname;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE EXCEPTION ’employee % not found’, myname;
WHEN TOO_MANY_ROWS THEN
RAISE EXCEPTION ’employee % not unique’, myname;
END;
EXECUTE ’SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2’
INTO c
USING checked_user, checked_date;
EXECUTE ’SELECT count(*) FROM ’
|| tabname::regclass
|| ’ WHERE inserted_by = $1 AND inserted <= $2’
INTO c
USING checked_user, checked_date;
EXECUTE ’UPDATE tbl SET ’
|| quote_ident(colname)
|| ’ = ’
|| quote_literal(newvalue)
|| ’ WHERE key = ’
|| quote_literal(keyvalue);
EXECUTE ’UPDATE tbl SET ’
|| quote_ident(colname)
|| ’ = ’
|| quote_nullable(newvalue)
|| ’ WHERE key = ’
|| quote_nullable(keyvalue);
EXECUTE ’UPDATE tbl SET ’
|| quote_ident(colname)
|| ’ = $$’
|| newvalue
|| ’$$ WHERE key = ’
|| quote_literal(keyvalue);
EXECUTE format(’UPDATE tbl SET %I = %L WHERE key = %L’, colname, newvalue, keyvalue);
EXECUTE format(’UPDATE tbl SET %I = $1 WHERE key = $2’, colname)
USING newvalue, keyvalue;