SQL代码开发规范文档.doc

上传人:小飞机 文档编号:4278333 上传时间:2023-04-13 格式:DOC 页数:64 大小:195KB
返回 下载 相关 举报
SQL代码开发规范文档.doc_第1页
第1页 / 共64页
SQL代码开发规范文档.doc_第2页
第2页 / 共64页
SQL代码开发规范文档.doc_第3页
第3页 / 共64页
SQL代码开发规范文档.doc_第4页
第4页 / 共64页
SQL代码开发规范文档.doc_第5页
第5页 / 共64页
点击查看更多>>
资源描述

《SQL代码开发规范文档.doc》由会员分享,可在线阅读,更多相关《SQL代码开发规范文档.doc(64页珍藏版)》请在三一办公上搜索。

1、SQL编码规范(V1.00)文 档 信 息文档名称:SQL编码规范电子文档:版本号:1.00密级:保密文档编号:编写人:黄业明日期:2007-03-27校对人:日期:审核人:日期:批准人:日期:更 改 记 录更改序号更改原因更改页码更改前版本号更改后版本号更改人生效日期备 注目录1注释规范61.1.一般性注释61.2.函数文本注释62.排版格式72.1.缩进72.2.换行82.3.空格102.4.大小写102.5.对齐103.命名规则113.1.输入变量113.2.输出变量113.3.内部变量113.4.游标命名114.编码规范114.1.不等于统一使用114.2.使用表的别名114.3.使用

2、SELECT语句时,必须指出列名124.4.使用INSERT语句时,必须指定插入的字段名。124.5.减少子查询的使用124.6.适当添加索引以提高查询效率124.7.不要在WHERE字句中对索引列施以函数124.8.不要使用数据库的类型自动转换功能,使用显式的类型转换124.9.应使用变量绑定实现SQL语句共享,避免使用硬编码124.10.用执行计划分析SQL性能14附录A:Oracle SQL性能优化14A.1选用适合的ORACLE优化器14A.2访问TABLE的方式15A.3共享SQL语句15A.4选择最有效率的表名顺序(只在基于规则的优化器中有效)17A.5WHERE子句中的连接顺序1

3、9A.6SELECT子句中避免使用 * 19A.7减少访问数据库的次数19A.8使用DECODE函数来减少处理时间21A.9整合简单,无关联的数据库访问22A.10删除重复记录23A.11用TRUNCATE替代DELETE全表记录23A.12尽量多使用COMMIT23A.13计算记录条数24A.14用Where子句替换HAVING子句24A.15减少对表的查询24A.16通过内部函数提高SQL效率26A.17使用表的别名(Alias)27A.18用EXISTS替代IN27A.19用NOT EXISTS替代NOT IN28A.20用表连接替换EXISTS29A.21用EXISTS替换DISTIN

4、CT30A.22识别低效执行的SQL语句31A.23使用TKPROF 工具来查询SQL性能状态31A.24用EXPLAIN PLAN 分析SQL语句32A.25用索引提高效率34A.26索引的操作34A.27基础表的选择36A.28多个平等的索引37A.29等式比较和范围比较38A.30不明确的索引等级39A.31强制索引失效40A.32避免在索引列上使用计算41A.33自动选择索引42A.34避免在索引列上使用NOT42A.35用=替代44A.36用UNION替换OR (适用于索引列)44A.37用IN来替换OR48A.38避免在索引列上使用IS NULL和IS NOT NULL49A.39

5、总是使用索引的第一个列50A.40ORACLE内部操作51A.41用UNION-ALL 替换UNION ( 如果有可能的话)51A.42使用提示(Hints)53A.43用WHERE替代ORDER BY54A.44避免改变索引列的类型56A.45需要当心的WHERE子句57A.46连接多个扫描58A.47CBO下使用更具选择性的索引60A.48避免使用耗费资源的操作60A.49优化GROUP BY61A.50使用日期62A.51使用显式的游标(CURSORs)62A.52优化EXPORT和IMPORT62A.53分离表和索引631 注释规范1.1. 一般性注释1.1.1. 创建每一数据库对象时

6、都要加上COMMENT ON注释,以说明该对象的功能和用途;建表时,对某些数据列也要加上COMMENT ON注释,以说明该列和/或列取值的含义。1.1.2. 注释语法包含两种情况:单行注释、多行注释单行注释:注释前有两个连字符(-)。多行注释:符号/*和*/之间的内容为注释内容。1.2. 函数文本注释1.2.1. 在每一个块和过程(存储过程、函数、包、触发器、视图等)的开头放置注释/*name : -函数名*function : -函数功能*input : -输入参数*output : -输出参数*author : -作者*CreateDate : -创建时间*UpdateDate : -函数

7、更改信息(包括作者、时间、更改内容等)*/CREATE OR REPLACE PROCEDURE dfsp_xxx1.2.2. 对传入参数的含义进行说明。如果取值范围确定,也一并说明。取值有特定含义的变量(如boolean类型变量),给出每个值的含义。1.2.3. 在每一个变量声明的旁边添加注释。说明该变量要用作什么。通常使用单行注释即可,例如login_id VARCHAR2(32) NOT NULL, - 会员标识1.2.4. 对存储过程的任何修改,都需要在注释最后添加修改人、修改日期及修改原因等信息1.2.5. 避免在一行代码或表达式的中间插入注释1.2.6. 在程序块的结束行右方加注释

8、,以表明程序块结束1.2.7. 在块的每个主要部分之前添加注释在块的每个主要部分之前增加注释,解释下组语句目的,说明该段语句及算法的目的以及要得到的结果,但不要对其细节进行过多的描述。1.2.8. 对程序分支必须书写注释2. 排版格式2.1. 缩进2.1.1. 存储过程中的SQL语句l 低级别语句在高级别语句后的,缩进4个空格。l 同一语句不同部分的缩进,如果为子句,则为4个空格,如果与上一行某部分有密切联系的,则缩至与其对齐。2.1.2. 对于Pro*C, Java等代码里的SQL字符串, 每一行字符串不可以空格开头。2.2. 换行2.2.1. 一行最长不能超过80字符2.2.2. SELE

9、CT/FROM/WHERE/ORDER BY/GROUP BY等子句应独占一行。2.2.3. SQL语句中间不允许出现空行2.2.4. SELECT子句内容如果只有一项,应与 SELECT 同占一行。2.2.5. SELECT子句内容如果多于一项,每一项都应独占一行,并在对应 SELECT的基础上向右缩进8个空格。2.2.6. FROM子句内容如果只有一项,应与 FROM同占一行。2.2.7. FROM子句内容如果多于一项,每一项都应独占一行,并在对应FROM的基础上向右缩进4个空格。2.2.8. WHERE子句内容如果只有一项,应与 WHERE同占一行。2.2.9. WHERE子句的条件如果

10、有多项,每一个条件应独占一行,并以AND开头,并在对应WHERE的基础上向右缩进4个空格。2.2.9.1. 进1个Tab或者4个字符。示例:/SELECT语句书写的正确示例SELECT bill_no,FROM mft_listWHERE manifest_no =000000000000000007;SELECT list.manifest_no,list.list_no,stat.list_statFROMmft_list list,list_stat statWHERE list.manifest_no = stat.manifest_noAND stat.stat != 2;2.2.1

11、0. (UPDATE)SET子句内容如果有一项,应与 SET同占一行。2.2.11. (UPDATE)SET子句内容如果有多项,每一项应独占一行,并在对应SET的基础上向右缩进4个空格。示例:/UPDATE语句书写的正确示例UPDATE list_statSETlist_stat = 2, parent = 0WHERE list_no = bill010; 2.2.12. INSERT 子句左/右括号以及每个表字段应独占一行,其中括号无缩进,表字段在对应括号的基础上向右缩进4个空格。2.2.13. VALUES子句左/右括号以及每一项的值应独占一行,其中括号无缩进,每一项的值在对应括号的基础

12、上向右缩进4个字符。示例:/INSERT语句书写的正确示例INSERT INTO list_stat( list_no, list_stat, parent, manifest_no, div_flag)VALUES( bill020,1,0, 000000000000007807, 0); 2.3. 空格2.3.1. SQL内算数运算符、逻辑运算符连接的两个元素之间必须用空格分隔2.3.2. 逗号之后必须接一个空格2.3.3. 关键字、保留字和左括号之间必须有一个空格2.4. 大小写2.4.1. SQL语句中出现的所有表名、表别名、字段名、序列等数据库对象都应小写2.4.2. SQL 语句中

13、出现的系统保留字、内置函数名、SQL保留字、绑定变量等都应大写。2.5. 对齐2.5.1. 变量初始化赋值时,各变量列对齐,赋值号列对齐,被赋值列对齐;3. 变量命名规则3.1. 输入变量in + 变量含义的英文单词,单词的首字母大写,单词之间用”_”分割。3.2. 输出变量out + 变量含义的英文单词,单词的首字母大写,单词之间用”_”分割。3.3. 内部变量v + 变量含义的英文单词,单词的首字母大写,单词之间用”_”分割。3.4. 游标命名CURSOR_表名4. BC命名规范4.1. 查询类BC 命名规则:cQ表名缩写By查询条件 例如: cQCustInfoByCustId cQUs

14、erInfoByCustId 对于查询条件是多个的,可选择一个具有代表性的字段作为查询条件,或者新定义一个新的单词 例如根据客户类型、证件类型、证件号码查询客户信息的BC,命名为cQCustInfoByIccid 4.2. 删除类BC 根据主键删除的, 命名规则:cD表名缩写 不根据主键删除的, 命名规则:cD表名缩写By删除条件 例如: 根据用户标识删除用户扩展属性,用户标识是非主键,BC命名为cDUserAddInfoByIdNo 根据主键(用户标识+属性代码)删除的, BC命名为 cDUserAddInfo 4.3. 修改类BC 根据主键修改的, 命名规则:cU字段信息Of表名缩写 不根

15、据主键修改的, 命名规则:cU字段信息Of表名缩写By修改条件 例如: 根据群成员标识 修改群成员的状态, BC命名为cUStateOfUserGroupMbrInfo 根据群标识修改群成员表中其所有成员的状态,BC命名为cUStateOfUserGroupMbrInfoByGrpId 4.4. 插入类BC 插入本表, 命名规则:cI表名缩写 插入历史表: 1、插入本表时,插入历史表, 命名规则:cI历史表表名缩写 2、删除、修改本表时,将数据备份到历史 i、根据主键删除修改时备份入历史, 命名规则为:cI历史表表名缩写Bak ii、不根据主键删除修改时备份入历史,命名规则为:cI历史表表名缩

16、写BakBy条件 例如: 插入用户扩展信息表 BC命名为cIUserAddInfo 插入用户扩展信息表时插用户扩展信息历史表 BC命名为cIUserAddInfoHis 根据(用户标识+属性代码)删除用户扩展信息之前,将预删除记录备份到历史 BC命名为cIUserAddInfoHisBak 根据用户标识删除用户扩展信息之前,将预删除记录备份到历史 BC命名为cIUserAddInfoHisBakByIdNo 4.5. 多表联合查询类BC 命名规则:cGet获取信息描述By条件 例如: 根据用户标识联合查询用户信息表和客户信息表,获取客户基本信息 BC命名为cGetCustInfoByIdNo5

17、. 编码规范5.1. 不等于统一使用Oracle认为!=和是等价的,都代表不等于的意义。为了统一,不等于一律使用表示。5.2. 使用表的别名多表连接时,应为每个表使用别名,别名要简短最好一个字母,且能代表一定意义,所有被引用列要加上表的别名。5.3. 使用SELECT语句时,必须指出列名不要使用列的序号或者用“*”替代所有列名。5.4. 使用INSERT语句时,必须指定插入的字段名。5.5. 减少子查询的使用子查询除了可读性差之外,还在一定程度上影响了SQL运行效率. 请尽量减少子查询的使用,采用其他效率更高、可读性更好的方式替代5.6. 适当添加索引以提高查询效率适当添加索引可以大幅度的提高

18、检索速度(具体的优化方法见附录A性能优化部分)5.7. 不要在WHERE字句中对索引列施以函数5.8. 不要使用数据库的类型自动转换功能,使用显式的类型转换5.9. 应使用变量绑定实现SQL语句共享,避免使用硬编码5.9.1. 不允许直接拼写SQL语句,而要使用绑定变量。例如:例1:此种写法不允许:init(dynStmt); sprintf(dynStmt,INSERT INTO wChg%s(id_no,total_date,login_accept,sm_code,belong_code,phone_no,org_code,login_no,op_code,op_time,machine

19、_code,cash_pay,check_pay,sim_fee,machine_fee,innet_fee,choice_fee,other_fee,hand_fee,deposit,back_flag,encrypt_fee,system_note,op_note)VALUES(%ld,TO_NUMBER(%s),%ld,%s,%s,%s,%s,%s,%s,TO_DATE(%s,yyyymmdd hh24:mi:ss),zz,0,0,0,0,0,0,0,0,0,0,0,%s,%s),YearMonth,idNo,totalDate,LoginAccept,smCode,belongCode

20、,phoneNo,orgCode,loginNo,opCode,opTime,systemNote,systemNote); EXEC SQL PREPARE ins_stmt FROM :dynStmt; EXEC SQL EXECUTE ins_stmt ; 例2:可以使用:init(dynStmt); sprintf(dynStmt, INSERT INTO wLoginOpr%s ( total_date,login_accept,op_code,pay_type,pay_money, sm_code,id_no,phone_no,org_code,loin_no,op_time,op

21、_note,ip_addr ) VALUES ( TO_NUMBER(:v1), :v2, :v3, :v4, :v5, :v6, :v7, :v8, :v9, :v10, TO_DATE(:v11, yyyymmdd hh24:mi:ss), :v12, :v13 ), YearMonth); EXEC SQL PREPARE prepare1 FROM :dynStmt; EXEC SQL EXECUTE prepare1 USING :totalDate, :LoginAccept, :opCode, :payType,:handFee, :smCode,:idNo, :phoneNo,

22、 :orgCode,:loginNo,:opTime, :opNote,:ipAddress; 例3:可以使用:EXEC SQL INSERT INTO dCustMsgAdd ( id_no,busi_type,user_type,field_code,field_order,field_value,other_value ) VALUES ( :idNo, :busiType, :userType, :fieldCode, :fieldOrder,:fieldValue, :otherValue );5.9.2. 执行相同操作的SQL语句必须使用相同名字的绑定变量。例如:第一组的两个SQL

23、语句,绑定变量是相同的,而第二组中的两个语句绑定变量不同,即使赋于不同的绑定变量相同的值也不能使这两个SQL语句相同,达不到共享SQL语句目的。 a)第一组 select pin , name from people where pin = :blk1.pin; select pin , name from people where pin = :blk1.pin; b)第二组 select pin , name from people where pin = :blk1.ot_ind; select pin , name from people where pin = :blk1.ov_in

24、d; 5.10. 用执行计划分析SQL性能EXPLAIN PLAN是一个很好的分析SQL语句的工具,它可以在不执行SQL的情况下分析语句. 通过分析,我们就可以知道ORACLE是怎样连接表,使用什么方式扫描表(索引扫描或全表扫描),以及使用到的索引名称, 按照从里到外,从上到下的次序解读分析的结果。EXPLAIN PLAN的分析结果是用缩进的格式排列的,最内部的操作将最先被解读,如果两个操作处于同一层中,带有最小操作号的将首先被执行。目前许多第三方的工具如PLSQL Developer和TOAD等都提供了极其方便的EXPLAIN PLAN工具。附录A:Oracle SQL性能优化A.1 选用适

25、合的ORACLE优化器l ORACLE的优化器共有3种: RULE (基于规则) COST (基于成本) CHOOSE (选择性) 设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS. 你当然也可以在SQL句级或是会话(session)级对其进行覆盖. l 为了使用基于成本的优化器(CBO, Cost-Based Optimizer), 你必须经常运行analyze 命令,以增加数据库中的对象统计信息(object statistics)的准确性. 如果数据库的优化器模式设置为

26、选择性(CHOOSE),那么实际的优化器模式将和是否运行过analyze命令有关. 如果table已经被analyze过, 优化器模式将自动成为CBO, 反之,数据库将采用RULE形式的优化器.l 在缺省情况下,ORACLE采用CHOOSE优化器, 为了避免那些不必要的全表扫描(full table scan) , 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器A.2 访问TABLE的方式ORACLE 采用两种访问表中记录的方式:l 全表扫描全表扫描就是顺序地访问表中每条记录. ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描.

27、l 通过ROWID访问表你可以采用基于ROWID的访问方式情况,提高访问表的效率, ROWID包含了表中记录的物理位置信息. ORACLE采用索引(INDEX)实现了数据和存放数据的物理位置(ROWID)之间的联系. 通常索引提供了快速访问ROWID的方法, 因此那些基于索引列的查询就可以得到性能上的提高.A.3 共享SQL语句为了不重复解析相同的SQL语句,在第一次解析之后, ORACLE将SQL语句存放在内存中.这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享. 因此,当你执行一个SQL语句

28、(有时被称为一个游标)时,如果它 和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的 执行路径. ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用. 可惜的是ORACLE只对简单的表提供高速缓冲(cache buffering) ,这个功能并不适用于多表连接查询. 数据库管理员必须在init.ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了. 当你向ORACLE 提交一个SQL语句,ORACLE会首先在这块内存中查找相同的语句. 这里需要注明的是,ORACLE对两者采取的是一种严格匹配,

29、要达成共享,SQL语句必须 完全相同(包括空格,换行等).共享的语句必须满足三个条件:l 字符级的比较: 当前被执行的语句和共享池中的语句必须完全相同例如: SELECT * FROM EMP; 和下列每一个都不同 SELECT * from EMP; Select * From Emp; SELECT * FROM EMP;l 两个语句所指的对象必须完全相同例如: 用户 对象名 如何访问 Jack sal_limit private synonym JackWork_city public synonym JackPlant_detail public synonym Jill sal_li

30、mit private synonym Jill Work_city public synonym JillPlant_detail table owner考虑一下下列SQL语句能否在这两个用户(Jack, Jill)之间共享? SQL: SELECT MAX(sal_cap) FROM sal_limit; 能否共享: 不能 原因: 每个用户都有一个private synonym - sal_limit , 它们是不同的对象 SQL: SELECT COUNT(0) FROM work_city WHERE sdesc LIKE NEW%; 能否共享: 不能 原因: 两个用户访问相同的对象p

31、ublic synonym - work_city SQL: SELECT a.sdesc,b.location FROM work_city a , plant_detail b WHERE a.city_id = b.city_id 能否共享: 不能 原因: 用户jack 通过public synonym访问plant_detail 而jill 是表的所有者,对象不同.l 两个SQL语句中必须使用相同的名字的绑定变量(bind variables) 例如: 第一组的两个SQL语句是相同的(可以共享),而第二组中的两个语句是不同的(即使在运行时,赋于不同的绑定变量相同的值) a)第一组 se

32、lect pin , name from people where pin = :blk1.pin; select pin , name from people where pin = :blk1.pin; b)第二组 select pin , name from people where pin = :blk1.ot_ind; select pin , name from people where pin = :blk1.ov_ind; A.4 选择最有效率的表名顺序(只在基于规则的优化器中有效)ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名.因此FROM子句中写在最后的表(

33、基础表 driving table)将被最先处理. 在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们.首先,扫描第一个表(FROM子句中最后的那个表)并对记录进行派序,然后扫描第二个表(FROM子句中最后第二个表),最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并.例如: 表 TAB1 16,384 条记录 表 TAB2 1 条记录 l 选择TAB2作为基础表 (最好的方法) select count(*) from tab1,tab2 执行时间0.96秒 l 选择TAB2作为基础表 (不佳的方

34、法) select count(*) from tab2,tab1 执行时间26.09秒 l 如果有3个以上的表连接查询, 那就需要选择交叉表(intersection table)作为基础表, 交叉表是指那个被其他表所引用的表. 例如: EMP表描述了LOCATION表和CATEGORY表的交集. SELECT * FROM LOCATION L , CATEGORY C, EMP E WHERE E.EMP_NO BETWEEN 1000 AND 2000 AND E.CAT_NO = C.CAT_NO AND E.LOCN = L.LOCN 将比下列SQL更有效率 SELECT * FR

35、OM EMP E , LOCATION L , CATEGORY C WHERE E.CAT_NO = C.CAT_NO AND E.LOCN = L.LOCN AND E.EMP_NO BETWEEN 1000 AND 2000A.5 WHERE子句中的连接顺序ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.例如: l (低效,执行时间156.3秒) SELECT FROM EMP E WHERE SAL 50000 AND JOB = MANAGER AND 25 (

36、SELECT COUNT(*) FROM EMP WHERE MGR=E.EMPNO); l (高效,执行时间10.6秒) SELECT FROM EMP E WHERE 25 50000 AND JOB = MANAGER;A.6 SELECT子句中避免使用 * 当你想在SELECT子句中列出所有的COLUMN时, 使用动态SQL列引用 * 是一个方便的方法. 不幸的是,这是一个非常低效的方法. 实际上,ORACLE在解析的过程中, 会将* 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间.A.7 减少访问数据库的次数当执行每条SQL语句时, ORACLE

37、在内部执行了许多工作: 解析SQL语句, 估算索引的利用率, 绑定变量 , 读数据块等等. 由此可见, 减少访问数据库的次数 , 就能实际上减少ORACLE的工作量.例如, 以下有三种方法可以检索出雇员号等于0342或0291的职员. l 方法1 (最低效) SELECT EMP_NAME , SALARY , GRADE FROM EMP WHERE EMP_NO = 342; SELECT EMP_NAME , SALARY , GRADE FROM EMP WHERE EMP_NO = 291; l 方法2 (次低效) DECLARE CURSOR C1 (E_NO NUMBER) IS

38、 SELECT EMP_NAME,SALARY,GRADE FROM EMP WHERE EMP_NO = E_NO; BEGIN OPEN C1(342); FETCH C1 INTO ,.,. ; . OPEN C1(291); FETCH C1 INTO ,.,. ; CLOSE C1; END; l 方法3 (高效) SELECT A.EMP_NAME , A.SALARY , A.GRADE, B.EMP_NAME , B.SALARY , B.GRADE FROM EMP A,EMP B WHERE A.EMP_NO = 342 OR B.EMP_NO = 291; 注意: 在SQ

39、L*Plus , SQL*Forms和Pro*C中重新设置ARRAYSIZE参数, 可以增加每次数据库访问的检索数据量 ,建议值为200A.8 使用DECODE函数来减少处理时间使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.例如: SELECT COUNT(*),SUM(SAL) FROMEMP WHERE DEPT_NO = 0020 AND ENAME LIKESMITH%; SELECT COUNT(*),SUM(SAL) FROMEMP WHERE DEPT_NO = 0030 AND ENAME LIKESMITH%; 你可以用DECODE函数高效地得到相同结果 S

40、ELECT COUNT(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 FROM EMP WHERE ENAME LIKE SMITH%; 类似的,DECODE函数也可以运用于GROUP BY 和ORDER BY子句中A.9 整合简单,无关联的数据库访问如果你有几个简单的数据库查询语句,你可以

41、把它们整合到一个查询中(即使它们之间没有关系)例如: SELECT NAME FROM EMP WHERE EMP_NO = 1234; SELECT NAME FROM DPT WHERE DPT_NO = 10 ; SELECT NAME FROM CAT WHERE CAT_TYPE = RD; 上面的3个查询可以被合并成一个: SELECT E.NAME , D.NAME , C.NAME FROM CAT C , DPT D , EMP E,DUAL X WHERE NVL(X,X.DUMMY) = NVL(X,E.ROWID(+) AND NVL(X,X.DUMMY) = NVL(X,D.ROWID(+) AND NVL(X,X.DUMMY) = NVL(X,C.ROWID(+) AND E.EMP_NO(+) = 1234 AND D.DEPT_NO(+) = 10 AND C.CAT_TYPE(+) = RD; A.10 删除重复记录最高效的删除重复记录方法 (因为使用了ROWID)DELETE FROM EMP E WHERE E.ROWID (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO);A.11

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号