返回首页DA系统C#IDE文件同步服务屏保 今天是: 2026-05-05    "立夏"  夏季的第一个节气,表示盛夏时节的正式开始

搜索
热搜: linux 技术
Hi~登录注册
查看: 1850|回复: 0

[转载] 【转载】达梦数据库存储过程的异常处理

[复制链接]
发表于 2024-12-31 12:03:26 | 显示全部楼层 |阅读模式
达梦数据库存储过程的异常处理


一、异常的分类
1.1编译异常
编译异常是指在编辑器中执行存储过程编译的时候的报错,一般情况下是由于语法错误导致的,如果不修改程序就无法执行,需要由程序员修复。





如图所示,在20行多加了一个多余的";",在编译的过程中会提示错误信息,并指出大概的位置。

提示的位置信息仅供参考,因为在存储过程代码过于复杂时,编辑器无法精准定位到报错的准确为止,需要自行排错。(这一点,在开发过程中,最让人难受)

1.2运行异常
运行异常是指存储过程在执行的过程中发生的异常情况,例如:除数为0异常,字符串转数字异常等等。

二、异常的类型
2.1内部定义异常
内部定义异常是指系统在安装好了之后就定义好了的异常,在发生该类异常的时候,根据报错的信息和错误编码可以定位到错误原因,

demo:除数为0


procedure PRO_TEST_MAIN(v_etl_date in date,v_sqlcode out number) as
v_sql  varchar(1000);
v_cont varchar(200);
v_job_id number;
v_proc_name varchar(100);
v_pkg_name varchar(100);
/***
*
*
* ***/
begin

v_job_id = round(dbms_random.value(1,999999),0);
v_pkg_name = 'PKP_PACKAGE_TEST';
v_proc_name = 'PRO_TEST_MAIN';
v_sqlcode = 0 ;

select 1/0 from dual;
print('hello dm');



end PRO_TEST_MAIN;





2.2用户自定义异常
用户定义异常对应于用户定义错误,由 用户显式抛出。
demo:


procedure PRO_TEST_MAIN(v_etl_date in date,v_sqlcode out number) as
v_sql  varchar(1000);
v_cont varchar(200);
v_job_id number;
v_proc_name varchar(100);
v_pkg_name varchar(100);
v_num number;
/***
*
*
* ***/
begin

v_job_id = round(dbms_random.value(1,999999),0);
v_pkg_name = 'PKP_PACKAGE_TEST';
v_proc_name = 'PRO_TEST_MAIN';
v_sqlcode = 0 ;


/**
除数为0
select 1/0 from dual;
**/


v_num = 1 ;
--假设v_num=1的值是我们得到的一个错误的结果,这时我们想要手动结束
if(v_num = 1) then
  RAISE_APPLICATION_ERROR(-20001, 'v_num is not what i want!');
end if;
print('hello dm');



end PRO_TEST_MAIN;





语法如下:

RAISE_APPLICATION_ERROR(error_number,error_message,[keep_errors]);

其中,error_number是一个错误编码(由用户自定义),值在-20000到-20999之间,error_message是与该错误相连的错误消息文本(通常用来显示错误提示信息),它最大不能超过512个字符。Keep_errors是一个boolean值。该参数是可选的(可以不写,默认为FALSE)。如果keep_errors为TRUE,则这个新的错误将加在已产生的错误列表之后。如果keep_errors为FALSE,则这个新错误将代替当前的错误列表。

三、异常的兜底策略
先上代码


procedure PRO_TEST_MAIN(v_etl_date in date,v_sqlcode out number) as
v_sql  varchar(1000);
v_cont varchar(200);
v_job_id number;
v_proc_name varchar(100);
v_pkg_name varchar(100);
v_num number;
/***
*
*
* ***/
begin

v_job_id = round(dbms_random.value(1,999999),0);
v_pkg_name = 'PKP_PACKAGE_TEST';
v_proc_name = 'PRO_TEST_MAIN';
v_sqlcode = 0 ;


/**
除数为0
select 1/0 from dual;
**/


v_num = 1 ;
--假设v_num=1的值是我们得到的一个错误的结果,这时我们想要手动结束
if(v_num = 1) then
  RAISE_APPLICATION_ERROR(-20001, 'v_num is not what i want!');
end if;
print('hello dm');

exception
when others then
print(SQLCODE);--打印错误编码
print(SQLERRM);--打印错误提示信息
print('异常兜底');
v_sqlcode = 1;

end PRO_TEST_MAIN;




我们可以看到之前手动报错的红色信息没有了,变成黑体字的提示信息,并且显示了“异常兜底”,最终显示"一条语句执行成功",说明手动报错的内容被最后的异常处理给处理掉了。
那么我们可以通过这种方式将错误编码和错误信息插入到日志表中记录下来,便于后续排错。
使用场景:




假设M是一个主程序,M中需要去分别调用a,b,c三个存储过程(a,b,c三个存储过程各自独立运行,互不影响),那么可以a,b,c中都加上异常兜底的代码。那么M能够很顺利的依次将a,b,c分别执行完成。假设a执行过程中报错,b和c执行成功,那么从执行结果日志中就能直接排查出是a报错,b和c运行正常,那么只需要将a中的错误修复即可。




总结
本文主要介绍了达梦数据库的存储过程,在日常开发中对于异常的相关处理策略,灵活的处理异常,对于程序员快速定位错误,记录跑批日志等,有非常大的帮助,希望这边文章能帮到大家少踩坑。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册成为修仙之旅的少年~

x
游客
回复
*滑块验证:

DA论坛飞机票来了~
快速回复 返回顶部 返回列表