Postgresql中plpgsql异常处理方法与实例(RAISE EXCEPTION)
相关
《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
- 其中
DEBUG
到WARNING
都不会产生错误,只会打印日志,日志级别按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
- 例如:division_by_zero异常处理时,
部分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)相关推荐
- python中的异常处理try/except/finally/raise
异常发生在程序执行的过程中,如果python无法正常处理程序就会发生异常,导致整个程序终止执行,python中使用try/except语句可以捕获异常. try/except 异常的种类有很多,在不确 ...
- java 实例方法直接调用超类的实例方法_Java继承关系中,父类方法使用实例变量和调用实例方法的探究...
面向对象编程中,某一个实例方法使用实例变量和调用其它实例方法的情况是常见的.当存在继承关系时,这种情况就变得复杂起来.以下就对继承关系中,父类的某实例方法使用实例变量和其它实例方法的情况进行探究.因为 ...
- 在WCF中的异常处理方法
在 WCF 中,客户端调用服务时,可能抛出的异常有以下三种类型. 1. 通讯异常.诸如网络错误,地址错误,服务器没有启动等等.这类异常多是 CommunicationException (或其具体继承 ...
- Postgresql中procedure支持事务语法(实例分析)
相关 <Postgresql源码(60)事务系统总结> <43.8. Transaction Management> 20220928新增 从之前的分析可知(<Postg ...
- java中的异常处理语句_Java中实现异常处理的基础知识
Java中实现异常处理的基础知识 异常 (Exception):发生于程序执行期间,表明出现了一个非法的运行状况.许多JDK中的方法在检测到非法情况时,都会抛出一个异常对象. 例如:数组越界和被0除. ...
- 【转】 ABAP中的异常处理 - TRY CATCH的使用实例
在平时的ABAP开发中,需要捕获的异常通常为两种,一种是执行SQL,比如主键重复,INSERT语句字段类型不匹配等.还有就是RFC的通信错误,比如不能进行远程连接等.通常可以这么处理: 1.数据库异常 ...
- Java中的常用异常处理方法
觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗? 1 OutputStreamWriter out = ... 2 ...
- PostgreSQL中的数据库实例、模式、用户(角色)、表空间
2019独角兽企业重金招聘Python工程师标准>>> 本文参考:http://blog.csdn.net/kanon_lgt/article/details/5931522 htt ...
- C#中的扩展方法,Linq,IO和多线程的定义和实例
前段时间学C#的上转型,泛型,lambda表达式这些应用的理解很费劲.学过之后我多多的练习了几天,接下来继续复习C#的其他一些概念,说实在的这些知识点学过之后很容易忘,但是都是很重要的,所以发表在博客 ...
最新文章
- 2019年CV领域,值得一看的综述文章!
- 中芯高层震荡未停:蒋尚义离职,梁孟松退出董事会,「台积电灵魂」加盟不足一年...
- 当引用com类dll时,在VS2005下会出现,dll虽然更换了但是引用没有更换或找不到的错误
- 删除SQL Server注册
- [js] callee和caller的区别和作用是什么?
- 谈Servlet与JSP
- 信息学奥赛一本通(1093:计算多项式的值)
- 在Go中使用Protobuf
- 城市社会经济专项规划之生态文化规划
- 阿里云服务器ip:端口号无法访问
- 程序员被怼!HR:对不起,我们不招“精通Excel”的程序员
- Go github.com/e421083458/golang_common/lib
- C语言之父丹尼斯·里奇:乔布斯脚下的巨人肩膀
- Java中如何判断一个集合中的一个元素不在另一个集合中?把不存在的元素移除
- ArcGIS教程:山地风景区景观规划中的可视性分析
- python基因差异分析_Biopython基因组分析
- nginx服务器404错误页面设置完整版
- 汉诺塔问题——递归算法
- 白光干涉仪(光学3D表面轮廓仪)与台阶仪的区别
- 关于微信支付的一些错误总结、微信支付48001