现在的位置: 首页 > 数据库 > 正文

存储过程开发规范、基础知识、常见问题和注意事项等

2017年07月29日 数据库 ⁄ 共 2224字 暂无评论 ⁄ 阅读 86 次
文章目录

规范类

在存储过程开始前,应该存储过程说明注释,如:

版本号如V1.0.0,小变更则v1.0.1,大变更则v1.1.0,重构则v2.0.0。所有涉及到的表,及表描述最好也添加一下。

对象命名一般使用有实际意义的英文单词缩写,一般不应超过5个,新对象命名一般按“系统_模块_功能”格式。老对象命名继承原有规则,同字段在不同表应保持字段名和类型一致。

常见对象命名如,主外键PK_表名、FK_表名、索引IDX_表名_字段名、位图索引BIT_表名_字段名、存储过程PRC_系统_模块_功能、函数FN_系统_模块_功能、序列SEQ_表名、视图V_表名、类型TYP_类型名、入参i_参数名、o_参数名、变量v_变量名、游标cur_游标名。

存储过程中独立的模块之间应该有空行,独立性大的模块前应有多行注释说明。循环和判断开始和结束语句后要加注释注明该模块内容,以便于调试时对模块进行独立测试。

基础知识

创建存储过程

游标

游标定义后,需要再定义一个接受游标数据的变量(类数组),使用该变量“变量名.游标字段名”。

动态SQL

动态SQL使用,定义一个变量接受动态sql的语句,变动部分用变量传值,执行用execute,如:

v_sql :=

'SELECT count(1)  FROM ' || v_tablename || ' WHERE ‘ || v_col || ' = ' ||v_value

EXECUTE IMMEDIATE v_sql INTO v_cnt;

循环

  1. 无限或简单循环

LOOP

EXIT WHEN  (退出循环条件);

END LOOP;

  1. while循环

WHILE condition

LOOP

executable_statements;

END LOOP;

  1. for循环

基于数字的for循环:

FOR v_index IN first_value .. last_value

LOOP

executable_statements;

END LOOP;

  1. 基于游标的for循环:

FOR v_cur IN my_cursor

LOOP

executable_statements;

END LOOP;

数组(内存表)

  1. 一个字段

  1. 定义多个字段

定时作业

需要注意一点,在新建job时,dbms_job.submit()中的what值应该是一个存储过程名或一段SQL,最后必须有分号“;”,否则会提交失败。

注意事项

空值参与计算,在空值参与计算时结果会是空值,为避免该情况,需要在计算时将可能是空值的字段加nvl函数转换成数字;

select条件中有in或not in,子查询中有空值需要特别注意结果。

第一行处理的数据进行单独的初始化,一般情况下,业务处理逻辑的第一行数据生成需要单独考虑,是否需要采用判断进行初始化;

最后一行处理的数据进行单独的处理,在部分情况下,业务处理的最后一行可能需要进行单独处理,若需要则使用分支判断单独处理该情况;

除数为零zero_divide异常,避免该异常可用decode函数将0强制转为1;

变量赋值no_data_found异常,为避免该异常可在外层用一个count(1)然后用if判断,将无值的情况用判断剔除出去,或者再嵌套一个匿名块用异常去处理掉空赋值;

变量赋值too_many_rows异常,为避免该异常要事先明确数据逻辑,若结果确实可能多行则考虑使用数组型变量;

非法字符转数字invalid_number异常;

编程思想与程序构造

编写程序前,最好先用文字将数据处理流用例和异常数据用例写出来,在写程序时可以直接检验程序的处理方式是否有问题。这样就规避了,在程序完成后,使用正式数据测试,结果bug一大堆,甚至整体逻辑有错的情况。

在解决程序问题时,若遇到计算特别复杂的情况,我们不妨跳出程序本身,从业务上思考,能否规避这种程序计算的复杂性,可能这便是架构师的思维方式。如最近遇到的几个例子,有一个跟外部交互的系统接口,现要计算对方接口处理数据的效率。正常情况下A发出一个请求,有一个发出时间一个成功发出时间,B回传一个响应,有一个响应时间一个响应成功时间,但异常情况下可能A发出多个请求,或B回传多个响应。此时要计算A最后一个请求和B最后一个响应之间的时间差,且中间涉及行列转换等。若从程序逻辑上处理较复杂,现从业务上考虑,给一次独立的请求一个唯一标识ID,传到B处,B处理完成后将该ID和完成时间回传过来,这样只根据ID去计算两个时间,就很大程度上避免了复杂的逻辑计算。

另外一个例子,系统中用户可以自定义设置某项业务的工作日,也可以不设定,之后有很复杂的一段逻辑计算。若在程序中判断用户是否设置工作日,然后再计算则程序逻辑相对较复杂。跳出程序逻辑,从业务上考虑,可以直接在系统中直接给用户设置全工作日初始化进数据库,若用户重新设置工作日则按前台控制直接修改了数据库,否则还是原初始化后的工作日。这样,直接在数据库中做一次逻辑计算就好了,去除了初始化和判断等过程,让程序逻辑更简单,有故障时也更容易定位故障了。

» 声明:本站文章源于个人经验总结或书籍、互联网转载,内容仅用于个人学习,请勿转载,否则后果自负!

给我留言

留言无头像?