调试

语法

RAISE语法

有以下五种语法格式:

图 1 raise_format::= 调试 - 图1

图 2 raise_condition::= 调试 - 图2

图 3 raise_sqlstate::= 调试 - 图3

图 4 raise_option::= 调试 - 图4

图 5 raise::= 调试 - 图5

参数说明:

  • level选项用于指定错误级别,有DEBUG,LOG,INFO,NOTICE,WARNING以及EXCEPTION(默认值)。EXCEPTION抛出一个正常终止当前事务的异常,其他的仅产生不同异常级别的信息。特殊级别的错误信息是否报告到客户端、写到服务器日志由log_min_messages和client_min_messages这两个配置参数控制。
  • format:格式字符串,指定要报告的错误消息文本。格式字符串后可跟表达式,用于向消息文本中插入。在格式字符串中,%由format后面跟着的参数的值替换,%%用于打印出%。例如:

1. --v_job_id 将替换字符串中的 %: 2. RAISE NOTICE 'Calling cs_create_job(%)',v_job_id; - option = expression:向错误报告中添加另外的信息。关键字option可以是MESSAGE、DETAIL、HINT以及ERRCODE,并且每一个expression可以是任意的字符串。

  • MESSAGE,指定错误消息文本,这个选项不能用于在USING前包含一个格式字符串的RAISE语句中。
  • DETAIL,说明错误的详细信息。
  • HINT,用于打印出提示信息。
  • ERRCODE,向报告中指定错误码(SQLSTATE)。可以使用条件名称或者直接用五位字符的SQLSTATE错误码。
  • condition_name:错误码对应的条件名。
  • sqlstate:错误码。

如果在RAISE EXCEPTION命令中既没有指定条件名也没有指定SQLSTATE,默认用RAISE EXCEPTION (P0001)。如果没有指定消息文本,默认用条件名或者SQLSTATE作为消息文本。

调试 - 图6 须知:

  • 当由SQLSTATE指定了错误码,则不局限于已定义的错误码,可以选择任意包含五个数字或者大写的ASCII字母的错误码,而不是00000。建议避免使用以三个0结尾的错误码,因为这种错误码是类别码,会被整个种类捕获。
  • 兼容O模式下,SQLCODE等于SQLSTATE。

调试 - 图7 说明:

  • 图5所示的语法不接任何参数。这种形式仅用于一个BEGIN块中的EXCEPTION语句,它使得错误重新被处理。
  • 用于ERRCODE指定的条件名称和condition_name可见SQL标准错误码说明,仅支持其中的ERROR类条件名。

EXCEPTION_INIT语法

兼容O模式下,支持使用EXCEPTION_INIT语法自定义错误码SQLCODE。语法格式如下:

图 6 exception_init::=

调试 - 图8

参数说明:

  • exception_name为用户申明的异常名,EXCEPTION_INIT语法必须出现在与申明异常相同部分,位于申明异常之后。
  • sqlcode为自定义的SQLCODE,必须为负整数,取值范围-2147483647~-1。

调试 - 图9 须知: 使用EXCEPTION_INIT语法自定义错误码SQLCODE时,SQLSTATE与SQLCODE相同,SQLERRM格式为” xxx: non-GaussDB Exception”。比如自定义SQLCODE=-1,则SQLSTATE=”-1”,SQLERRM=” 1: non-GaussDB Exception”。

示例

终止事务时,给出错误和提示信息:

1. CREATE OR REPLACE PROCEDURE proc_raise1(user_id in integer)
2. AS
3. BEGIN
4. RAISE EXCEPTION 'Noexistence ID --> %',user_id USING HINT = 'Please check your user ID';
5. END;
6. /

8. call proc_raise1(300011);

10. --执行结果
11. ERROR:  Noexistence ID --> 300011
12. HINT:  Please check your user ID

两种设置SQLSTATE的方式:

1. CREATE OR REPLACE PROCEDURE proc_raise2(user_id in integer)
2. AS
3. BEGIN
4. RAISE 'Duplicate user ID: %',user_id USING ERRCODE = 'unique_violation';
5. END;
6. /

8. \set VERBOSITY verbose
9. call proc_raise2(300011);

11. --执行结果
12. ERROR:  Duplicate user ID: 300011
13. SQLSTATE: 23505

如果主要的参数是条件名或者是SQLSTATE,可以使用:

RAISE division_by_zero;

RAISE SQLSTATE ‘22012’;

例如:

1. CREATE OR REPLACE PROCEDURE division(div in integer, dividend in integer)
2. AS
3. DECLARE
4. res int;
5. BEGIN
6. IF dividend=0 THEN
7. RAISE division_by_zero;
8. RETURN;
9. ELSE
10. res := div/dividend;
11. RAISE INFO 'division result: %', res;
12. RETURN;
13. END IF;
14. END;
15. /
16. call division(3,0);

18. --执行结果
19. ERROR:  division_by_zero

或者另一种方式:

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

兼容O模式下,支持使用语法EXCEPTION_INIT自定义错误码SQLCODE:

1. declare
2. deadlock_detected exception;
3. pragma exception_init(deadlock_detected, -1);
4. begin
5. if 1 > 0 then
6. raise deadlock_detected;
7. end if;
8. exception
9. when deadlock_detected then
10. raise notice 'sqlcode:%,sqlstate:%,sqlerrm:%',sqlcode,sqlstate,sqlerrm;
11. end;
12. /
13. --执行结果
14. NOTICE:  sqlcode:-1,sqlstate:-1,sqlerrm: 1: non-GaussDB Exception