依据SQL编写的规范标准说明.docx

上传人:b****5 文档编号:8143734 上传时间:2023-01-29 格式:DOCX 页数:14 大小:22.96KB
下载 相关 举报
依据SQL编写的规范标准说明.docx_第1页
第1页 / 共14页
依据SQL编写的规范标准说明.docx_第2页
第2页 / 共14页
依据SQL编写的规范标准说明.docx_第3页
第3页 / 共14页
依据SQL编写的规范标准说明.docx_第4页
第4页 / 共14页
依据SQL编写的规范标准说明.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

依据SQL编写的规范标准说明.docx

《依据SQL编写的规范标准说明.docx》由会员分享,可在线阅读,更多相关《依据SQL编写的规范标准说明.docx(14页珍藏版)》请在冰豆网上搜索。

依据SQL编写的规范标准说明.docx

依据SQL编写的规范标准说明

SQL编写规范

 

1.书写格式

  

  示例代码:

  

  存储过程SQL文书写格式例

  select

  c.dealerCode,

  round(sum(c.submitSubletAmountDLR+c.submitPartsAmountDLR+c.submitLaborAmountDLR)/count(*),2)asavg,

  decode(null,'x','xx','CNY')

  from(

  select

  a.dealerCode,

  a.submitSubletAmountDLR,

  a.submitPartsAmountDLR,

  a.submitLaborAmountDLR

  fromSRV_TWC_Fa

  where(to_char(a.ORIGSUBMITTIME,'yyyy/mm/dd')>='DateRange(start)'

  andto_char(a.ORIGSUBMITTIME,'yyyy/mm/dd')<='DateRange(end)'

  andnvl(a.deleteflag,'0')<>'1')

  unionall

  select

  b.dealerCode,

  b.submitSubletAmountDLR,

  b.submitPartsAmountDLR,

  b.submitLaborAmountDLR

  fromSRV_TWCHistory_Fb

  where(to_char(b.ORIGSUBMITTIME,'yyyy/mm/dd')>='DateRange(start)'

  andto_char(b.ORIGSUBMITTIME,'yyyy/mm/dd')<='DateRange(end)'

  andnvl(b.deleteflag,'0')<>'1')

  )c

  groupbyc.dealerCode

  orderbyavgdesc;

  

  Javasource里的SQL字符串书写格式例

  strSQL="insertintoSnd_FinanceHistory_Tb"

  +"(DEALERCODE,"

  +"REQUESTSEQUECE,"

  +"HANDLETIME,"

  +"JOBFLAG,"

  +"FRAMENO,"

  +"INMONEY,"

  +"REMAINMONEY,"

  +"DELETEFLAG,"

  +"UPDATECOUNT,"

  +"CREUSER,"

  +"CREDATE,"

  +"HONORCHECKNO,"

  +"SEQ)"

  +"values('"+draftInputDetail.dealerCode+"',"

  +"'"+draftInputDetail.requestsequece+"',"

  +"sysdate,"

  +"'07',"

  +"'"+frameNO+"',"

  +requestMoney+","

  +remainMoney+","

  +"'0',"

  +"0,"

  +"'"+draftStruct.employeeCode+"',"

  +"sysdate,"

  +"'"+draftInputDetail.honorCheckNo+"',"

  +index+")";

  

  1).缩进

  对于存储过程文件,缩进为8个空格

  对于Javasource里的SQL字符串,不可有缩进,即每一行字符串不可以空格开头

  

  2).换行

  1>.Select/From/Where/Orderby/Groupby等子句必须另其一行写

  2>.Select子句内容如果只有一项,与Select同行写

  3>.Select子句内容如果多于一项,每一项单独占一行,在对应Select的基础上向右缩进8个空格(Javasource无缩进)

  4>.From子句内容如果只有一项,与From同行写

  5>.From子句内容如果多于一项,每一项单独占一行,在对应From的基础上向右缩进8个空格(Javasource无缩进)

  6>.Where子句的条件如果有多项,每一个条件占一行,以AND开头,且无缩进

  7>.(Update)Set子句内容每一项单独占一行,无缩进

  8>.Insert子句内容每个表字段单独占一行,无缩进;values每一项单独占一行,无缩进

  9>.SQL文中间不允许出现空行

  10>.Javasource里单引号必须跟所属的SQL子句处在同一行,连接符("+")必须在行首

  

  3).空格

  1>.SQL内算数运算符、逻辑运算符连接的两个元素之间必须用空格分隔

  2>.逗号之后必须接一个空格

  3>.关键字、保留字和左括号之间必须有一个空格

  

  2.不等于统一使用"<>"

  

  Oracle认为"!

="和"<>"是等价的,都代表不等于的意义。

为了统一,不等于一律使用"<>"表示

  

  3.使用表的别名

  

  数据库查询,必须使用表的别名

  

  4.SQL文对表字段扩展的兼容性

  

  在Javasource里使用Select*时,严禁通过getString

(1)的形式得到查询结果,必须使用getString("字段名")的形式

  使用Insert时,必须指定插入的字段名,严禁不指定字段名直接插入values

  

  5.减少子查询的使用

  

  子查询除了可读性差之外,还在一定程度上影响了SQL运行效率

  请尽量减少使用子查询的使用,用其他效率更高、可读性更好的方式替代

  

  6.适当添加索引以提高查询效率

  

  适当添加索引可以大幅度的提高检索速度

  请参看ORACLESQL性能优化系列

  

  7.对数据库表操作的特殊要求

  

  本项目对数据库表的操作还有以下特殊要求:

  

  1).以逻辑删除替代物理删除

  

  注意:

现在数据库表中数据没有物理删除,只有逻辑删除

  

  以deleteflag字段作为删除标志,deleteflag='1'代表此记录被逻辑删除,因此在查询数据时必须考虑deleteflag的因素

  

  deleteflag的标准查询条件:

NVL(deleteflag,'0')<>'1'

  

  2).增加记录状态字段

  

  数据库中的每张表基本都有以下字段:

DELETEFLAG、UPDATECOUNT、CREDATE、CREUSER、UPDATETIME、UPDATEUSER

  

  要注意在对标进行操作时必须考虑以下字段

  

  插入一条记录时要置DELETEFLAG='0',UPDATECOUNT=0,CREDATE=sysdate,CREUSER=登录User

  

  查询一条记录时要考虑DELETEFLAG,如果有可能对此记录作更新时还要取得UPDATECOUNT作同步检查

  

  修改一条记录时要置UPDATETIME=sysdate,UPDATEUSER=登录User,UPDATECOUNT=(UPDATECOUNT+1)mod1000,

  

  删除一条记录时要置DELETEFLAG='1'

  

  3).历史表

  

  数据库里部分表还存在相应的历史表,比如srv_twc_f和srv_twchistory_f

  

  在查询数据时除了检索所在表之外,还必须检索相应的历史表,对二者的结果做Union(或UnionAll)

  

  8.用执行计划分析SQL性能

  

  EXPLAINPLAN是一个很好的分析SQL语句的工具,它可以在不执行SQL的情况下分析语句

  

  通过分析,我们就可以知道ORACLE是怎样连接表,使用什么方式扫描表(索引扫描或全表扫描),以及使用到的索引名称

  

  按照从里到外,从上到下的次序解读分析的结果

  

  EXPLAINPLAN的分析结果是用缩进的格式排列的,最内部的操作将最先被解读,如果两个操作处于同一层中,带有最小操作号的将首先被执行

  

  目前许多第三方的工具如PLSQLDeveloper和TOAD等都提供了极其方便的EXPLAINPLAN工具

  

  PG需要将自己添加的查询SQL文记入log,然后在EXPLAINPLAN中进行分析,尽量减少全表扫描

  

  ORACLESQL性能优化系列

  

  1.选择最有效率的表名顺序(只在基于规则的优化器中有效)

  

  ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表drivingtable)将被最先处理

  

  在FROM子句中包含多个表的情况下,必须选择记录条数最少的表作为基础表

  

  当ORACLE处理多个表时,会运用排序及合并的方式连接它们

  

  首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行排序;

  

  然后扫描第二个表(FROM子句中最后第二个表);

  

  最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并

  

  例如:

  

  表TAB116,384条记录

  

  表TAB25条记录

  

  选择TAB2作为基础表(最好的方法)

  

  selectcount(*)fromtab1,tab2执行时间0.96秒

  

  选择TAB2作为基础表(不佳的方法)

  

  selectcount(*)fromtab2,tab1执行时间26.09秒

  

  如果有3个以上的表连接查询,那就需要选择交叉表(intersectiontable)作为基础表,交叉表是指那个被其他表所引用的表

  

  例如:

  EMP表描述了LOCATION表和CATEGORY表的交集

  SELECT*

  FROMLOCATIONL,

  CATEGORYC,

  EMPE

  WHEREE.EMP_NOBETWEEN1000AND2000

  ANDE.CAT_NO=C.CAT_NO

  ANDE.LOCN=L.LOCN

  

  将比下列SQL更有效率

  SELECT*

  FROMEMPE,

  LOCATIONL,

  CATEGORYC

  WHEREE.CAT_NO=C.CAT_NO

  ANDE.LOCN=L.LOCN

  ANDE.EMP_NOBETWEEN1000AND2000

  

  2.WHERE子句中的连接顺序

  

  ORACLE采用自下而上的顺序解析WHERE子句

  

  根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾

  

  例如:

  (低效,执行时间156.3秒)

  SELECT*

  FROMEMPE

  WHERESAL>50000

  ANDJOB='MANAGER'

  AND25<(SELECTCOUNT(*)FROMEMPWHEREMGR=E.EMPNO);

  

  (高效,执行时间10.6秒)

  SELECT*

  FROMEMPE

  WHERE25<(SELECTCOUNT(*)FROMEMPWHEREMGR=E.EMPNO)

  ANDSAL>50000

  ANDJOB='MANAGER';

  

  3.SELECT子句中避免使用'*'

  

  当你想在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用'*'是一个方便的方法,不幸的是,这是一个非常低效的方法

  

  实际上,ORACLE在解析的过程中,会将'*'依次转换成所有的列名

  

  这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间

  

  4.减少访问数据库的次数

  

  当执行每条SQL语句时,ORACLE在内部执行了许多工作:

解析SQL语句,估算索引的利用率,绑定变量,读数据块等等

  

  由此可见,减少访问数据库的次数,就能实际上减少ORACLE的工作量

  

  例如:

  

  以下有三种方法可以检索出雇员号等于0342或0291的职员

  

  方法1(最低效)

  SELECTEMP_NAME,SALARY,GRADE

  FROMEMP

  WHEREEMP_NO=342;

  

  SELECTEMP_NAME,SALARY,GRADE

  FROMEMP

  WHEREEMP_NO=291;

  

  方法2(次低效)

  DECLARE

  CURSORC1(E_NONUMBER)IS

  SELECTEMP_NAME,SALARY,GRADE

  FROMEMP

  WHEREEMP_NO=E_NO;

  BEGIN

  OPENC1(342);

  FETCHC1INTO…,…,…;

  …

  OPENC1(291);

  FETCHC1INTO…,…,…;

  …

  CLOSEC1;

  END;

  

  方法2(高效)

  SELECTA.EMP_NAME,A.SALARY,A.GRADE,

  B.EMP_NAME,B.SALARY,B.GRADE

  FROMEMPA,EMPB

  WHEREA.EMP_NO=342

  ANDB.EMP_NO=291;

  

  5.使用DECODE函数来减少处理时间

  

  使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表

  

  例如:

  SELECTCOUNT(*),SUM(SAL)

  FROMEMP

  WHEREDEPT_NO='0020'

  ANDENAMELIKE'SMITH%';

  

  SELECTCOUNT(*),SUM(SAL)

  FROMEMP

  WHEREDEPT_NO='0030'

  ANDENAMELIKE'SMITH%';

  

  你可以用DECODE函数高效地得到相同结果

  SELECTCOUNT(DECODE(DEPT_NO,'0020','X',NULL))D0020_COUNT,

  COUNT(DECODE(DEPT_NO,'0030','X',NULL))D0030_COUNT,

  SUM(DECODE(DEPT_NO,'0020',SAL,NULL))D0020_SAL,

  SUM(DECODE(DEPT_NO,0030,SAL,NULL))D0030_SAL

  FROMEMP

  WHEREENAMELIKE'SMITH%';

  

  'X'表示任何一个字段

  类似的,DECODE函数也可以运用于GROUPBY和ORDERBY子句中

  

  6.用Where子句替换HAVING子句

  

  避免使用HAVING子句,HAVING只会在检索出所有记录之后才对结果集进行过滤,这个处理需要排序、统计等操作

  

  如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销

  

  例如:

  低效

  SELECTREGION,AVG(LOG_SIZE)

  FROMLOCATION

  GROUPBYREGION

  HAVINGREGIONREGION!

='SYDNEY'

  ANDREGION!

='PERTH'

  

  高效

  SELECTREGION,AVG(LOG_SIZE)

  FROMLOCATION

  WHEREREGIONREGION!

='SYDNEY'

  ANDREGION!

='PERTH'

  GROUPBYREGION

  

  7.减少对表的查询

  

  在含有子查询的SQL语句中,要特别注意减少对表的查询

  

  例如:

  

  低效

  SELECTTAB_NAME

  FROMTABLES

  WHERETAB_NAME=(SELECTTAB_NAME

  FROMTAB_COLUMNS

  WHEREVERSION=604)

  ANDDB_VER=(SELECTDB_VER

  FROMTAB_COLUMNS

  WHEREVERSION=604)

  

  高效

  SELECTTAB_NAME

  FROMTABLES

  WHERE(TAB_NAME,DB_VER)=(SELECTTAB_NAME,DB_VER

  FROMTAB_COLUMNS

  WHEREVERSION=604)

  

  Update多个Column例子:

  低效

  UPDATEEMP

  SETEMP_CAT=(SELECTMAX(CATEGORY)

  FROMEMP_CATEGORIES),

  SAL_RANGE=(SELECTMAX(SAL_RANGE)

  FROMEMP_CATEGORIES)

  WHEREEMP_DEPT=0020;

  

  高效

  UPDATEEMP

  SET(EMP_CAT,SAL_RANGE)=(SELECTMAX(CATEGORY),MAX(SAL_RANGE)

  FROMEMP_CATEGORIES)

  WHEREEMP_DEPT=0020;

  

  8.使用表的别名(Alias)

  

  当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个Column上

  

  这样可以减少解析的时间并减少那些由Column歧义引起的语法错误

  

  9.用EXISTS替代IN

  

  在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接

  

  在这种情况下,使用EXISTS(或NOTEXISTS)通常将提高查询的效率

  

  低效

  SELECT*

  FROMEMP(基础表)

  WHEREEMPNO>0

  ANDDEPTNOIN(SELECTDEPTNO

  FROMDEPT

  WHERELOC='MELB')

  

  高效

  SELECT*

  FROMEMP(基础表)

  WHEREEMPNO>0

  ANDEXISTS(SELECT'X'

  FROMDEPT

  WHEREDEPT.DEPTNO=EMP.DEPTNO

  ANDLOC='MELB')

  

  10.用NOTEXISTS替代NOTIN

  

  在子查询中,NOTIN子句将执行一个内部的排序和合并

  

  无论在哪种情况下,NOTIN都是最低效的,因为它对子查询中的表执行了一个全表遍历

  

  为了避免使用NOTIN,我们可以把它改写成外连接(OuterJoins)或NOTEXISTS

  

  例如:

  SELECT…

  FROMEMP

  WHEREDEPT_NONOTIN(SELECTDEPT_NO

  FROMDEPT

  WHEREDEPT_CAT='A');

  

  为了提高效率改写为

  高效

  SELECT…

  FROMEMPA,DEPTB

  WHEREA.DEPT_NO=B.DEPT(+)

  ANDB.DEPT_NOISNULL

  ANDB.DEPT_CAT(+)='A'

  

  最高效

  SELECT…

  FROMEMPE

  WHERENOTEXISTS(SELECT'X'

  FROMDEPTD

  WHERED.DEPT_NO=E.DEPT_NO

  ANDDEPT_CAT='A');

  

  11.用表连接替换EXISTS

  

  通常来说,采用表连接的方式比EXISTS更有效率

  

  例如:

  SELECTENAME

  FROMEMPE

  WHEREEXISTS(SELECT'X'

  FROMDEPT

  WHEREDEPT_NO=E.DEPT_NO

  ANDDEPT_CAT='A');

  

  更高效

  SELECTENAME

  FROMDEPTD,EMPE

  WHEREE.DEPT_NO=D.DEPT_NO

  ANDDEPT_CAT='A';

  

  12.用EXISTS替换DISTINCT

  

  当提交一个包含多表信息(比如部门表和雇员表)的查询时,避免在SELECT子句中使用DISTINCT,一般可以考虑用EXIST替换

  

  例如:

  

  低效

  SELECTDISTINCTDEPT_NO,DEPT_NAME

  FROMDEPTD,EMPE

  WHERED.DEPT_NO=E.DEPT_NO

  

  高效

  SELECTDEPT_NO,DEPT_NAME

  FROMDEPTD

  WHEREEXISTS(SELECT'X'

  FROMEMPE

  WHEREE.DEPT_NO=D.DEPT_NO);

  

  EXISTS使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果

  

  13.用索引提高效率

  

  索引是表的一个概念部分,用来提高检索数据的效率。

实际上,ORACLE使用了一个复杂的自平衡B-tree结构

  

  通常,通过索引查询数据比全表扫描要快。

当ORACLE找出执行查询和Update语句的最佳路径时,ORACLE优化器将使用索引

  

  同样,在联结多个表时使用索引也可以提高效率。

另一个使用索引的好处是,它提供了主键(primarykey)的唯一性验证

  

  除了那些LONG或LONGRAW数据类型,你可以索引几乎所有的列

  

  通常在大型表中使用索引特别有效,当然,在扫描小表时,使用索引同样能提高效率

  

  虽然使用索引能得到查询效

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1