olap分析平臺的設計與實現(十一)-動態生成sql(下)

OLAP分析應用(十一)-動態生成sq

動態插入語句:

拼前半段:前半段語句在佈局表當中,已經存在了(設計界面的時候,就生成好了)。

拼插入sql語句後半段:關鍵是順序還要和插入前半段字段順序一致,其實,我們在comm_doc_layout中也有定義:

根據comm_doc_layout表中maincols中定義的順序,循環取得相關的值,代碼如下:


            DocLayout layout = (DocLayout) cacheHelper.getObjectInCache(Constants.CACHE_LAYOUT,
                    new DocLayout_Key(true), Integer.parseInt(layoutId));
            StringBuffer sql = new StringBuffer(layout.getMainsql() + "(");//插入語句的前半段
            String[] cols = layout.getMaincols().split(",");//界面已保存的所有字段
            List<BillArrObject> objs = this.exchange2Codes(list);//轉換得到所有數據元code
            //保存主表
            for (String col : cols) {//循環界面已保存的所有字段與傳來的list拼湊後半段sql
                boolean f = true;
                for (BillArrObject obj : objs) {
                    if (col.equals(obj.getName())) {
                        sql.append(this.exchange2str(user, obj, newGuid) + ",");//轉換成值
                        f = false;
                    }
                }
                if (col.equals("GUID") && f) {
                    String s = CreateGUID.GenerateGUID();
                    sql.append("'" + s + "',");
                    newGuid = s;
                }
            }
            StringBuffer sql2 = new StringBuffer(sql.substring(0, sql.length() - 1));//去掉最後的逗號
            sql2.append(")");
            Query query = this.getCurrentSession().createSQLQuery(sql2.toString());
            query.executeUpdate();

        

不過,取得值根據類型要進行一些轉換,如對日期進行格式化、數字進行必要的檢查判斷、字符串進行必要的轉換(主要是轉自然鍵值)、字符類型插入要加上前後引號等,代碼如下:

    /***
     * 判斷數據元類型並返回相應的字符串
     * @param ecode
     * 字符串返回'XX',數字返回XX,日期返回to_date('xx','yyyy-mm-dd hh24:mi:ss')
     */
    private String exchange2str(UserInfo user, BillArrObject obj, String newGuid) throws Exception {
        String str = "";
        //try {
        DataElement de = (DataElement) cacheHelper.getObjectInCache(
                Constants.CACHE_DATA_ELEMENT, new DataElement_Code_Key(true), obj.getName());
        if (de != null) {
            Dictionary dic = (Dictionary) cacheHelper.getObjectInCache(Constants.CACHE_DIC,
                    new Dictionary_Key(true), de.getEtype());
            String type = dic.getContent();
            //String value = new String(obj.getValue().getBytes("ISO-8859-1"), "UTF-8");
            String value = obj.getValue();
            if (BaseUtil.isNotNull(value)) {
                value = value.trim();
            }
            if ("VARCHAR2".equals(type)) {//字符串類型
                if ("GUID".equals(de.getEcode()) && BaseUtil.isNull(value)) {//sys_guid()
                    str = "'" + newGuid + "'";
                } else if ("DOC_BILLID".equals(de.getEcode()) && BaseUtil.isNotNull(value)) {
                    str = "'" + BaseUtil.guid2Nid(EBasBillInfo.class, value) + "'";//前端傳來的票種GUID轉換成NID
                } else if ("ChargeProjectID1".equals(de.getEcode()) && BaseUtil.isNotNull(value)) {
                    str = "'" + BaseUtil.guid2Nid(EBasChargePrjAll.class, value) + "'";//前端傳來的項目GUID轉換成NID
                } else if ("dwmc".equals(de.getEcode()) && BaseUtil.isNotNull(value)) {
                    //str = "'"+BaseUtil.guid2Nid(EBasChargeAgency.class,value)+"'";//前端傳來的單位GUID轉換成NID
                    str = "'" + user.getDept() + "'";
                } else if ("CollectingBank".equals(de.getEcode()) && BaseUtil.isNotNull(value)) {
                    str = "'" + BaseUtil.guid2Nid(EBasRemittedBank.class, value) + "'";
                } else {
                    str = "'" + value + "'";
                }
            } else if ("NUMBER".equals(type) || "number".equals(type)
                    || type.contains("number") || type.contains("NUMBER")) {//數字類型
                if ("DOC_ID".equals(de.getEcode()) && (BaseUtil.isNull(value) || "0".equals(value))) {
                    str = "SEQUENCE_DOC_ID.NEXTVAL";
                } else if ("DOC_TOTALAMOUNT".equals(de.getEcode()) && BaseUtil.isNull(value)) {//總金額爲空的話
                    str = "0.00";
                    //return "";
                } else if ("num".equals(de.getEcode()) && BaseUtil.isNull(value)) {
                    str = "1";
                } else if ("num".equals(de.getEcode()) && BaseUtil.isNotNull(value)) {
                    Double sl = Double.parseDouble(value);
                    if (sl.doubleValue() == 0) {
                        str = "1";
                    } else {
                        str = "" + value + "";
                    }
                } else if ("amount".equals(de.getEcode()) && BaseUtil.isNull(value)) {
                    throw new BusinessException("明細金額有誤,請重新開票保存!");
                } else if ("amount".equals(de.getEcode()) && BaseUtil.isNotNull(value)) {
                    Double amt = Double.parseDouble(value);
                    if (amt.doubleValue() == 0) {
                        throw new BusinessException("明細金額有誤,請重新開票保存!");
                    } else {
                        str = "" + value + "";
                    }
                } else if (!"amount".equals(de.getEcode()) && !"DOC_ID".equals(de.getEcode()) && !"DOC_TOTALAMOUNT".equals(de.getEcode()) && BaseUtil.isNull(value)) {
                    str = "0.00";
                } else {
                    str = "" + value + "";
                }
            } else if ("DATE".equals(type)) {//時間類型
                str = "to_date('" + value + "','yyyy-MM-dd HH24:mi:ss')";
            } else if ("CHAR".equals(type)) {//字符類型
                str = "'" + value + "'";
            }
        }
        //} catch (CacheException e) {
        //	log.error(e.getMessage(), e);
        //	e.printStackTrace();
        //}
        return str;
    }

至於更新,和插入是一樣的,不過得先刪除原來的記錄。

動態查詢列表:

目前的寫法有點...,主要搞了個doc_index表,做爲所有動態業務表的入口

這裏,無非是查總記錄調試、記錄集合而已。


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        StringBuffer account = new StringBuffer("select count(*) from DOC_INDEX t ");
        StringBuffer hql = new StringBuffer("select t.id \"id\",t.doc_id \"docid\",t.doc_zg \"doczg\",t.doc_num \"docnum\"," +
                "t.create_date \"createdate\",t.table_name \"tablename\",t.doc_state \"docstate\"," +
                "t.bill_def_id \"billdefid\",t.login_code \"logincode\",t.doc_totalamount \"totalamount\"," +
                "t.billdate \"billdate\",t.agencyid \"agencyid\",t.verifistate \"verifistate\",t.invalidstate \"invalidstate\","
                + "t.orgid \"orgid\",t.verid \"verid\",t.dkagency \"dkagency\",t.dkagencyid \"dkagencyid\",t.jm \"jm\",x.payer \"payer\",t.xjagencyid \"xjagencyid\" from DOC_INDEX t ");
        StringBuffer joinStr = new StringBuffer(" inner join ");
        StringBuffer str = new StringBuffer(" where 1=1 ");
        String sdate = (String) map.get("sbilldate");
        String edate = (String) map.get("ebilldate");
        String docnum = (String) map.get("docnum");
        String creator = (String) map.get("creator");
        String orgID = (String) map.get("orgID");
        String ignorelogincode = (String) map.get("ignorelogincode");
        String payer = (String) map.get("payer");
        EBasBill2DataSet b2d = null;
        DataSet ds = null;
        String tabName = "";

        int docstate = -1;

        String localyear = Constants.BUSI_YEAR;

        if (BaseUtil.isNotNull(map.get("docstate"))) {
            docstate = (Integer) map.get("docstate");   //如果docstate是0,查詢可刪除與可審覈的單據
            if (docstate == 4) {//覈銷狀態
                str.append(" and t.doc_state>0 ");
                str.append(" and t.verifistate>0 ");
            }
            if (docstate >= 0 && docstate <= 2) {
                str.append(" and t.verifistate=0 ");
            }
        }
        String userRole = this.checkUserRole(user);

        str.append(" and t.bill_def_id = '" + billid + "'");//票種id
        if (docstate > -1 && docstate < 4) {//3是收款狀態
            str.append(" and t.doc_state =" + docstate + "");
        }

        if (userRole.equals(Constants.SYS_ROLE_AGENCY) || userRole.equals(Constants.SYS_ROLE_BANK)) {
            //單位自己和自己的下級
            if (docstate > -1) {
                str.append(" and t.agencyid in (select distinct nid from BAS_CHARGEAGENCY where guid in "
                        + "(select agencyid from BAS_CHGAGENCY2CHGAGENCY where parentagencyid='" + BaseUtil.nid2Guid(EBasChargeAgency.class, user.getDept(), localyear) + "')"
                        + " union  select '" + user.getDept() + "' from dual ) ");
                if (docstate == 4) {
                    str.append(" and t.doc_state>0 ");
                    str.append(" and t.verifistate>0 ");
                } else {
                    str.append(" and t.doc_state =" + docstate + " ");
                }
                //str.append(" ) ");
            } else {
                str.append(" and t.agencyid in (select distinct nid from BAS_CHARGEAGENCY where guid in "
                        + "(select agencyid from BAS_CHGAGENCY2CHGAGENCY where parentagencyid='" + BaseUtil.nid2Guid(EBasChargeAgency.class, user.getDept(), localyear) + "')"
                        + " union  select '" + user.getDept() + "' from dual )");
            }
        }

        if (BaseUtil.isNotNull(sdate)) {
            str.append(" and to_date(to_char(t.billdate,'yyyy-mm-dd'),'yyyy-mm-dd') >= to_date('" + sdate + "','yyyy-mm-dd')");
        }
        if (BaseUtil.isNotNull(edate)) {
            str.append(" and to_date(to_char(t.billdate,'yyyy-mm-dd'),'yyyy-mm-dd') <= to_date('" + edate + "','yyyy-mm-dd')");
        }
        if (BaseUtil.isNotNull(docnum)) {
            str.append(" and t.doc_num like '%" + docnum + "%'");
        }
        if (BaseUtil.isNotNull(creator)/* && "0".equals(ignorelogincode)*/) {
            try {
                creator = new String(creator.getBytes("ISO-8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                log.error(e.getMessage(), e);
                e.printStackTrace();
            }
            str.append(" and t.login_code like '%" + creator + "%'");
        }


        //如果是二級單位則只能看見自己機構開的票,不能看到上級單位開的票
        boolean isSecOrg = userDao.checkUserIsSecOrg(user);
        if (isSecOrg) {
            str.append(" and orgid=" + user.getOrgid() + " ");
        } else {
            //TODO NID?
            if (orgID != null && !orgID.trim().equals("")) {
                BaseUtil.nid2Guid(EBasChargeAgency.class, user.getDept(), localyear);
                if (!BaseUtil.nid2Guid(EBasChargeAgency.class, user.getDept(), localyear).equals(orgID)) {
                    str.append(" and t.xjagencyid='" + orgID + "'");
                } else {
                    str.append(" and (t.xjagencyid is null or t.xjagencyid='')");
                }
            }
        }


        if (Constants.BUSI_YBJKSNID.equals(billid)) {//如果是一般繳款書
				......
        } else {//專票
            try {
                b2d = (EBasBill2DataSet) cacheHelper.getObjectInCache(Constants.CACHE_BILL2SET, new Bill2DataSet_billid_Key(true), billid);
                if (b2d != null) {
                    ds = (DataSet) cacheHelper.getObjectInCache(Constants.CACHE_DATA_SET, new DataSet_Key(true), b2d.getDatasetid());
                }
                if (ds != null) tabName = ds.getScode();
            } catch (CacheException e) {
                e.printStackTrace();
            }

            joinStr.append(tabName).append(" x on t.doc_id=x.guid ");
            if (BaseUtil.isNotNull(payer)) {//如果繳款人條件是空的則先分頁查詢
                str.append(" and x.payer like '%" + payer + "%' ");
            }
            List<EDocIndex> list = null;
            //算總條數
            String totalSql = account.toString() + joinStr.toString() + str.toString();
            Query query = this.getCurrentSession().createSQLQuery(totalSql);
            Integer totalCount = Integer.parseInt(query.uniqueResult().toString());
            str.append(" order by t.create_date desc");   // where 語句
            String hqlSql = hql.toString() + joinStr.toString() + str.toString();
            query = this.getCurrentSession().createSQLQuery(hqlSql);
            if (pageIndex > -1) {
                query.setFirstResult((pageIndex - 1) * GlobalConfig.pageSize);
                query.setMaxResults(GlobalConfig.pageSize);
            }
            query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
            List<Map> listmap = query.list();   //查詢記錄
            if (listmap != null && listmap.size() > 0) {
                list = new ArrayList<EDocIndex>();
                for (Map map2 : listmap) {
                    try {
                        EDocIndex dc = (EDocIndex) BaseUtil.map2Bean(map2, EDocIndex.class.newInstance());
                        if (dc != null) list.add(dc);
                    } catch (InstantiationException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
            BigDecimal o = null;
            try {
                String countSql = "select SUM(t.DOC_TOTALAMOUNT) from DOC_INDEX t" + joinStr.toString() + str.toString();
                Query sqlQuery = this.getCurrentSession().createSQLQuery(countSql);
                o = (BigDecimal) sqlQuery.uniqueResult();
            } catch (Exception ignored) {
            }

            if (list != null) {
            	
            	//這裏寫的有點小問題,把公共屬性都放入的EDocIndex 屬性當中了,如pager屬性...
                for (EDocIndex eDocIndex : list) {
                    EBasChargeAgency agency = null;
                    EBasBillInfo bill = null;
                    CommOrg org = null;
                    try {
                        agency = (EBasChargeAgency) cacheHelper.getObjectInCache(Constants.CACHE_AGENCY,
                                new BasChgAgency_Key(true), BaseUtil.nid2Guid(EBasChargeAgency.class, eDocIndex.getAgencyid(), localyear));
                        bill = (EBasBillInfo) cacheHelper.getObjectInCache(Constants.CACHE_BILLINFO,
                                new BasBillInfo_Key(true), BaseUtil.nid2Guid(EBasBillInfo.class, eDocIndex.getBilldefid(), localyear));
                        org = (CommOrg) cacheHelper.getObjectInCache(
                                Constants.CACHE_ORG, new Org_Key(true), eDocIndex.getOrgid());
                        try {
                            if (eDocIndex.getXjagencyid() != null && !eDocIndex.getXjagencyid().equals("")) {
                                EBasChargeAgency objectInCache = (EBasChargeAgency) cacheHelper.getObjectInCache(Constants.CACHE_AGENCY,
                                        new BasChgAgency_Key(true), BaseUtil.nid2Guid(EBasChargeAgency.class, eDocIndex.getXjagencyid(), localyear));
                                if (objectInCache != null) {
                                    agency = objectInCache;
                                }
                            }
                        } catch (Exception ignored) {
                        }
                        if (org != null) {
                            eDocIndex.setOrgname(org.getName());
                        }
                        if (agency != null) {
                            eDocIndex.setAgencyname(agency.getAgencyname());
                        }
                        eDocIndex.setBillname(bill.getBillname());
                        eDocIndex.setPager(PublicUtil.getPager(totalCount, GlobalConfig.pageSize, pageIndex));
                        if (o != null) {
                            eDocIndex.setTablename(o.toString());
                        }

                    } catch (CacheException e) {
                        e.printStackTrace();
                    }

                }
                return list;
            }
        }
        return null;
    

 

動態刪除

一個要點是找到要刪除的表:路徑爲:佈局對象-->數據集--->要刪除的表  拼接到sql當中

要刪除細表,要找到這個細表,路徑爲  主表數據集對象--->主細表關係對象-->關聯數據元

   
//根據佈局表找到數據集id
String setid = layout.getBillsetid();
//根據數據集id從緩存當中取得數據集對象 
ds = (DataSet) cacheHelper.getObjectInCache(Constants.CACHE_DATA_SET, new DataSet_Key(true), setid);

//刪除主表 
 sql = "delete from " + ds.getScode() + " where " + FieldEnum.GUID.getFieldCode() + "='" + obj.getValue() + "'";
....
//找到主細關係表  進一步刪除細表當中數據
 DataSet2DataSet s2s = (DataSet2DataSet) cacheHelper.getObjectInCache(
                            Constants.CACHE_DATA_SET2SET, new DataSet2Set_RelationId_Key(true), setid);

 DataSet dds = (DataSet) cacheHelper.getObjectInCache(Constants.CACHE_DATA_SET,
                            new DataSet_Key(true), s2s.getSetid());//細表
DataElement de = (DataElement) cacheHelper.getObjectInCache(Constants.CACHE_DATA_ELEMENT,
                            new DataElement_Key(true), s2s.getElementid());//關聯數據元
 String sql2 = "delete from " + dds.getScode() + " where " + de.getEcode() + "= '" + oldGuid + "'";//刪除細表
 query = this.getCurrentSession().createSQLQuery(sql2);
query.executeUpdate();//執行刪除細表



 

sql 題外話:

PLSQL性能優化技巧

 

 

上一節:OLAP分析應用(十一)-動態生成sql(上)

下一節:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章