今天恰好有空,就分析下 金蝶BOS 7.5 SQL語句生成 方式.(分析環境 Oracle 11.0.2 , 金蝶BOS 7.5.0)java
1 操做思路sql
思路是這樣的,在開發環境觸發SQL操做,而後在數據庫中查出最近執行的SQL,對其分析.
數據庫
數據庫裏使用SQL語句:app
--這裏只查詢JDBC操做的SQL語句 SELECT t.sql_id, t.sql_text, t.sql_fulltext, to_char(t.last_active_time, 'yyyy-mm-dd HH24:mi:ss') FROM v$sql t WHERE t.last_active_time > SYSDATE - 0.0005 AND t.module = 'JDBC Thin Client' ORDER BY t.last_active_time DESC; --根據SQL_ID獲取執行時參數值 SELECT child_number, NAME, position, datatype_string, value_string, last_captured FROM v$sql_bind_capture WHERE sql_id = '8du5umjut76wc' ORDER BY child_number, position;
來獲取最近一分鐘內執行的SQL.spa
2 操做數據code
實體找了帶有一個分錄的基礎資料,數據共5條. ( 實體 package-> CT_BAS_PACKAGE,分錄 E1 ->CT_BAS_PACKAGEE1 ).排序
3 操做過程ip
3.1 KSQL開發
爲了操做直觀,這裏不使用 EntityViewInfo 操做,而是直接從 KSQL 下手,操做代碼相似:
get
IPackage ipackage = PackageFactory.getRemoteInstance(); package.getPackageCollection("select * where number='BZ0001'");//select * where number='BZ0001' 爲KSQL
分析結果:
--KSQL:select * where number='BZ0001' SELECT "T0"."FID" "ID", "T0"."FCREATORID" "T1.ID", "T0"."FCREATETIME" "CREATETIME", "T0"."FLASTUPDATEUSERID" "T2.ID", "T0"."FLASTUPDATETIME" "LASTUPDATETIME", "T0"."FCONTROLUNITID" "T3.ID", "T0"."FNAME_L2" "NAME", "T0"."FNAME_L1" "NAME_L1", "T0"."FNAME_L2" "NAME_L2", "T0"."FNAME_L3" "NAME_L3", "T0"."FNUMBER" "NUMBER", "T0"."FDESCRIPTION_L2" "DESCRIPTION", "T0"."FDESCRIPTION_L1" "DESCRIPTION_L1", "T0"."FDESCRIPTION_L2" "DESCRIPTION_L2", "T0"."FDESCRIPTION_L3" "DESCRIPTION_L3", "T0"."FSIMPLENAME" "SIMPLENAME", "T0"."CFSTATE" "STATE" FROM "CT_BAS_PACKAGE" "T0" WHERE "T0"."FNUMBER" = :1; --查詢分錄ID SELECT "T0"."FID" "ID", "T0"."FPARENTID" "T1.ID" FROM "CT_BAS_PACKAGEE1" "T0" INNER JOIN "CT_BAS_PACKAGE" "T1" ON "T0"."FPARENTID" = "T1"."FID" WHERE "T1"."FNUMBER" = :1 ORDER BY "T1.ID" ASC, "T0"."FSEQ" ASC; --總結:若是不指定,會查詢主表數據,加分錄數據中的 fid 字段 --KSQL:select number where number='BZ0001' SELECT "T0"."FID" "ID", "T0"."FNUMBER" "NUMBER" FROM "CT_BAS_PACKAGE" "T0" WHERE "T0"."FNUMBER" = :1; -- SELECT "T0"."FID" "ID", "T0"."FPARENTID" "T1.ID" FROM "CT_BAS_PACKAGEE1" "T0" INNER JOIN "CT_BAS_PACKAGE" "T1" ON "T0"."FPARENTID" = "T1"."FID" WHERE "T1"."FNUMBER" = :1 ORDER BY "T1.ID" ASC, "T0"."FSEQ" ASC; --總結:即便在主表中指定了主數據的查詢字段,仍然會查詢分錄 fid ,真是讓人失望 --KSQL:select E1.id where number='BZ0001' SELECT "T0"."FID" "ID" FROM "CT_BAS_PACKAGE" "T0" WHERE "T0"."FNUMBER" = :1; -- SELECT "T0"."FID" "ID", "T0"."FPARENTID" "T1.ID" FROM "CT_BAS_PACKAGEE1" "T0" INNER JOIN "CT_BAS_PACKAGE" "T1" ON "T0"."FPARENTID" = "T1"."FID" WHERE "T1"."FNUMBER" = :1 ORDER BY "T1.ID" ASC, "T0"."FSEQ" ASC; --總結:這裏也是很讓人失望,指定分錄中字段查詢,仍會查詢兩次,BOS對於ID真是有很深的執念啊 --KSQL:select E1.* where number='BZ0001' SELECT "T0"."FID" "ID" FROM "CT_BAS_PACKAGE" "T0" WHERE "T0"."FNUMBER" = :1; -- SELECT "T0"."FID" "ID", "T0"."FSEQ" "SEQ", "T0"."FPARENTID" "T1.ID", "T0"."CFNAME" "NAME", "T0"."CFREMARK" "REMARK", "T0"."CFWIDTH" "WIDTH", "T0"."CFHIGTH" "HIGTH", "T0"."CFLONGNUM" "LONGNUM" FROM "CT_BAS_PACKAGEE1" "T0" INNER JOIN "CT_BAS_PACKAGE" "T1" ON "T0"."FPARENTID" = "T1"."FID" WHERE "T1"."FNUMBER" = :1 ORDER BY "T1.ID" ASC, "T0"."FSEQ" ASC; --總結:同上 --KSQL:select E1 where number='BZ0001' SELECT "T0"."FID" "ID" FROM "CT_BAS_PACKAGE" "T0" WHERE "T0"."FNUMBER" = :1; -- SELECT "T0"."FID" "ID", "T0"."FPARENTID" "T1.ID" FROM "CT_BAS_PACKAGEE1" "T0" INNER JOIN "CT_BAS_PACKAGE" "T1" ON "T0"."FPARENTID" = "T1"."FID" WHERE "T1"."FNUMBER" = :1 ORDER BY "T1.ID" ASC, "T0"."FSEQ" ASC; --總結: 這裏分錄 E1 轉換成 E1.fid ,而不是 E1.* ,這個作得好.
3.2 exists 操做
IPackage ipackage = PackageFactory.getRemoteInstance(); FilterInfo filter=new FilterInfo(); filter.appendFilterItem("number", "BZ0001"); ipackage.exists(filter);
數據庫SQL
SELECT "T0"."FID" FROM "CT_BAS_PACKAGE" "T0" WHERE "T0"."FNUMBER" = :1 AND rownum <= 1;
這個讓人還算滿意.
3.3 Query
你們都知道在EAS 裏面 list 界面使用的是 Query的數據,用於篩選和排序.
Query裏顯示的SQL
SELECT "PACKAGE".FID AS "ID", "PACKAGE".FNumber AS "NUMBER", "PACKAGE".FName_l2 AS "NAME", "PACKAGE".FDescription_l2 AS "DESCRIPTION", "PACKAGE".FLastUpdateTime AS "LASTUPDATETIME", "LASTUPDATEUSER".FName_l2 AS "LASTUPDATEUSER.NAME", "PACKAGE".FCreateTime AS "CREATETIME", "CREATOR".FName_l2 AS "CREATOR.NAME", "PACKAGE".CFState AS "STATE" FROM ct_bas_package AS "PACKAGE" INNER JOIN t_pm_user AS "CREATOR" ON "PACKAGE".FCreatorID = "CREATOR".FID INNER JOIN t_pm_user AS "LASTUPDATEUSER" ON "PACKAGE".FLastUpdateUserID = "LASTUPDATEUSER".FID WHERE "PACKAGE".CFState = 1 ORDER BY "LASTUPDATETIME" ASC, "NUMBER" ASC;
實際執行的SQL:
--建立表,存入查詢數據(這張表,晚點會被刪掉),只有 ksql_seq, id 兩列,用於保存順序和ID INSERT INTO vtzoggntt1c6bxfd8u1mbc4q020 (ksql_seq, id) SELECT rownum, TMP_SUBSELECT_ALIAS."ID" FROM (SELECT * FROM (SELECT "PACKAGE".FID "ID", "PACKAGE".FLastUpdateTime "LASTUPDATETIME", "PACKAGE".FNumber "NUMBER" FROM ct_bas_package "PACKAGE" INNER JOIN t_pm_user "CREATOR" ON "PACKAGE".FCreatorID = "CREATOR".FID INNER JOIN t_pm_user "LASTUPDATEUSER" ON "PACKAGE".FLastUpdateUserID = "LASTUPDATEUSER".FID WHERE ("PACKAGE".CFState = :1 AND ("PACKAGE".FControlUnitID = :2 OR "PACKAGE".FControlUnitID = :3 OR "PACKAGE".FControlUnitID = :4)) ORDER BY "LASTUPDATETIME" ASC, "NUMBER" ASC) WHERE rownum <= 10000) tmp_subselect_alias WHERE rownum <= 10000; --查詢數據總數 SELECT * FROM (SELECT ksql_seq FROM vtzoggntt1c6bxfd8u1mbc4q020 ORDER BY ksql_seq DESC) WHERE rownum <= 1; --查詢前50條數據( 這個50 從哪裏來的,不清楚) SELECT * FROM vtzoggntt1c6bxfd8u1mbc4q020 WHERE ((ksql_seq >= :1) AND (ksql_seq <= :2)) ORDER BY ksql_seq ASC; --這裏只有5條數據,爲了方便看,我把參數加到SQL裏了,能夠看出,根據上面的查詢結果,這裏分兩種狀況,分別是ID和....真是任性 SELECT "PACKAGE".FID "ID", "PACKAGE".FNumber "NUMBER", "PACKAGE".FName_l2 "NAME", "PACKAGE".FDescription_l2 "DESCRIPTION", "PACKAGE".FLastUpdateTime "LASTUPDATETIME", "LASTUPDATEUSER".FName_l2 "LASTUPDATEUSER.NAME", "PACKAGE".FCreateTime "CREATETIME", "CREATOR".FName_l2 "CREATOR.NAME", "PACKAGE".CFState "STATE" FROM ct_bas_package "PACKAGE" INNER JOIN t_pm_user "CREATOR" ON "PACKAGE".FCreatorID = "CREATOR".FID INNER JOIN t_pm_user "LASTUPDATEUSER" ON "PACKAGE".FLastUpdateUserID = "LASTUPDATEUSER".FID WHERE (("PACKAGE".FID IN ('PKIAAAABDe9S2ZK/', :2, :3, :4, :5, 'NE' :7, :8, :9, :10, :11, :12, :13, :14, :15, :16, :17, :18, :19, :20, :21, :22, :23, :24, :25, :26, :27, :28, :29, :30, :31, :32, :33, :34, :35, :36, :37, :38, :39, :40, :41, :42, :43, :44, :45, :46, :47, :48, :49, :50)) AND ("PACKAGE".FID = 'PKIAAAABDe9S2ZK/' OR (("PACKAGE".FID IS NULL) AND 0 = 1) OR "PACKAGE".FID = :53 OR (("PACKAGE".FID IS NULL) AND :54 = 1) OR "PACKAGE".FID = :55 OR (("PACKAGE".FID IS NULL) AND :56 = 1) OR "PACKAGE".FID = :57 OR (("PACKAGE".FID IS NULL) AND :58 = 1) OR "PACKAGE".FID = :59 OR (("PACKAGE".FID IS NULL) AND :60 = 1) OR "PACKAGE".FID = :61 OR (("PACKAGE".FID IS NULL) AND :62 = 1) OR "PACKAGE".FID = :63 OR (("PACKAGE".FID IS NULL) AND :64 = 1) OR "PACKAGE".FID = :65 OR (("PACKAGE".FID IS NULL) AND :66 = 1) OR "PACKAGE".FID = :67 OR (("PACKAGE".FID IS NULL) AND :68 = 1) OR "PACKAGE".FID = :69 OR (("PACKAGE".FID IS NULL) AND :70 = 1) OR "PACKAGE".FID = :71 OR (("PACKAGE".FID IS NULL) AND :72 = 1) OR "PACKAGE".FID = :73 OR (("PACKAGE".FID IS NULL) AND :74 = 1) OR "PACKAGE".FID = :75 OR (("PACKAGE".FID IS NULL) AND :76 = 1) OR "PACKAGE".FID = :77 OR (("PACKAGE".FID IS NULL) AND :78 = 1) OR "PACKAGE".FID = :79 OR (("PACKAGE".FID IS NULL) AND :80 = 1) OR "PACKAGE".FID = :81 OR (("PACKAGE".FID IS NULL) AND :82 = 1) OR "PACKAGE".FID = :83 OR (("PACKAGE".FID IS NULL) AND :84 = 1) OR "PACKAGE".FID = :85 OR (("PACKAGE".FID IS NULL) AND :86 = 1) OR "PACKAGE".FID = :87 OR (("PACKAGE".FID IS NULL) AND :88 = 1) OR "PACKAGE".FID = :89 OR (("PACKAGE".FID IS NULL) AND :90 = 1) OR "PACKAGE".FID = :91 OR (("PACKAGE".FID IS NULL) AND :92 = 1) OR "PACKAGE".FID = :93 OR (("PACKAGE".FID IS NULL) AND :94 = 1) OR "PACKAGE".FID = :95 OR (("PACKAGE".FID IS NULL) AND :96 = 1) OR "PACKAGE".FID = :97 OR (("PACKAGE".FID IS NULL) AND :98 = 1) OR "PACKAGE".FID = :99 OR (("PACKAGE".FID IS NULL) AND :100 = 1) OR "PACKAGE".FID = :101 OR (("PACKAGE".FID IS NULL) AND :102 = 1) OR "PACKAGE".FID = :103 OR (("PACKAGE".FID IS NULL) AND :104 = 1) OR "PACKAGE".FID = :105 OR (("PACKAGE".FID IS NULL) AND :106 = 1) OR "PACKAGE".FID = :107 OR (("PACKAGE".FID IS NULL) AND :108 = 1) OR "PACKAGE".FID = :109 OR (("PACKAGE".FID IS NULL) AND :110 = 1) OR "PACKAGE".FID = :111 OR (("PACKAGE".FID IS NULL) AND :112 = 1) OR "PACKAGE".FID = :113 OR (("PACKAGE".FID IS NULL) AND :114 = 1) OR "PACKAGE".FID = :115 OR (("PACKAGE".FID IS NULL) AND :116 = 1) OR "PACKAGE".FID = :117 OR (("PACKAGE".FID IS NULL) AND :118 = 1) OR "PACKAGE".FID = :119 OR (("PACKAGE".FID IS NULL) AND :120 = 1) OR "PACKAGE".FID = :121 OR (("PACKAGE".FID IS NULL) AND :122 = 1) OR "PACKAGE".FID = :123 OR (("PACKAGE".FID IS NULL) AND :124 = 1) OR "PACKAGE".FID = :125 OR (("PACKAGE".FID IS NULL) AND :126 = 1) OR "PACKAGE".FID = :127 OR (("PACKAGE".FID IS NULL) AND :128 = 1) OR "PACKAGE".FID = :129 OR (("PACKAGE".FID IS NULL) AND :130 = 1) OR "PACKAGE".FID = :131 OR (("PACKAGE".FID IS NULL) AND :132 = 1) OR "PACKAGE".FID = :133 OR (("PACKAGE".FID IS NULL) AND :134 = 1) OR "PACKAGE".FID = :135 OR (("PACKAGE".FID IS NULL) AND :136 = 1) OR "PACKAGE".FID = :137 OR (("PACKAGE".FID IS NULL) AND :138 = 1) OR "PACKAGE".FID = :139 OR (("PACKAGE".FID IS NULL) AND :140 = 1) OR "PACKAGE".FID = :141 OR (("PACKAGE".FID IS NULL) AND :142 = 1) OR "PACKAGE".FID = :143 OR (("PACKAGE".FID IS NULL) AND :144 = 1) OR "PACKAGE".FID = :145 OR (("PACKAGE".FID IS NULL) AND :146 = 1) OR "PACKAGE".FID = :147 OR (("PACKAGE".FID IS NULL) AND :148 = 1) OR "PACKAGE".FID = :149 OR (("PACKAGE".FID IS NULL) AND :150 = 1))) ORDER BY "LASTUPDATETIME" ASC, "NUMBER" ASC;
總之,我認爲EAS BOS 7.5 在SQL語句的生成方式上,相對 Hibernate之流相甚遠!!!!徹底沒有效率可言.特別是創表存儲數據,稍後刪除的做法,更是讓人難以想象.