存储过程实现可扩展灵活接口

序言

本文分享一个通过数据库(ORACLE)的存储过程,遵循“对修改封闭,对增加开放”的开闭原则,实现的可扩展性极强的灵活接口方案。

背景

本人从事离散型MES系统的开发工作,近期负责了一个PCBA(电子、手机)行业的MES系统二开工作。PCBA行业使用ATE工具(自动测试工具)进行写号、查号、置标志位等工作,写号查号等相关数据需要与MES系统进行数据交互,同时MES系统也需要管控ATE工具的作业流程。如查号必须在写号后,没有写号的工具不能进行查号等流程管控。由于ATE工具的测试不须人员参与,所以MES系统需要开发相关接口给ATE工具端调用,进行数据交互和流程管控等工作。

MES系统前期已有途程检查,分配IMEI、MAC、BT数据,过站等相关基础接口可供ATE工具调用,基本能满足要求。但在面对某些客户定制化的需求时(如上传软件版本、记录测试内容),就必须在原有接口的基础上增加或修改程序,然后把C#编写的dll封装成COM组件(因为ATE工具使用C++编写的),更新文档,再通知ATE工具编写人员重新连入新版本进行编写和调试,最后再更新现有工具的所有版本。别看流程描述起来比较简单,但实际操作起来涉及到沟通、部门协作等问题,非常繁琐累人。

基于上述原因,笔者思考是否有一个方案能够灵活面对客户的定制化需求,又不需涉及到太多变更,特别是重新编译、重新连入和更新等操作。有志者事竟成,经过一番研究与思考后,笔者决定采用“存储过程”来进行实现。

整体方案

方案详述

为了更好的讲述该方案,下面将以代码(或伪代码)的方式进行讲述。

接口方法调用存储过程

public bool SetATEData(string iCmdType, string iText, out string oText, out string oErrMessage)
        {
            return ExecProc.ProcInputPara(iCmdType, iText, out oText, out oErrMessage);
        }

对该方法的详细介绍如下:

Bool SetATEData(String iCmdType, String iText, String oText, String oErrMessage)

参数说明

         iCmdType----传入的接口代码,如1001;可自定义

         iText-----------传入此接口参数列表,采用键值对的方式传入,以“|”分隔,例如:

       “Field1=Value1|Field2=Value2|Field3=Value3|... … ”(也可定义其他分隔符,如有需要,请考虑转义字符)

   oText----------如接口需要返回参数的列表,采用键值对的方式输出,以“|”分隔,例如:

       “Key1=Value1| Key2=Value2| Key3=Value3|... … “,可为空

   oErrMessage----当方法返回false时,传出具体的出错信息

注:

ExecProc.ProcInputPara(iCmdType, iText, out oText, out oErrMessage)是笔者写的一个静态方法,用于调用存储过程。实际应用中需要自行编写。为了做好记录,笔者也会上传该静态类,仅供参考。

存储过程统一入口

根据传入的iCmdType查询对应的存储过程名称,若存在则动态执行该存储过程。

储存存储过程的表格结构如下所示:

存储过程的代码(ORACLE 11g版本)如下所示:

CREATE OR REPLACE PROCEDURE PROCDLLBASE (ICMDTYPE IN VARCHAR2,ITEXT IN VARCHAR2,OTEXT OUT VARCHAR2,OERRMSG OUT VARCHAR2,ORESULT OUT INTEGER)
AS
v_Sql varchar2(4000);
v_ProcName TBLPROCGROUP.PROCNAME%TYPE;
i_ProcCount integer;
BEGIN
  SELECT COUNT(1) INTO i_ProcCount from TBLPROCGROUP where PROCID=ICMDTYPE;
  IF i_ProcCount=0 THEN
     OERRMSG:='CMDTYPE2PROC_NOT_FOUND';
     ORESULT:=0;
     RETURN;
  END IF;

  SELECT PROCNAME INTO v_ProcName from TBLPROCGROUP where PROCID=ICMDTYPE;
  v_Sql:='begin '|| v_ProcName || '(:itext,:otext,:oerrmsg,:oresult);end;';
  EXECUTE IMMEDIATE v_Sql using in ITEXT,out OTEXT,out OERRMSG,out ORESULT;
     EXCEPTION
      WHEN OTHERS THEN
            ROLLBACK;
      OERRMSG:='CMDTYPE2PROC_UNKNOWN_ERROR';
      ORESULT:=0;
      RETURN;
END PROCDLLBASE;

 子存储过程

根据业务需求编写对应的存储过程,并将iCmdType与存储过程名称关联后储存至TBLPROCGROUP表格中。

子存储过程中涉及到输入参数的解析,输入参数的非空性校验及重复性校验,这些都是保证系统稳健性的需要。

总结

通过上述方案,当客户再有其他需求时,只需根据业务逻辑创建存储过程并分配iCmdType与之关联即可实现接口的扩展。

ATE工具开发人员也只需要按照文档的格式传参并解析输出参数即可,免却编译程序,封装COM组件及更新的繁琐流程。

posted @ 2016-12-05 17:29  蜡笔小黄  阅读(1902)  评论(4编辑  收藏  举报