金蝶BOS 7.5 SQL语句生成分析

今天刚好有空,就分析下 金蝶BOS 7.5 SQL语句生成 方式.(分析环境 Oracle 11.0.2 , 金蝶BOS 7.5.0)

1 操作思路

思路是这样的,在开发环境触发SQL操作,然后在数据库中查出最近执行的SQL,对其分析.

数据库里使用SQL语句:

--这里只查询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.

2 操作数据

实体找了带有一个分录的基础资料,数据共5条. ( 实体 package-> CT_BAS_PACKAGE,分录 E1 ->CT_BAS_PACKAGEE1 ).

3 操作过程

3.1 KSQL

为了操作直观,这里不使用 EntityViewInfo 操作,而是直接从 KSQL 下手,操作代码类似:

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之流相甚远!!!!完全没有效率可言.特别是创表存储数据,稍后删除的作法,更是让人不可思议.

时间: 2024-10-24 18:26:13

金蝶BOS 7.5 SQL语句生成分析的相关文章

SQL语句性能分析常用选项开关

DBCC freeproccache DBCC dropcleanbuffers 1.set statistics IO {ON| OFF} /*Transact-SQL 语句生成的磁盘活动量的信息*/2.set statistics time on {ON| OFF} /*显示分析.编译和执行各语句所需的毫秒数*/3.set statistics profile on 4.set showplan_all on {ON| OFF} /*返回有关语句执行情况的详细信息,并估计语句对资源的需求*/

在线数据库表(sql语句)生成java实体类工具

相信每个做java开发的读者,都接触过SQL建表语句,尤其是在项目开发初期,因为数据库是项目的基石. 在现代项目开发中,出现了许多ORM框架,通过简单的实体映射,即可实现与数据库的交互,然而我们最初设计的一定是数据库表结构,而不是实体类.实体类仅仅是对底层数据结构的有损压缩,它仅仅是数据载体,不具备数据归档能力. 因此,很多时候,我们需要将原始的SQL建表语句转换成java实体类,这项工作看似简单,但若人工完成,工作量也是相当可观的,而且难免会出现差错. 到目前为止,笔者还没有发现比较靠谱的此类

在线数据库表(sql语句)生成java实体类工具 - 参考手册

SQL建表语句 说明 格式良好的SQL建表语句,可以是直接从PowerDesigner.Navicat等工具中导出SQL建表语句.所谓格式良好,是指建表指令与表名必须在一行,字段名称.类型.注释必须在一行,因为这个工具是用正则实现的,并不是语法解析器,当然,以后有时间的话,会改进成解析器. 举例 -- ---------------------------- -- Table structure for t_activity -- ---------------------------- DRO

PowerDesigner通过SQL语句生成PDM文件并将name和comment进行互相转换

本篇文章主要介绍了PowerDesigner通过SQL语句生成PDM文件并将name和comment进行互相转换 超详细过程(图文),具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.软件准备 软件:Navicat 11.1,Powerdesigner 15 2.安装步骤 第一步:将要生成的数据库导出为sql文件 第二步:打开PowerDesigner选择File-->Reverse Engineer --> Database... 第三步:选择MySQL5.0数据库 第四步:找到第一步生

对SQL语句进行分析和优化

安装和查看ORACLE执行计划ORACLE在执行SQL语句时使用的步骤的集合叫做执行计划 前起条件:    在目录:$ORACLE_HOME/RDBMS/ADMIN目录下的执行utlxplan.sql 查看执行计划:    EXPLAN PLAN FOR <SQL语句>        CREDIT @ORCL>explain plan for select * from creditcard; Explained. 看SQL执行计划的信息CREDIT @ORCL>select a.

MySQL innodb中各种SQL语句加锁分析

概要 Locking read( SELECT ... FOR UPDATE or SELECT ... LOCK IN SHARE MODE),UPDATE以及DELETE语句通常会在他扫描的索引所有范围上加锁,忽略没有用到索引的那部分where语句.举个例子: CREATE TABLE `test` ( `id` int(11) NOT NULL DEFAULT '0', `name` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE

转:C#制作ORM映射学习笔记二 配置类及Sql语句生成类

在正式开始实现ORM之前还有一点准备工作需要完成,第一是实现一个配置类,这个很简单的就是通过静态变量来保存数据库的一些连接信息,等同于.net项目中的web.config的功能:第二需要设计实现一个sql语句的生成类来帮助生成sql语句,当前如果不实现这个类也不会影响orm的制作,之所以要做这么一个类主要有几个目的,1.减少sql语句中拼写错误的发生.2.统一解决防sql注入的问题. 下面分别说明一下这两个类的实现方式: 1.配置类DbConfig using System; using Sys

使用SQL语句生成 web图表

简单学了下nodejs web开发框架express,以及一些相关的技术- 关于express的部分主要参考:Node.js开发框架Express4.x.Node.js + Express 构建网站简单示例 需要注意的是,express 4.x 构建器独立成了一个模块,如果要使用系统中的express命令,就必须安装独立的generator: npm install -g express express-generator bower supervisor express -e bower-ex

sql语句 生成数据库表

  打开PowerDesigner,鼠标单击File菜单: 2 选择:Reverse Enginer,然后在他的子菜单选择Database...; 3 选择好DBMS(数据库管理系统)类型:然后点击确定按钮:这里演示选中的是mysql数据库,具体类型根据自己需要选择: 4 点击Add  Files 图标添加脚本: 5 找到要导入的sql脚本,鼠标单击打开按钮: 6 鼠标单击,确定按钮: 7 开始反向工程生成数据库..... 8 导入成功! 原文地址:https://www.cnblogs.com