RSS订阅
RSS订阅TT数据库

PL/SQL最差实践(二)

2008-7-14  选择字号:  | |
打印本文章

导读:本文基于若干项目中的代码,总结常见的PL/SQL最差实践,并提出针对性的解决办法。

关键词:PL/SQL 最差实践 Oracle

正在加载数据...

  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

  影响:可维护性、性能

  症状:execute IMMEDIATE ‘select A FROM TAB1’ INTO v_a;

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

  14. 对ROWID进行访问

  影响:数据一致性

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

  为什么是最差:

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

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


PL/SQL最差实践
 PL/SQL最差实践(一)
 PL/SQL最差实践(二)

来源:it168    作者:齐琨    
相关的新闻
本文只是一个例子,大家可以把它封装成一个通用函数进行实用。大家在试的时候将里面相应的其它进制的数值换成自己的数据就可以了……
PL/SQL是由构造程序、统计数据、模块性以及异常管理等建模观念发展而来的。它扩展了ADA程序语言。ADA扩展了Pascal程序语言,包括配置、比较运算符以及单引字符串分隔符。
随便在什么地方,只要是BEGIN和END之间,就可以使用DBMS_OUTPUT.PUT_LINE(output); 而这有个问题,就是使用该函数最多只可以显示255个字符,否则缓冲区会溢出。
个人认为ORACLE实在不适合来讨论算法,所以只挑了一个比较简单的算法进行计算,多项式为:PI=2+1/3*(2+2/5*(2+3/7*(2+…(2+N/(2N+1))…))),上一篇之所以给出……
经常可以碰到Oracle的内部错误ORA-600和ORA-7445,这个PL/SQL的内部错误还是第一次碰到。在11g中建立10.1或10.2基表的物化视图,就会引发这个错误。

本专题介绍了SQL Server服务代理相关方面的知识,包括SQL Server服务代理基础知识的概述、消息类型、契约、队列、服务和路由、SEND命令和RECEIVE命令、性能方面的改进以及对运行状况的监控等等。

无论你是否计划将SQL Server数据库转换服务(DTS)包迁移到SQL Server集成服务(SSIS)或在SQL Server 2005里运行DTS包,都需要专家的一些建议。这一指南主要是包括SSIS的相关基础知识、技巧帮助你进行SSIS调整,还介绍了SSIS有经验的一些用户的具体信息等等。

子查询是一个嵌套在SELECT、INSERT、UPDATE 或DELETE语句,或者另一个子查询里的查询。一个子查询可以返回一行或多行结果给父查询。标量子查询是只返回一个值的查询:只有一个字段的一行记录。标量子查询可以在SQL语句的大多数位置,其中你可以使用一个表达式或一个实际值。
最新更新
专家答疑
技巧
Michael Hillenbrand
你能解释一下数据库公程师、数据库架构师以及数据库管理员之间有什么区别吗?数据库管理员:这是目前最普遍使用的对从事数据库相关的工作的人的头衔。数据库管理员是指……
Brian Peasland
对5GB大小的Oracle 7.3存档或删除的最佳办法是什么?为了便于管理机构查询,这些数据至少需要再用20年的时间。我们担心将来我们不能对它重新获取并迁入一个更新的……
Rudy Limeback
如何创建一个约束限制2007年1月1日之前的日期被录入?用CHECK约束就可以。如下面的示例……