Chinaunix首页 | 论坛 | 博客
  • 博客访问: 686045
  • 博文数量: 845
  • 博客积分: 5000
  • 博客等级: 大校
  • 技术积分: 5015
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-15 16:22
文章分类

全部博文(845)

文章存档

2011年(1)

2008年(844)

我的朋友

分类:

2008-10-15 16:25:59

        1. 超长的PL/SQL代码

           影响:可维护性,性能

           症状:

            在复杂的企业应用中,存在动辄成百上千行的过程或上万行的包。

        为什么是最差:

            太长的PL/SQL代码不利于阅读,第三方工具在调试时也会出现代码行混乱等问题。PL/SQL对象(存储过程、包、函数、触发器等)行数上限约为6000000行,但实际工作中,当包大小超过5000行就会出现调试问题。

        解决之道:

            PL/SQL代码在执行前会被加载到shared pool中,shared pool以字节为单位,UNIX下为64K,桌面环境下为32K,可以通过查询数据字典USER_OBJECT_SIZE的PARSED_SIZE字段查看对象大小。对于较大的包,应采用拆包策略,抽取复用部分,减少重复代码;对于较大的存储过程,应将存储过程组织到包中,易于管理;对于较大的匿名块,应将匿名块重新定义成子过程保存在数据库中。

        2. 脱离控制的全局变量

        影响:可维护性

        症状:在包中使用了全局变量,在多个位置对全局变量进行操作。

        CREATE OR REPLACE PACKAGE BODY PKG_TEST IS

        GN_全局变量 NUMBER(12, 2);

        PROCEDURE 过程A IS

        BEGIN

        GN_全局变量:=1;

        END;

        PROCEDURE 过程B IS

        BEGIN

        GN_全局变量:=2; -- 这里对全局变量进行了另外的操作

        END;

        为什么是最差:

           全局变量可以在整个包范围内被访问到,因此对全局变量的跟踪和调试会比较困难。如果变量是在package中定义的,变量还可以被其他包访问,这将会更为危险。

        解决之道:

           减少或取缔全局变量的使用,对于要在过程间交互的变量,通过参数传递来实现。如果必须使用全局变量,应对全局变量进行get/set函数封装,规范对全局变量的访问。

        3. PL/SQL中嵌入复杂SQL语句

        影响:可维护性

        症状:

        在PL/SQL代码中嵌入SQL语句,如:

        ...

        PROCEDURE 过程A IS

        BEGIN

        UPDATE T_A SET COL1 = 10;

        END;

        PROCEDURE 过程B IS

        BEGIN

        DELETE FROM T_A WHERE COL1=10;

        END;

        ...

        为什么是最差:

        ? PL/SQL代码中嵌入SQL语句使得代码含义变得难于阅读和理解

        ? 在多个位置对表进行访问,不利于SQL优化

        解决之道:

        ? 将分散SQL语句进行封装,例如上例中的删除语句,可以封装为“prc_删除T_A()”过程参数为T_A的type类型,对T_A的删除操作都委托此过程处理,当T_A表增加或删除字段时,主要的变化都集中在这些过程中,对其他逻辑影响较少

        ? 对SQL的优化集中在封装的过程中

        4. “异常”的异常处理

        影响:可维护性,健壮性

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

        PROCEDURE 过程A(错误代码 out varchar2,错误信息 out varchar2) IS

        BEGIN

        ...

        UPDATE T_A SET COL1 = 10;

        SELECT ... FROM T_A WHERE ...;

        DELETE FROM T_A WHERE COL1 = 20;

        ...

        EXCEPTION

        WHEN OTHERS THEN

        ...

        END;

        为什么是最差:

        整个过程只有一个WHEN OTHERS 的异常段,示例中的三个语句发生的异常只能被最外层捕捉,无法区分发生异常的种类和位置。

        解决之道:

        ? 不使用WHEN OTHERS捕捉所有异常,例如不应该捕捉NO_DATA_FOUND异常,使用专用的Exception来捕捉特定的异常。

        ? 声明自己的异常处理机制,处理与业务相关的异常,将业务异常与系统运行期异常分开处理。

        ? 自定义完整的异常信息,异常信息中包含异常发生时的场景。

[1]  

【责编:michael】

--------------------next---------------------

阅读(377) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~