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 題外話:
下一節: