文章
· 九月 28, 2022 阅读大约需 12 分钟

关于%Dictionary.CompiledClass类在实际业务中的一些应用

简单分享下在医院实际业务过程中%Dictionary.CompiledClass的一些应用。
一,Query查询出来的数据直接存表。
       我们经常会遇到一些突如其来的检查,如:飞行检查,审计检查等等,往往一下子要查询几年的各种数据,每种数据涉及字段还非常多,数据之间还要求对上,查询耗时长,数据对比难度大,此时,我们需要把查询出来的数据直接存到临时表,数据核对和修改直接在临时表中完成,核对好的数据直接在sqldbx或者水滴等查询工具中整表导出,效率会高一些。
       具体实现:按照数据要求,把表建好,Query输出字段和表字段顺序一致,按日期每天调用Query查询和插入,记录异常数据,后续单独处理。
       优点:效率明显提高,数据核对和修改、导出很方便,避免了数据量大,多次查询耗时长问题。
       缺点:数据量大会占用存储,记得删。
// W ##CLASS(lizw.CloseCycleData).insertDayByDay("2022-01-01","2022-06-30")
ClassMethod insertDayByDay(sd, ed)
{
    k ^tmplzw("insertFromQyeryTestpara",$j)
    S classOBJ=##class(%Dictionary.CompiledClass).%OpenId("lizw.User.CloseCycleDateTime") //##class(lizw.User.CloseCycleDateTime).%New()
    if (classOBJ.%IsA("%Library.Persistent")||(classOBJ.%IsA("%RegisteredObject"))){
        s className=classOBJ.Name
        s pkgName=classOBJ.SqlSchemaName //%PackageName()
        s key=""
        s:$d(^oddCOM(className)) ClassName=className
        q:ClassName=""
        f {
            s key=$o(^oddCOM(ClassName,"a",key))
            q:key=""
            i $e(key,1)="%"{
                continue
            }
            s private=$g(^oddDEF(ClassName,"a",key,35))
            if private=1{
                continue
            }
            continue:$g(^oddDEF(ClassName,"a",key,11))=""
            ;B ; ClassName
            s ^tmplzw("insertFromQyeryTestpara",$j,$g(^oddDEF(ClassName,"a",key,11)))=$g(^oddDEF(ClassName,"a",key,47))    
        }
    }
    s parakey="",fields=""
    f  s parakey=$o(^tmplzw("insertFromQyeryTestpara",$j,parakey)) q:parakey=""  d
    .i fields="" s fields=^tmplzw("insertFromQyeryTestpara",$j,parakey)
    .e  s fields=fields_","_^tmplzw("insertFromQyeryTestpara",$j,parakey)
    ;b ; fields
    s sd=$zdh(sd,3)
    s ed=$zdh(ed,3)
    f dd=sd:1:ed d
    .s stdate=$zd(dd,3)
    .w stdate_"^"_$zt($p($h,",",2)),!
    .d ..insertFromQyeryPublic("lizw.CloseCycleData","GetLabTransferDateTime","lizw.User.CloseCycleDateTime","lizw_User.CloseCycleDateTime",stdate,stdate,"","",fields)
    q "OK"
}

// W ##CLASS(lizw.CloseCycleData).insertFromQyeryPublic("lizw.CloseCycleData","GetLabTransferDateTime","lizw.User.CloseCycleDateTime","lizw_User.CloseCycleDateTime","2022-01-01","2022-01-01")
ClassMethod insertFromQyeryPublic(queryClass, queryMethod, userName, tableName, arg1 = "", arg2 = "", arg3 = "", arg4 = "", arg5 = "")
{
  s totalNum=0
  try{
   Set queryrset=##class(%ResultSet).%New(queryClass_":"_queryMethod)
    do queryrset.Execute(arg1,arg2)
    Set columns = queryrset.GetColumnCount()
   S SQLresult=##class(%SQL.Statement).%New()
    While (queryrset.Next()) {
        s values=""
        f inum=1:1:columns d
        .i values="" s values=""""_queryrset.GetData(inum)_""""
        .e  s values=values_","_""""_queryrset.GetData(inum)_""""
        s sqlStr ="INSERT INTO "_tableName_" ("_fields_") VALUES ("_values_")"
        s Status=SQLresult.%Prepare(sqlStr)
        s SSRET = SQLresult.%Execute()                
       ; b ; SSRET.%SQLCODE
       i SSRET.%SQLCODE'=0 w arg1_"^"_SSRET.%SQLCODE,!
       i SSRET.%SQLCODE'=0 b ;  SSRET.%SQLCODE
        s totalNum=totalNum+1
    }
   }
  catch{
      s ^lzw("insertFromQyeryErr",+$h,$zts)=$g(arg1)_"^"_$g(arg2)_"^"_$ze
      }
    q totalNum
}

二,病案数据、医保结算清单数据等上传,上传数据组织成xml或json等格式,上传数据存表记录。
      在实际业务中,经常需要做一些数据上报、第三方接口等等,数据传输格式往往是xml或json等同格式,我们一般会建一个类,Property 就是需要上传的字段,继承%XML.Adaptor, 输出时调用DO Obj.XMLExportToString(.XML,"Response")输出xml。在与第三方交互时,我们往往需要记录给第三方的入参及返回,此时,我们通过%Dictionary.CompiledClass可以很方便的把xml类的数据存储到表。
      具体实现:按照接口要求,把注册类和持久类建好,表字段名一致,转换时按名称匹配比较方便,否则要做映射。
       优点:把数据上传和合并合到一起了,注册类数据存储到持久类也很方便。如果按正常的步骤,先把数据存起来,再组织xml会比较麻烦一些,特别是上传数据量大,涉及到一堆子表的情况下。
       缺点:毕竟多了一步数据存储,会影响效率。如果是走平台或者不需要记录数据就不用这样做。
// 建一个注册类, 转换xml
Class lizw.yb.JSQDXML Extends (%RegisteredObject, %XML.Adaptor)
{

Parameter XMLIGNORENULL = 1;

Parameter XMLIGNOREINVALIDTAG = 1;

Parameter XMLNAME = "Response";

///     必填    
Property EpisodeID As %String(CONTENT = "就诊号", MAXLEN = 200, XMLNAME = "EpisodeID");

///     人员编号
Property psnno As %String(CONTENT = "人员编号", MAXLEN = 200, XMLNAME = "psn_no");



}

// 建一个持久类, 存储数据
Class lizw.User.JSQDSAVE Extends %Library.Persistent [ ClassType = persistent, Owner = {_SYSTEM}, Not ProcedureBlock, SqlRowIdName = JSQD_rowid, SqlTableName = JSQDSAVE_Data ]
{

Parameter XMLIGNOREINVALIDTAG = 1;

Parameter XMLIGNORENULL = 1;

///     必填    
Property EpisodeID As %String [ SqlColumnNumber = 2, SqlFieldName = JSQD_EpisodeID ];

///     就诊ID    
Property psnno As %String [ SqlColumnNumber = 3, SqlFieldName = psn_no ];



}

/// Return:        出院诊断、手术取病案首页上的    w ##class(lizw.JSQDInsert).GetChargeBillDataGJYB("34430780")
ClassMethod GetChargeBillDataGJYB(AEpisodeID As %String, AIsEMR As %String = "")
{
s ModelObj = ##class(lizw.yb.JSQDXML).%New()
        //出院科室
    s RMYYCYKS=##Class(EMRservice.HISInterface.PatientInfoAssist).DisDept(AEpisodeID)
    s CTLOCDr=$p(RMYYCYKS,"^",1)
    s HOSpId=$P(^CTLOC(CTLOCDr),"^",22)
    // 取系统参数
    s Hospital=""
    s ModelObj.EpisodeID=AEpisodeID
    s (cykssj,setlid,mdtrtid,adminfo,jjpayStr)="0"
    &sql(SELECT max(INPAY_iDate) ,INPAY_djlsh0 , INPAY_zylsh0 ,INPAY_id0000, INPAY_AdmInfoDr, INPAY_Zstr11 INTO :cykssj, :setlid, :mdtrtid,:psnno ,:adminfo, :jjpayStr FROM sqluser.insu_divide WHERE INPAY_AdmDr =:AEpisodeID AND INPAY_Flag ='I' ORDER BY INPAY_Rowid desc)
    s ModelObj.psnno=psnno



                               d ..ObjExchange(ModelObj)
        do ModelObj.%Close()
        DO ModelObj.XMLExportToString(.XML,"Response")
        ;b // 输出XML
        q XML
}

// 注册 类 数据存储到 表
ClassMethod ObjExchange(ClassOBJ)
{

    s ClassName="lizw.yb.JSQDXML"
    s dcd1 = ##Class(%Dictionary.CompiledClass).%OpenId(ClassName)
    s objName="lizw.User.JSQDSAVE"
    s obj=##class(lizw.User.JSQDSAVE).%New()
    s cnt=dcd1.Properties.Count()
    f i=2:1:cnt  d
    .s propObj = dcd1.Properties.GetAt(i)
    .s PropertyName = propObj.Name
    .i ##class(web.DHCBL.BDP.FindTableStructure).PropertyExistOrNot(objName,PropertyName)=1 d
    ..s $PROPERTY(obj,PropertyName)=$PROPERTY(ClassOBJ,PropertyName)
    
    s $PROPERTY(obj,"supDate")=+$h
    d obj.%Save()
    s GJYBID=obj.%Id()
    
    s dlen=ClassOBJ.opspdiseinfo.Count()
    f diagnum=1:1:dlen d
    .s opspdiseinfoobj=##class(lizw.yb.opspdiseinfoSave).%New()
    .s opspdiseinfoobj.diagname=ClassOBJ.opspdiseinfo.GetAt(diagnum).diagname
    .s opspdiseinfoobj.diagcode=ClassOBJ.opspdiseinfo.GetAt(diagnum).diagcode
    .s opspdiseinfoobj.oprnoprtname=ClassOBJ.opspdiseinfo.GetAt(diagnum).oprnoprtname
    .s opspdiseinfoobj.oprnoprtcode=ClassOBJ.opspdiseinfo.GetAt(diagnum).oprnoprtcode
    .D opspdiseinfoobj.GJYBIDSetObjectId(GJYBID)
    .D opspdiseinfoobj.%Save()



}


三,把注册类或者持久类中的数据转换成json。
      在实际业务中,对于字段比较多,需要输出成json格式时,我们可以把数据已经组织好的注册类或持久类转换成json键值对。
      具体实现:按照字段要求,把存放数据的类建好,字段名跟json要求保持一致,否则要做映射。
       优点:把注册类或持久类存放的数据直接转换成json键值,当json涉及的字段较多时,可以省去较多的代码量。
       缺点:使用与数据已经组织或已存放好,json键值较多的情况。

/// w ##Class(lizw.JSQDInsert).ReturnInputJSON("2")
ClassMethod ReturnInputJSON(TID As %String) As %String
{
    s OutputObj=##class(%DynamicObject).%New()
    S obj=##class(lizw.User.JSQDSAVE).%OpenId(TID)
    s setlinfoObj=##class(%DynamicObject).%New()
    s adm=obj.EpisodeID
    s AdmInfoDr=$o(^DHCINADM("0","ADM",adm,""),-1)
    s AdmInfo=$g(^DHCINADM(AdmInfoDr))        
    s InsuAdmCenter=$p(AdmInfo,"^",8)
    d OutputObj.%Set("infno","4101A")
    s msgid="H42010400158"_$tr($zd(+$h,3),"-")_$tr($zt($p($h,",",2)),":")_$e($tr($zt($p($h,",",2)),":"),1,4)
    d OutputObj.%Set("msgid",msgid)
    d OutputObj.%Set("insuplc_admdvs",InsuAdmCenter)
    d OutputObj.%Set("mdtrtarea_admvs","420100")
    。
    。
    。
    d OutputObj.%Set("fixmedins_name","武汉市中西医结合医院(武汉市第一医院)")
    d OutputObj.%Set("sign_no","")
    
    s setlinfoarr=..GetDynamicObjectFromOBJ(obj)
    s oprninfoArr=##class(%DynamicArray).%New()
    S oprninfoId=""
    F  S oprninfoId=$o(^lizw.yb.oprninfoSaveI("GJYBID",TID,oprninfoId)) Q:oprninfoId=""  D
    .S obj=##class(lizw.yb.oprninfoSave).%OpenId(oprninfoId)
    .s oprninfoObj=..GetDynamicObjectFromOBJ(obj)
    .d oprninfoArr.%Push(oprninfoObj)
    d setlinfoObj.%Set("oprninfo",oprninfoArr)
    
    s iteminfoArr=##class(%DynamicArray).%New()
    S iteminfoId=""
    F  S iteminfoId=$o(^lizw.yb.bldinfoSaveI("GJYBID",TID,iteminfoId)) Q:iteminfoId=""  D
    .S obj=##class(lizw.yb.bldinfoSave).%OpenId(iteminfoId)
    .s iteminfoObj=..GetDynamicObjectFromOBJ(obj)
    .d iteminfoArr.%Push(iteminfoObj)
    d setlinfoarr.%Set("bldinfo",iteminfoArr)
    
    s diseinfoArr=##class(%DynamicArray).%New()
    S diseinfoId=""
    F  S diseinfoId=$o(^lizw.yb.diseinfoSaveI("GJYBID",TID,diseinfoId)) Q:diseinfoId=""  D
    .S obj=##class(lizw.yb.diseinfoSave).%OpenId(diseinfoId)
    .s diseinfoObj=..GetDynamicObjectFromOBJ(obj)
    .d diseinfoArr.%Push(diseinfoObj)
    d setlinfoObj.%Set("diseinfo",diseinfoArr)
    
    s opspdiseinfoArr=##class(%DynamicArray).%New()
    S opspdiseinfoId=""
    F  S opspdiseinfoId=$o(^lizw.yb.opspdiseinfoSaveI("GJYBID",TID,opspdiseinfoId)) Q:opspdiseinfoId=""  D
    .S obj=##class(lizw.yb.opspdiseinfoSave).%OpenId(opspdiseinfoId)
    .s opspdiseinfoObj=..GetDynamicObjectFromOBJ(obj)
    .d opspdiseinfoArr.%Push(opspdiseinfoObj)
    d setlinfoObj.%Set("opspdiseinfo",opspdiseinfoArr)
    
    s icuinfoArr=##class(%DynamicArray).%New()
    S icuinfoId=""
    F  S icuinfoId=$o(^lizw.yb.icuinfoSaveI("GJYBID",TID,icuinfoId)) Q:icuinfoId=""  D
    .S obj=##class(lizw.yb.icuinfoSave).%OpenId(icuinfoId)
    .s icuinfoObj=..GetDynamicObjectFromOBJ(obj)
    .d icuinfoArr.%Push(icuinfoObj)
    d setlinfoObj.%Set("icuinfo",icuinfoArr)
    d setlinfoObj.%Set("setlinfo",setlinfoarr)
    d OutputObj.%Set("input",setlinfoObj)
    q TID_$c(0)_OutputObj.%ToJSON()
}

ClassMethod GetDynamicObjectFromOBJ(classOBJ) As %DynamicObject
{
    s arr=##class(%DynamicObject).%New()
    if (classOBJ.%IsA("%Library.Persistent")||(classOBJ.%IsA("%RegisteredObject"))){
        s className=classOBJ.%ClassName()
        s pkgName=classOBJ.%PackageName()
        s key=""
        s:$d(^oddCOM(className)) ClassName=className
        s:$d(^oddCOM(pkgName_"."_className)) ClassName=pkgName_"."_className
        f {
            s key=$o(^oddCOM(ClassName,"a",key))
            q:key=""
            i $e(key,1)="%"{
                continue
            }
            s private=$g(^oddDEF(ClassName,"a",key,35))
            if private=1{
                continue
            }
            continue:((key="GJYBID")||(key="supDate")||(key="BAH")||(key="EpisodeID"))
            d arr.%Set(^oddDEF(ClassName,"a",key,47),$PROPERTY(classOBJ,key))
        }
    }
    q arr
}

讨论 (1)1
登录或注册以继续