PL/SQL最差实践(二)

日期: 2008-07-13 作者:齐琨 来源:TechTarget中国

  5. 固定的变量长度和变量类型


  影响:可维护性
  症状:当声明基于字段类型的变量时,尤其是varchar2类型,直接使用固定长度声明。


  为什么是最差:


  这种硬编码的变量大小很可能与数据库中实际大小不符


  如果字段的类型、大小等发生变化,还需要到PL/SQL中调整变量
  解决之道:


  使用%Type声明与字段类型相关的变量。


  6. 不做单元测试


  影响:健壮性


  症状:PL/SQL代码中蕴含大量的业务逻辑,这些逻辑编写完毕后,没有提供合适的单元测试用例用于验证。


  为什么是最差: 不做单元测试的危害这里就不再废话了。


  解决之道:


    PL/SQL并没有提供诸如JUnit之类易用的单元测试工具。现在有一些开源工具可以使用。使用utPLSQL(http://utplsql.sourceforge.net/)工具进行单元测试,或DBUnit进行二次开发,满足不同应用的需要。


  7. 使用代码值而不使用代码名称


  影响:可维护性


  症状:我们看下面的代码:


  方法1:


  V_sex:=’1’; — 男


  方法2:


  CONST_MALE CONSTANT VARchar2(1) := ’1’; — 定义常量 男


  V_sex:=CONST_MALE;


  为什么是最差:


  从例子中可以看出,同样是使用性别,方法1是直接使用代码值,方法2是使用常量,看上去似乎方法2要比方法1麻烦一些,但方法2比方法1更为直观,代码的可读性也更好,代码的阅读者不需要关注“1”代表什么含义。


  当其他项目男性性别定义修改为“2”时,采用方法1编码的程序需要仔细查找每一段代码,容易产生错误,而采用方法2编码的程序只修改常量定义即可。


  解决之道:


  将常量定义放入到公共的代码包中,供其他程序共享,所有涉及到代码值的比较、引用等都必须使用常量名,而不能直接书写代码值。对于一些复杂的代码值间的关系可以进一步封装,以函数的方式提供调用。


  8. 不对PL/SQL对象进行配置管理


  影响:可维护性


  症状:PL/SQL对象(package、package body、trigger、procedure、type、type body、函数等)的代码没有使用配置管理工具进行维护和更新。


  为什么是最差:


   因为Oracle内部结构的差异,对象的管理具有一定的难度,尤其是在并行开发的情况下。
 
  对象职责划分不清,造成多人同时修改一个对象,在编译时,如果后来者没有获取最新的代码,会造成前一个开发人员修改的代码被覆盖。


  Oracle对象不能追溯既往,数据库中只能保存最新


  解决之道:


  规范开发过程,以配置管理工具上的PL/SQL代码为最新。
 
  使用第三方插件减少同步工作量,如PL/SQL Developer下的VCS版本控制插件。


  9. IF … ELSE …的坏味道


  影响:可维护性


  症状:大量使用IF … ELSE


  为什么是最差:


    大量存在IF/ELSE,造成代码逻辑混乱、不易修改。无论是PL/SQL还是其他编程语言,这种代码都已经飘着“bad smell”了。


  解决之道:
 
  使用Oracle数据库的继承特性,通过type实现对象的继承,利用策略模式封装差异,对外提供统一的调用接口


  将频繁使用的IF/ELSE代码重构为单独的过程或函数,供其他代码复用


  10. 在非自治事务中控制事务


  影响:数据一致性


  症状:
  在PL/SQL非自治事务代码中控制事务,例如:
 
  PROCEDURE 过程A(错误代码 out varchar2,错误信息 out varchar2) IS
  BEGIN
  …
  SAVEPOINT A;
  update T_A SET COL1 = 10;
  COMMIT;
  delete FROM T_A where COL1 = 20;
  ROLLBACK TO A;
  …
  EXCEPTION
  WHEN OTHERS THEN
  …
  END;


  为什么是最差:


  这种行为是我认为最差实践中危害最大的一种。随处可见的事务控制代码会造成数据不一致,引发的问题难于跟踪和调试。
 
  解决之道:


  由调用者决定何时提交或回滚事务。


  对于需要特殊事务管理的过程如记载日志,使用自治事务。


  11. 不使用绑定变量


  影响:性能


  症状:直接使用值而不使用绑定变量进行查询。尤其是在拼写sql的程序中,这种情况更突出。
  为什么是最差:
 
    这是一个常见问题,当代码中大量充斥固定的代码值时,数据库引擎每次都需要重新解析,不能使用既有的执行计划。


解决之道:对于这种经常执行的语句,使用绑定变量而非实际参数值执行。


  12. 慎用ROWNUM=1


  影响:可维护性、数据一致性


  症状:在读取数据时,有时只需要取一行,这时where条件中就会用到ROWNUM=1。
 
  为什么是最差:


    之所以将这个实践评成最差,是因为笔者在实际工作中曾经遇到过这类问题,跟踪和调试都很困难。ROWNUM本身的处理顺序是在ORDER BY 之前,所以当ROWNUM=1时产生的结果很可能是随机的。


  解决之道:了解要查询数据的含义,使用其他条件限制结果集。


  13. 灵活的动态SQL


  影响:可维护性、性能


  症状:&#101xecute IMMEDIATE ‘select A FROM TAB1’ INTO v_a;


  为什么是最差:动态SQL失去了编译期检查能力,将发生问题的可能性推迟到运行期。动态SQL也不利于优化,因为只有在运行期才能得到完整的SQL语句。
解决之道:尽量避免使用动态SQL,对于易变的业务逻辑可以抽取到中间层实现。


  14. 对ROWID进行访问


  影响:数据一致性


  症状:使用ROWID作为数据更新、删除的where条件


  为什么是最差:


    ROWID属于Oracle底层存储结构,会随着数据的迁移、导入、导出发生变化,而业务逻辑则不应依赖底层存储结构。


  解决之道:使用主键进行数据操作。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

作者

齐琨
齐琨

相关推荐