oracle api小结

来源:互联网 发布:数据库设计的最后阶段 编辑:程序博客网 时间:2024/06/15 20:49

 前几个项目自己没有写过接口,都是负责前台的控制。来到这个项目上,才开始自己写,我是6月中旬开始做这个项目的,现在11月份,现在在去看6月份写的package,简直有点想吐了。原因有以下几点:

1. 简洁,扼要的说明没有附加。

2. n多功能综合到一起,全部放到一个包里,而不是根据功能模块划分。

3. 没有例外控制。

4. 写法不规范

5. 取值逻辑考虑不周全

 

针对于第一点,首先,一个让人容易理解你的包的是干唯一方法就是加上必要的注释,这样方便别人,也方便自己,不至于最后自己都看不懂你写的是干什么用的。看下面这个例子(我六月份写的):

e.g:

  PROCEDURE ship_bill_insert(
              p_business_id IN NUMBER ,
              p_site_id IN NUMBER,
              p_use_site_id IN NUMBER DEFAULT NULL,
              p_business_type IN VARCHAR2,
              p_created_by IN NUMBER,
              p_creation_date IN DATE,
              p_last_updated_by IN NUMBER,
              p_last_update_date IN DATE,
              p_last_update_login IN NUMBER,
              p_address IN VARCHAR2 DEFAULT NULL,
              p_enable_flag IN VARCHAR2 ,
              p_primary_flag IN VARCHAR2 DEFAULT NULL,
              p_object_version_number IN NUMBER DEFAULT NULL
            );

想必你看到这个方法,真的不知道如何去使用,连参数的说明都没有,如何去使用呢,不能盲猜吧。

现在写的程序:

CREATE OR REPLACE PACKAGE bf_isp_price_sku_cost_pkg AS
  -- Author  : Judev Qin
  -- Created : 2009-9-30
  -- Purpose : 商品结算成本维护

  /*==========================================================
  参数:     p_sku_cost_id           IN ID,唯一性索引
             p_sku_id                IN 商品ID
             p_business_type_id      IN 业态类型 OEM,QSP,Bexpromo,FME
             p_enable_flag           IN 是否有效
    Created : 2009-09-30  Judev Qin
    Modified:
 ==========================================================*/
  --插入一条记录至BF_PRICE_SKU_COST
  PROCEDURE insert_sku_cost(p_sku_cost_id          NUMBER,
                            p_sku_id               NUMBER,
                            p_business_type_id     NUMBER,
                            p_sku_cost             NUMBER,
                            p_enable_flag          VARCHAR2,
                            p_created_by           NUMBER,
                            p_creation_date        DATE,
                            p_last_updated_by      NUMBER,
                            p_last_update_date     DATE,
                            p_last_update_login    NUMBER
  );

这样的程序,如果另一个去使用,岂不是一目了然啊。

针对第二点,一个包封装的就应该是一个功能,这样不仅便于维护,而且风险性降低了,如果所有的功能都放到一个包里,岂不是一个地方出错,整个系统就要崩溃了。就拿我之前写的程序来看,我当时写了一个包,刚开始主要是负责用户,客户注册的模块,后来又加进来了些成本的维护功能,再后来又加一个用户登录的验证,主要是通过dblink从erp测试环境里取值。后来,出现这样的情况,由于erp测试环境数据库出错,导致该方法不能正确取值,导致了前台用户不能登录。可见这种危险性真是大啊,所以一定要分功能建包。

针对第三点,一个健壮的程序都是能够应对各种异常的,并能够正确处理掉。如果没有这些控制,你的程序就是不合格的,是不健康的。看我的程序(六月份的)

eg:

 select t.role_category
     into l_role_category
    from fnd_prv_role t
 where t.role_id = p_role_id;

表面上看没有问题,其实是危机重重。首先,有两个疑问,第一,你一定能保证p_role_id有值吗?其二,你一定能保证p_role_id对应的role_category一定有值吗?如果你能保证有,别人调用你api的时候,也保证能完全按照你的想法去做吗?所以还是改下程序吧,(现在)

begin

  --utl包对参数验证

  select t.role_category
     into l_role_category
    from fnd_prv_role t
 where t.role_id = p_role_id;

 exception when no_data_found then

     --处理一

   when too_many_rows then

    --处理二

  when others then

    --处理三

end;

这样一处理,你就可以无忧无虑的使用了。

针对第四点:最基本的就是参数的写法,IN 参数一般都是 p_xxxx,OUT 参数一般都是x_xxxx,定义的变量l_xxxx,package的名称前缀_pkg,如果写接口的话,都是三个包(pub,pvt,utl)。function和procedure要看具体功能来命名。

针对第五点:这一点其实至关重要,取值逻辑的错误,会导致你劳而无获。之前,在做一个运费计算的api,我当时写了:

。。。       

SELECT SUM(QOL.QUANTITY * BSC.OUTER_GROSS_WEIGHT) INTO l_trans_weight
          FROM QSP_ORDER_LINE QOL, BF_SKU_CUST_LINE_VL BSC
         WHERE QOL.SKU_CUST_ID = BSC.SKU_CUST_ID
           AND QOL.QSP_ORDER_HEADER_ID = p_header_id;

。。。

一个老顾问,看到这句话时,提示有问题,自己找了下也没发现什么。后来他告诉我,如果订单头没有订单行,你如何取值啊!所以大家对于取值一定要深思熟虑。

 

 

原创粉丝点击