相关
《Postgresql中plpgsql异常处理方法与实例(RAISE EXCEPTION)》
《Postgresql源码(80)plpgsql中异常处理编译与执行流程分析(sqlstate)》

Postgresql中有关plpgsql异常处理的一切(RAISE EXCEPTION)

1 抛出异常

主要列出实例,语法比较简单

语法

现在PL中支持使用RAISE语法抛出异常,具体支持下面五种语法:

1 RAISE [ level ] 'format' [, expression [, ... ]] [ USING option = expression [, ... ] ];
2 RAISE [ level ] condition_name [ USING option = expression [, ... ] ];
3 RAISE [ level ] SQLSTATE 'sqlstate' [ USING option = expression [, ... ] ];
4 RAISE [ level ] USING option = expression [, ... ];
5 RAISE ; -- 特殊,只能在EXCEPTION语法块中使用,重新抛出catch的异常。
  • level

    • 可选DEBUG, LOG, INFO, NOTICE, WARNING, EXCEPTION
    • 其中DEBUGWARNING都不会产生错误,只会打印日志,日志级别按level输出,由log_min_messages、client_min_messages参数决定是否输出。
    • 其中EXCEPTION会产生错误,中断程序执行,错误如果不被捕获会被抛到上一层。
  • 抛出指定类型的异常
    • 方式一:RAISE SQLSTATE
    • 方式二:RAISE condition_name
    • 方式三:RAISE 'text' USING ERRCODE = 'unique_violation'

抛出异常的实例展示

文本拼接

do $g$
DECLAREv_job_id int := 100;
BEGINRAISE NOTICE 'Calling cs_create_job(%)', v_job_id;
END;
$g$;

执行结果

postgres=# do $g$
postgres$# DECLARE
postgres$#   v_job_id int := 100;
postgres$# BEGIN
postgres$#   RAISE NOTICE 'Calling cs_create_job(%)', v_job_id;
postgres$# END;
postgres$# $g$;
NOTICE:  Calling cs_create_job(100)
DO

使用Hint

级别可任选,这里使用EXCEPTION没人处理,所以抛到顶层报错。

do $g$
DECLAREuser_id int := 100;
BEGINRAISE EXCEPTION 'Nonexistent ID --> %', user_idUSING HINT = 'Please check your user ID';
END;
$g$;

执行结果

postgres=# do $g$
postgres$# DECLARE
postgres$#   user_id int := 100;
postgres$# BEGIN
postgres$#   RAISE EXCEPTION 'Nonexistent ID --> %', user_id
postgres$#       USING HINT = 'Please check your user ID';
postgres$# END;
postgres$# $g$;
ERROR:  Nonexistent ID --> 100
HINT:  Please check your user ID
CONTEXT:  PL/pgSQL function inline_code_block line 5 at RAISE

抛出指定类型异常

1

do $g$
DECLAREuser_id int := 100;
BEGINRAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation';
END;
$g$;-- ERROR:  Duplicate user ID: 100
-- CONTEXT:  PL/pgSQL function inline_code_block line 5 at RAISE

2

do $g$
DECLAREuser_id int := 100;
BEGINRAISE 'Duplicate user ID: %', user_id USING ERRCODE = '23505';
END;
$g$;-- ERROR:  Duplicate user ID: 100
-- CONTEXT:  PL/pgSQL function inline_code_block line 1 at RAISE

3

do $g$
BEGINRAISE division_by_zero;
END;
$g$;-- ERROR:  division_by_zero
-- CONTEXT:  PL/pgSQL function inline_code_block line 3 at RAISE

4

do $g$
BEGINRAISE SQLSTATE '22012';
END;
$g$;-- ERROR:  22012
-- CONTEXT:  PL/pgSQL function inline_code_block line 3 at RAISE

5

do $g$
DECLAREuser_id int := 100;
BEGINRAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id;
END;
$g$;-- ERROR:  Duplicate user ID: 100
-- CONTEXT:  PL/pgSQL function inline_code_block line 5 at RAISE

2 捕获处理异常

捕获&&处理异常

语法

[ <<label>> ]
[ DECLAREdeclarations ]
BEGINstatements
EXCEPTIONWHEN condition [ OR condition ... ] THENhandler_statements[ WHEN condition [ OR condition ... ] THENhandler_statements... ]
END;在EXCEPTION内的特殊变量:
- SQLSTATE
- SQLERRM
  • condition:异常名字,有两种使用方式,所有异常列表在PG文档中可以找到《Appendix A. PostgreSQL Error Codes》,下面列举一部分。

    • 异常名:WHEN division_by_zero THEN规律:小写下划线连接关键字
    • 异常码:WHEN SQLSTATE '22012' THEN ...规律:5位字符,数字和任意字母组成
    • OTHERS:匹配一些异常
  • handler_statements:异常处理语法块,如果这里面再产生异常不会被当前的EXCEPTION捕获,会直接抛到上层。
  • 特殊变量:SQLSTATE、SQLERRM只在EXCEPTION语法块中生效,可以打印错误码和错误信息。
    • 例如:division_by_zero异常处理时,sqlerrm="division by zero"sqlstate=22012

部分condition实例

Class 00 — Successful Completion00000    successful_completionClass 01 — Warning01000    warning0100C    dynamic_result_sets_returned01008   implicit_zero_bit_padding01003  null_value_eliminated_in_set_function01007  privilege_not_granted01006  privilege_not_revoked01004  string_data_right_truncation01P01   deprecated_featureClass 22 — Data Exception22000    data_exception2202E array_subscript_error22021  character_not_in_repertoire22008    datetime_field_overflow22012    division_by_zero22005   error_in_assignment2200B    escape_character_conflict22022  indicator_overflow22015 interval_field_overflow

异常捕获实例

1 系统异常

do $g$
DECLAREuser_id int := 100;
BEGINuser_id = user_id / 0;
EXCEPTIONWHEN division_by_zero THENRAISE NOTICE 'caught division_by_zero';
END;
$g$;-- NOTICE:  caught division_by_zerodo $g$
DECLAREuser_id int := 100;
BEGINuser_id = user_id / 0;
EXCEPTIONWHEN SQLSTATE '22012' THENRAISE NOTICE 'caught division_by_zero';
END;
$g$;-- NOTICE:  caught division_by_zero

2 主动产生异常:没给错误码使用SQLSTATE P0001

没显示指定错误码,使用P0001、raise_exception:

do $g$
DECLAREuser_id int := 100;text_var1 text;text_var2 text;text_var3 text;text_var4 text;text_var5 text;
BEGINRAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user ID';
EXCEPTION WHEN OTHERS THENGET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,text_var2 = PG_EXCEPTION_DETAIL,text_var3 = PG_EXCEPTION_HINT,text_var4 = PG_EXCEPTION_CONTEXT,text_var5 = RETURNED_SQLSTATE;raise notice '%', text_var1;raise notice '%', text_var2;raise notice '%', text_var3;raise notice '%', text_var4;raise notice '%', text_var5;
END;
$g$;-- NOTICE:  Nonexistent ID --> 100
-- NOTICE:
-- NOTICE:  Please check your user ID
-- NOTICE:  PL/pgSQL function inline_code_block line 10 at RAISE
-- NOTICE:  P0001

3 主动抛出异常:给定错误码

do $g$
DECLAREuser_id int := 100;text_var1 text;text_var2 text;text_var3 text;text_var4 text;text_var5 text;
BEGINRAISE 'Duplicate user ID: %', user_id USING ERRCODE = 'unique_violation';
EXCEPTION WHEN OTHERS THENGET STACKED DIAGNOSTICS text_var1 = MESSAGE_TEXT,text_var2 = PG_EXCEPTION_DETAIL,text_var3 = PG_EXCEPTION_HINT,text_var4 = PG_EXCEPTION_CONTEXT,text_var5 = RETURNED_SQLSTATE;raise notice '%', text_var1;raise notice '%', text_var2;raise notice '%', text_var3;raise notice '%', text_var4;raise notice '%', text_var5;
END;
$g$;-- NOTICE:  Duplicate user ID: 100
-- NOTICE:
-- NOTICE:
-- NOTICE:  PL/pgSQL function inline_code_block line 10 at RAISE
-- NOTICE:  23505

4 特殊变量:注意sqlerrm会被异常文本替换掉,sqlstate永远是预定义好的错误码

do $g$
DECLAREuser_id int := 100;
BEGINRAISE EXCEPTION 'Nonexistent ID --> %', user_id USING HINT = 'Please check your user ID';
EXCEPTION WHEN OTHERS THENraise notice 'sqlstate: %', sqlstate;raise notice 'sqlerrm: %', sqlerrm;
END;
$g$;-- NOTICE:  sqlstate: P0001
-- NOTICE:  sqlerrm: Nonexistent ID --> 100

Postgresql中plpgsql异常处理方法与实例(RAISE EXCEPTION)相关推荐

  1. python中的异常处理try/except/finally/raise

    异常发生在程序执行的过程中,如果python无法正常处理程序就会发生异常,导致整个程序终止执行,python中使用try/except语句可以捕获异常. try/except 异常的种类有很多,在不确 ...

  2. java 实例方法直接调用超类的实例方法_Java继承关系中,父类方法使用实例变量和调用实例方法的探究...

    面向对象编程中,某一个实例方法使用实例变量和调用其它实例方法的情况是常见的.当存在继承关系时,这种情况就变得复杂起来.以下就对继承关系中,父类的某实例方法使用实例变量和其它实例方法的情况进行探究.因为 ...

  3. 在WCF中的异常处理方法

    在 WCF 中,客户端调用服务时,可能抛出的异常有以下三种类型. 1. 通讯异常.诸如网络错误,地址错误,服务器没有启动等等.这类异常多是 CommunicationException (或其具体继承 ...

  4. Postgresql中procedure支持事务语法(实例分析)

    相关 <Postgresql源码(60)事务系统总结> <43.8. Transaction Management> 20220928新增 从之前的分析可知(<Postg ...

  5. java中的异常处理语句_Java中实现异常处理的基础知识

    Java中实现异常处理的基础知识 异常 (Exception):发生于程序执行期间,表明出现了一个非法的运行状况.许多JDK中的方法在检测到非法情况时,都会抛出一个异常对象. 例如:数组越界和被0除. ...

  6. 【转】 ABAP中的异常处理 - TRY CATCH的使用实例

    在平时的ABAP开发中,需要捕获的异常通常为两种,一种是执行SQL,比如主键重复,INSERT语句字段类型不匹配等.还有就是RFC的通信错误,比如不能进行远程连接等.通常可以这么处理: 1.数据库异常 ...

  7. Java中的常用异常处理方法

    觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗? 1 OutputStreamWriter out = ... 2 ...

  8. PostgreSQL中的数据库实例、模式、用户(角色)、表空间

    2019独角兽企业重金招聘Python工程师标准>>> 本文参考:http://blog.csdn.net/kanon_lgt/article/details/5931522 htt ...

  9. C#中的扩展方法,Linq,IO和多线程的定义和实例

    前段时间学C#的上转型,泛型,lambda表达式这些应用的理解很费劲.学过之后我多多的练习了几天,接下来继续复习C#的其他一些概念,说实在的这些知识点学过之后很容易忘,但是都是很重要的,所以发表在博客 ...

最新文章

  1. 2019年CV领域,值得一看的综述文章!
  2. 中芯高层震荡未停:蒋尚义离职,梁孟松退出董事会,「台积电灵魂」加盟不足一年...
  3. 当引用com类dll时,在VS2005下会出现,dll虽然更换了但是引用没有更换或找不到的错误
  4. 删除SQL Server注册
  5. [js] callee和caller的区别和作用是什么?
  6. 谈Servlet与JSP
  7. 信息学奥赛一本通(1093:计算多项式的值)
  8. 在Go中使用Protobuf
  9. 城市社会经济专项规划之生态文化规划
  10. 阿里云服务器ip:端口号无法访问
  11. 程序员被怼!HR:对不起,我们不招“精通Excel”的程序员
  12. Go github.com/e421083458/golang_common/lib
  13. C语言之父丹尼斯·里奇:乔布斯脚下的巨人肩膀
  14. Java中如何判断一个集合中的一个元素不在另一个集合中?把不存在的元素移除
  15. ArcGIS教程:山地风景区景观规划中的可视性分析
  16. python基因差异分析_Biopython基因组分析
  17. nginx服务器404错误页面设置完整版
  18. 汉诺塔问题——递归算法
  19. 白光干涉仪(光学3D表面轮廓仪)与台阶仪的区别
  20. 关于微信支付的一些错误总结、微信支付48001

热门文章

  1. Ora01722 无效数字 报错带来的反省
  2. 《算法思维——一种问题驱动的思维方式》之第11篇:数据结构之动态栈篇——采用C#编程语言实现
  3. python遍历数组获取下标_如何在循环中获取索引(数组下标)
  4. 记2016年随手记的一次面试
  5. Activity背景透明和窗口化
  6. 创建自己的GitHub上传代码
  7. 北京市国资委监管企业名单
  8. tf.multiply、tf.matmul函数
  9. jstack命令相关参数解释(tid,nid,prio,os_prio)
  10. 新品上市调查方案-面临的问题