关闭

关闭

关闭

封号提示

内容

首页 剑破冰山-Oracle开发艺术.pdf

剑破冰山-Oracle开发艺术.pdf

剑破冰山-Oracle开发艺术.pdf

上传者: genwen 2011-10-10 评分 0 0 0 0 0 0 暂无简介 简介 举报

简介:本文档为《剑破冰山-Oracle开发艺术pdf》,可适用于IT/计算机领域,主题内容包含第章大话数据库编程规范目前在软件圈内有这么一个现象就是DBA不太懂得写PLSQL而开发人员写得又是五花八门而且效率不高。如此一来造成诸多弊端:可读性符等。

第章大话数据库编程规范目前在软件圈内有这么一个现象就是DBA不太懂得写PLSQL而开发人员写得又是五花八门而且效率不高。如此一来造成诸多弊端:可读性差。读别人写的一个程序花费的时间比自己写一个程序花费的时间还要长不但别人看不懂时间久了连自己也看不懂了。可维护性差。程序越写越长越改越烂。可移植性差。今天用Oracle写一套明天换成SQLServer的时候再写一套众多的数据库开发人员在程序的苦海中重复着低级劳动。效率和性能差。一个存储过程或SQL执行效率简直可以让你感觉到对时间的绝望你很快就理解什么是相对论了。编程规范概述事实上为了统一在软件开发过程中关于数据库设计时的命名规范和编程规范正规的IT公司都会制定一些关于数据库对象的命名和编程规范。否则你写你的我写我的各自为战不兼容彼此看不懂甚至到最后连自己都弄不明白了这样的经历相信每个人都曾经遇到过。第章大话数据库编程规范剑破冰山Oracle开发艺术剑破冰山Oracle开发艺术如下面这段简单的代码你看得明白吗?就算暂时明白过个一年半载你还明白吗?就算你记忆超群想必也会忘记不是吗?A:=b:=SeLeCTusernamefromEmPLOyeewhereid=aaNdType=b如果你改为下面这样的写法相信稍微懂点数据库的人都应该看得明白。vID:=A为IDvType=B为类型SELECTusernameFROMemployeeWHEREid=vIDANDtype=vType书写规范丑陋的书写规范不仅可读性较差而且给人以敬而远之的感觉就算你是大侠也不行而良好的书写规范则给人以享受和艺术的体验。大小写风格规则所有数据库关键字和保留字均使用大写关于字段、变量的大小写风格在节详细介绍。缩进风格规则程序块严格采用缩进风格书写保证代码清晰易读风格一致缩进格数统一为个。必须使用空格不允许使用【Tab】键。以免在用不同的编辑器阅读程序时因【Tab】键所设置的空格数目不同而造成程序布局不整齐。规则当同一条语句需要占用多于一行时每行的其他关键字与第一行的关键字进行右对齐。IFflag=THENSELECTusername同上一行相比缩进个空格INTOvuserinfoINTO与SELECT进行右对齐FROMuserinfoFROM与SELECT进行右对齐WHEREuserid=:iuseridWHERE与SELECT进行右对齐ENDIF第章大话数据库编程规范空格及换行规则不允许把多个语句写在一行中即一行只写一条语句。规则避免将复杂的SQL语句写到同一行建议要在关键字和谓词处换行。规则相对独立的程序块之间必须加空行。BEGIN、END独立成行。规则太长的表达式应在低优先级操作符处换行操作符或关键字放在新行之首。划分出新行应当适当地缩进使排列整齐语句可读。当不同类型的操作符混合使用时建议使用括号进行隔离以使代码清晰。规则减少控制语句的检查次数例如在IF…ELSE控制语句中应将最常用的符合条件前置以被检查到。DECLARE定义局部变量vFlagVARCHAR()判断标志…BEGINIF((a=bANDa=cANDa=d)OR在OR处断行可使得逻辑更为清晰(a=eANDe=f))THENProcesssomethingIFvFlag=THENvFlag=为经常出现的条件可有效减少判断检查次数ProcesssomethingELSIFvFlag=THENvFlag=为次之出现的条件ProcesssomethingELSEProcesssomethingENDIF剑破冰山Oracle开发艺术其他规则避免使用SELECT*语句不要用*来代替所有字段应给出字段列表以避免在表结构发生变化时应用程序出现无法识别的情况。规则INSERT语句必须给出字段列表以避免在表结构发生变化时发生编译错误。规则当一个PLSQL或SQL语句中涉及多个表时始终使用别名来限定表名和字段名这使其他人阅读起来更方便避免了含义模糊的引用并能够在别名中清晰地判断出表名和相关字段名。规则确保变量和参数在类型和长度上与表数据列相匹配。如果与表数据列宽度不匹配则当较宽或较大的数据传进来时会产生运行异常。DECLARE定义相关表字段变量vDeptNosalaryDeptnotypenotVARCHAR()以适应变化vEmployeeNosalaryEmployeeNotypenotVARCHAR()以适应变化vSalarysalarySalarytypenotNUMBER以适应变化BEGINProcesssomethingEND命名规范一千个读者就有一千个哈姆雷特对于命名规范来说想做到完全统一的确是不可能的任务。命名规范更多的是个人层面的爱好就算有命名规范也不过是体现制定规范的相关人的爱好而已。即使无法完全做到一致但是我们仍然要尽量去遵守必要的时候需要通过代码检查和专家评审来进行约束因为一个不成熟的规范总会胜过没有规范。表和字段命名规范在此仅提供几种常见的命名方法(表和字段的命名方式雷同)。第章大话数据库编程规范以用户权限字段表为例如表所示。表命名规范表UserPrivilege适合那些英文比较好并且喜欢抑扬顿挫和有艺术美感的人userprivilege适合那些英文好且比较严谨的人毕竟全部小写很容易与数据库关键字区别tbluserprivilege适合那些做开发的人开发的人会习惯性地给变量加前缀(这里指表的命名字段一般很少加前缀)yhqx热爱中文的人前提是恐怕你得对这些缩写先做好相关备注等大家习惯了才行实际上这几种命名规范各有千秋很难去指责或否定哪种不好完全取决于整个公司多数人的习惯记住没有十全十美的命名规范只有绝大多数人心甘情愿地去遵从了那就是好的命名规范。就笔者个人而言我更偏向于第一种命名习惯。规则不建议使用数据库关键字和保留字(不建议并不意味着不能使用)只是为了避免不必要的冲突和麻烦。例如name,id,level,remark,description等。如果有兴趣则大家可以参考SELECT*FROMv$reservedwordsWHEREreserved='Y'。实际上Oracle不建议大家使用v$reservedwords表中所有的关键字因为这些关键字太多了reserved='Y'的关键字则是被完全禁止的。规则严禁使用带空格的名称来给字段和表命名在产生数据库脚本并重新加载的时候可能会出现错误而被迫终止。其他对象命名用户自定义的数据库对象名包括表、视图、主外键、索引、触发器、函数、存储过程、序列、同义词、数据库链接、包和包体等。规则其他对象的命名也与表和字段的命名规则类似风格保持一致即可。规则除数据库名称长度为~个字符外其余为~个字符databaselink名称也不要超过剑破冰山Oracle开发艺术个字符。命名只能使用英文字母、数字和下画线。规则除表外其他各种对象的命名最好用不同的前缀加以区别。采用前缀的方式来命名对象则很容易通过排序对对象进行区别。如在命名规范中各组成部分以“”分割则前缀建议也以“”分割反之则可加可不加如表所示。表其他对象命名规范表对象名前缀范例表(table)tblt(或不加前缀)userinfotuserinfotbluserinfo视图(view)vvvuserinfovuserinfo序列(sequence)seqsequserinfo簇(cluster)ccuserinfo触发器(trigger)trgtrguserinfo存储过程(procedure)sppspuserinfopuserinfo函数(function)ffnfnuserinfofuserinfo物化视图(materializedview)mvmvuserinfo包和包体(packagepackagebody)pkgpkguserinfo类和类体(typetypebody)typtypuserinfo主键(primarykey)pkpkuserinfo外键(foreignkey)fkfkuserinfofieldname唯一索引(uniqueindex)ukukuserinfofieldname普通索引(normalindex)idxidxuserinfofieldname位图索引(bitmapindex)bkbkuserinfofieldname同义词(synonym)依据所分配的表所属模块模式数据库链接(databaselink)无特殊要求第章大话数据库编程规范变量命名规则所有PLSQL中的变量与对象命名规则相似如表所示。表变量命名规范表变量类型前缀范例输入变量iiiuseridiuserid输出变量ooousernameousername输出输入变量ioioiousernameiousername普通变量vvvuseridvuserid全局变量gvgvgvuseridgvuserid常量大写PI游标curcuruserinfo用户自定义类型typetypeuserinfo保存点(savepoint)sptsptuserinfo规则命名不允许使用中文或者特殊字符。命名中若使用特殊约定或缩写则要注释说明。规则使用有意义、易于记忆、描述性强、简短及唯一的英文单词拼音缩写。保持自己特有的命名风格不可来回变化。说明:个人命名风格在符合所在项目组的命名规则的前提下才可以使用。规则对于变量命名禁止取单个字符(如i、j„„)建议除了要有具体含义外还要能表明变量类型等。说明:变量尤其是局部变量如果用单个字符表示很容易输错(如i写成j)而编译时又检查不出来有可能因为这个小小的错误而花费大量的时间。剑破冰山Oracle开发艺术注释规范注释规范是判断一个开发人员优劣和成熟度的重要标准。一个优秀的研发人员必然是经过深思熟虑后才洋洋洒洒妙笔生花的注释的书写体现了一个人思考问题的全过程和步骤话又说回来就算代码写得很差只要注释写得好至少也会给人以良好的感觉。规则在一般情况下源程序有效注释量必须在左右。说明:注释的原则是有助于对程序阅读理解在该加的地方都加了注释不宜太多也不能太少注释语言需准确、易懂、简洁、精炼。规则统一文件头的注释。主要是对相关过程、函数进行功能性描述、修订记录以及入参出参说明。对存储过程、函数的任何修改都需要在注释后添加修改人、修改日期及修改原因等修订说明。***********************************************************名称:spxxx功能描述:修订记录:版本号编辑时间编辑人修改描述John创建此存储过程Sandy增加传入参数入参出参描述:iparameterINVARCHAR()传入参数iparameterINVARCHAR()传入参数iparameterOUTVARCHAR()传出参数iparameterOUTVARCHAR()传出参数返回值描述:(主要针对函数)Successnormalfail***********************************************************规则所有变量定义需要加注释说明该变量的用途和含义。第章大话数据库编程规范规则注释内容要清晰、明了、含义准确防止注释二义性。在代码的功能、意图层次上进行注释提供有用、额外的信息。避免在一行代码或表达式的中间插入注释。尽量使用“”进行注释行尾注释需使用“”。规则对程序分支必须书写注释。说明:这些语句往往是程序实现某一特定功能的关键对于维护人员来说良好的注释有助于更好地理解程序有时甚至优于看设计文档。在程序块的结束行右方加注释以表明程序块结束。规则注释应与其描述的代码相似对代码的注释应放在其上方或右方(对单条语句的注释)相近位置不可放在下面。注释要与所描述的内容进行同样的缩排。注释上面的代码应空行隔开。规则注释用中文书写。有一次同事写了一个行的存储过程里面定义了十几个游标以进行遍历这个存储过程缺乏注释执行一次居然要一天一夜已经达到了无法容忍的地步。因为缺乏注释我花了整整一天的时间来对该存储过程进行分析然后用了半天时间来进行改写和调试。其实很简单把游标遍历替换成SQL的集合操作把整个大事务分割成若干个小事务然后修改了部分代码结果执行时间就变成了短短的分钟。当然游标也并非不可触及既然存在就有它存在的理由。语法规范良好的语法规范有助于书写出高效、完备的PLSQL程序同时有助于提高系统的容错性、剑破冰山Oracle开发艺术健壮性、可追溯性。规则避免隐式的数据类型转换。说明:在书写代码时必须确定表的结构和表中各个字段的数据类型特别是在书写查询条件时的字段就更要注意了。这个是导致SQL性能不佳的原因之一。规则为了方便不同数据库平台的移植尽量使用SQL标准而不要使用Oracle的“方言”。例如DECODE函数完全可以用CASEWHEN语句代替而且可编程性更强。()=右关联用RIGHTOUTERJOIN语句代替。=()左关联用LEFTOUTERJOIN语句代替。规则对于非常复杂的SQL(特别是多层嵌套、带子句或相关的查询)应该先考虑是否是由设计不当引起的对于复杂的一些SQL可以考虑使用程序实现原则上遵循一句话只做一件事情。关于处理的优先级。静态SQL>动态SQL。绑定变量的SQL>动态SQL(在OLTP系统中建议这么做)。SQL>PLSQL的过程极端复杂的SQL除外。SQL>游标遍历。Oracle函数>自定义函数。尽量使用Oracle分析函数代替同一个表多次的关联。规则原则上不要使用动态SQL如果非得使用动态SQL建议使用绑定变量。规则一定要及时关闭和释放游标。规则建议在异常处理中把收集到的错误信息记入错误日志表以备查询和分析。CREATEORREPLACEPROCEDUREspincreamentxxx***********************************************************名称:spincreamentxxx功能描述:xxx表模块数据增量更新错误原因分析通过tbltasktable日志表第章大话数据库编程规范修订记录:版本号编辑时间编辑人修改描述John创建此存储过程Sandy更新xxx字段在xxx处入参出参描述:NA返回值描述:(主要针对函数)NA***********************************************************ASverrnumNUMBERverrmsgVARCHAR()vbegindateDATEvenddateDATEBEGINverrnum:=verrmsg:=''某表增量更新步骤BEGINSAVEPOINTsptxxx从任务表中获取初始更新时间SELECTlasttimeINTOvbegindateFROMtbltasktableTWHEREid='spincreamentxxx'从源数据表中获取等待结束更新时间SELECTMAX(operdate)INTOvenddateFROMtbltablesource为提高执行效率将增量数据写入临时表中INSERTINTOtmptbltablesource(fieldname,fieldname,fieldname,fieldname,fieldname,fieldname)SELECTfieldname,fieldname,fieldname,fieldname,fieldname,fieldnameFROMtbltablesourcesourcetableWHEREsourcetablecreatedate>vbegindateANDsourcetablecreatedate<=venddate再将增量数据从临时表更新到最终目标表MERGEINTOtbltableoriginaldestdesttableUSINGtmptbltablesourcetmptableON(desttableprimarykey=tmptableprimarykey)匹配判断标准根据主键判断WHENMATCHEDTHEN如果已存在更新原记录UPDATESETdesttablefieldname=tmptablefieldname,desttablefieldname=tmptablefieldname,desttablefieldnamem=tmptablefieldnamem,desttablefieldnamen=tmptablefieldnamenWHENNOTMATCHEDTHEN如果不存在插入新记录INSERT(fieldname,fieldname,fieldname,剑破冰山Oracle开发艺术fieldname,fieldname,fieldname)VALUES(tmptablefieldname,tmptablefieldname,tmptablefieldname,tmptablefieldname,tmptablefieldname,tmptablefieldname)更新任务表相应的状态、时间UPDATEtbltasktableSETlasttime=venddate,status='SUCCESS'WHEREid='spincreamentxxx'COMMIT异常处理把错误记入相关日志表可以及时找到错误原因并进行分析。EXCEPTIONWHENOTHERSTHENROLLBACKTOSAVEPOINTsptxxxverrnum:=SQLCODEverrmsg:=SUBSTR(SQLERRM,,)UPDATEtbltasktableSETlasttime=vbegindate,status='FAIL'WHEREid='spincreamentxxx'COMMITEND某表增量更新步骤BEGINENDEND本例为数据库定时调用存储过程同时也是为了演示存储过程的全部过程对于常用的由客户端调用的存储过程建议不要捕获异常而由客户程序进行直接处理。规则不要将空的变量值直接与比较运算符(符号)比较。如果变量可能为空应使用IS或ISNOT或NVL函数进行比较。规则尽可能地使用相关表字段的类型定义如TYPE、ROWTYPE。这样做当表结构发生变动的时候能够最大程度地做到容错性和健壮性。规则在存储过程中变量的声明应集中在AS和BEGIN关键字之间不允许在代码中随意定义变量。在定义变量时完成相同功能模块的变量应放在一起与不同模块的变量应空行隔开增加代码的可读性。第章大话数据库编程规范脚本规范脚本规范有助于进行版本基线的管理、版本控制也有助于系统的自动部署、定位和解决部署过程中出现的问题。规则所有脚本按分类或内容分开存放并按以下顺序进行存储:()创建数据库角色、用户脚本。()创建数据库表空间、数据文件脚本。()创建数据类型脚本自定义的数据类型。()创建业务表脚本表是其他依赖关系的基础。()创建临时表脚本可能会在过程脚本中用到。()创建视图脚本。()创建主外键脚本。()创建索引脚本。()创建触发器脚本。()创建函数、存储过程脚本。()初始化数据脚本。()创建作业脚本。规则创建每个对象代码的首部应该有对象注释。规则每个函数、存储过程应单独创建脚本在配置库上按照功能模块存放到不同的目录下。并在相应的目录下创建一个运行所有脚本的总脚本。第章gR新特性之递归with编程精粹with子查询也称为CTE(CommonTableExpression)是ANSISQL标准的一部分。Oracle从i开始引入with子查询把它称作SUBQUERYFACTORING(分解子查询)。with子查询的作用类似于内联视图(inlineview)。内联视图的定义写在SQL的FROM后面只能够引用一次而with子查询需要在引用之前先定义一旦定义了在整个查询的后续部分就可以按名称来反复引用从这点来看又很像临时表。从版本gR开始Oracle支持递归的with即允许在with子查询的定义中对自身引用。这不是什么新鲜事其他数据库如DB、Firebird、MicrosoftSQLServer、PostgreSQL都先于Oracle支持这一特性。但对于Oracle用户来说这一递归特性还是很令人期待的利用它可以轻易实现以往做不到的、或者很难做到的许多事。这一章我们就来探索这一令人兴奋的新特性并把它和以往的实现手段(主要是connectby层次查询)作比较。我们先来看看这个递归with子查询的语法。WITHqueryname(calias,calias)AS(subquery)第章gR新特性之递归with编程精粹剑破冰山Oracle开发艺术第章gR新特性之递归with编程精粹searchclausecycleclause,queryname(calias,calias)AS(subquery)searchclausecycleclause是子查询的名称和以往不同的是必须在括号中把这个子查询的所有列名写出来。AS后面的subquery就是查询语句递归部分就写在这里。遍历顺序子句可以指定深度优先或广度优先遍历顺序。循环子句用于中止遍历中出现的死循环。如果还有其他递归子查询定义同上。subquery部分由两个成员组成anchormember(锚点成员)和recursivemember(递归成员)。它们之间必须用unionall联合起来anchormember必须写在recursivemember前面。anchormember用来定位递归的入口锚点成员是一个select语句它不可以包含自身名称(queryname)。这相当于connectby查询中的startwith典型写法就是:SELECTFROM要遍历的表WHERE(起始条件)。递归成员也是一个语句用于定义上下级的关系它必须包含自身名称(即queryname)而且仅仅只能引用一次。递归正是体现在对于自身的引用。典型的做法就是把queryname和其他表(一般来说就是要遍历的表)做一个连接连接条件表明了上下级的关系。必须注意在这个queryname中并不是目前为止的所有数据都是可见的可见的只是上次递归新加入的最近的一层数据。对queryname列的引用相当于connectby中的PRIOR操作符。当找不到满足条件的下级遍历就会停止如果你还有其他的递归出口条件也可以一起写在where中当where不满足时遍历就会停止这就是在遍历树、图时候的剪枝操作。越早停止则效率越高。这个递归成员就是程序员发挥创造力的地方以往在connectby中做不到的事情比如沿路径求和、求积等运算现在都轻而易举。而sysconnectbypath也很容易用字符串拼接'||'来实现。搜索子句(searchclause)和循环子句(cycleclause)我们后面的例子中会见到。下面我们就来看看递归with子查询的用法实例。上下级关系例:从scotttiger的emp表来查找上下级关系传统的connectby写法:SELECTempno,ename,job,mgr剑破冰山Oracle开发艺术,deptno,level,SYSCONNECTBYPATH(ename,'')ASpath,CONNECTBYROOT(ename)AStopmanagerFROMEMPSTARTWITHmgrISmgr列为空表示没有上级该员工已经是最高级别这是层次查询的起点CONNECTBYPRIORempno=mgr新的递归with写法:WITHT(empno,ename,job,mgr,deptno,thelevel,path,topmanager)AS(必须把结构写出来SELECTempno,ename,job,mgr,deptno先写锚点查询用startwith的条件,ASthelevel递归起点第一层,''||ename路径的第一截,enameAStopmanager原来的connectbyrootFROMEMPWHEREmgrIS原来的startwith条件UNIONALL下面是递归部分SELECTeempno,eename,ejob,emgr,edeptno要加入的新一层数据来自要遍历的emp表,tthelevel递归层次在原来的基础上加这相当于connectby查询中的level伪列,tpath||''||eename把新的一截路径拼上去,ttopmanager直接继承原来的数据因为每个路径的根节点只有一个FROMt,empe典型写法把子查询本身和要遍历的表作一个连接WHEREtempno=emgr原来的connectby条件)with定义结束SELECT*FROMT查询结果:EMPNOENAMEJOBMGRDEPTNOTHELEVELPATHTOPMANAGEKINGPRESIDENTKINGKINGJONESMANAGERKINGJONESKINGBLAKEMANAGERKINGBLAKEKINGCLARKMANAGERKINGCLARKKINGALLENSALESMANKINGBLAKEALLENKINGWARDSALESMANKINGBLAKEWARDKINGMARTINSALESMANKINGBLAKEMARTINKINGSCOTTANALYSTKINGJONESSCOTTKINGTURNERSALESMANKINGBLAKETURNERKINGJAMESCLERKKINGBLAKEJAMESKINGFORDANALYSTKINGJONESFORDKINGMILLERCLERKKINGCLARKMILLERKINGSMITHCLERKKINGJONESFORDSMITHKINGADAMSCLERKKINGJONESSCOTTADAMSKINGrowsselected从结果集的THELEVEL和PATH列可以清楚地看到数据是如何被一层一层叠加上去的。第章gR新特性之递归with编程精粹例:求遍历树中的叶子节点在例中我们看到一个求出所有员工的上下级关系的层次查询。现在假设要把最下级的员工求出来。CONNECTBY写法:SELECTempno,ename,job,deptno,LEVEL,SYSCONNECTBYPATH(ename,'')aspathFROMEMPWHERECONNECTBYISLEAF=叶子节点STARTWITHmgrISmgr列为空表示没有上级该员工已经是最高级别这是层次查询的起点CONNECTBYPRIORempno=mgr查询结果:EMPNOENAMEJOBDEPTNOLEVELPATHADAMSCLERKKINGJONESSCOTTADAMSSMITHCLERKKINGJONESFORDSMITHALLENSALESMANKINGBLAKEALLENWARDSALESMANKINGBLAKEWARDMARTINSALESMANKINGBLAKEMARTINTURNERSALESMANKINGBLAKETURNERJAMESCLERKKINGBLAKEJAMESMILLERCLERKKINGCLARKMILLERconnectbyisleaf是g以上提供的它是一个伪列当connectbyisleaf=时表示该行为叶子节点。在i中没有connectbyisleaf这个伪列我们可以根据叶子节点的定义写一个相关子查询。SELECTempno,ename,job,deptno,LEVEL,SYSCONNECTBYPATH(ename,'')aspathFROMEMPeWHERENOTEXISTS(SELECTFROMempWHEREmgr=eempno)相关子查询STARTWITHmgrISCONNECTBYPRIORempno=mgr在这里notexists相关子查询的意思即不存在下一级数据这正是叶子节点的定义。在递归with子查询中实现connectbyisleaf的方法:WITHT(empno,ename,mgr,thelevel,path)AS(必须把结构写出来SELECTempno,ename,mgr先写锚点查询用startwith的条件,ASthelevel递归起点第一层,''||ename路径的第一截FROMEMPWHEREmgrIS原来的startwith条件UNIONALL下面是递归部分SELECTeempno,eename,emgr要加入的新一层数据来自要遍历的emp表,tthelevel递归层次在原来的基础上加,tpath||''||eename把新的一截路径拼上去剑破冰山Oracle开发艺术FROMt,empe典型写法把子查询本身和要遍历的表作一个连接WHEREtempno=emgr原来的connectby条件)SEARCHDEPTHFIRSTBYmgrSETseq指定深度优先,按顺序生成序号seqSELECT*FROM(SELECTT*,(CASEWHENthelevel<LEAD(thelevel)OVER(ORDERBYseq)THENELSEEND)isleaf如果层数不增加则为叶子节点FROMT)WHEREisleaf=查询结果:EMPNOENAMEMGRTHELEVELPATHSEQISLEAFADAMSKINGJONESSCOTTADAMSSMITHKINGJONESFORDSMITHALLENKINGBLAKEALLENWARDKINGBLAKEWARDMARTINKINGBLAKEMARTINTURNERKINGBLAKETURNERJAMESKINGBLAKEJAMESMILLERKINGCLARKMILLERrowsselectedseq是整个结果集按照深度优先遍历顺序排序后的序号。按照深度优先的定义每个节点都要比它的上一节点更深一层除非已经到底(也就是叶子节点)。因此如果层数没有增加则我们知道碰到了叶子节点这就是最后一个CASE表达式的依据。这个例子中出现了前面没有的搜索子句(searchclause)。search子句的语法:SEARCH{DEPTHFIRSTBYcalias,caliasASC|DESCSFIRST|SLAST|BREADTHFIRSTBYcalias,caliasASC|DESCSFIRST|SLAST}SETorderingcolumnDEPTHFIRST表示按深度优先的顺序来输出。BY后面的列名及其升降序、空值放置顺

用户评论(1)

0/200
  • suepen 2011-10-24 21:35:32

    多谢,得跟上时代的步伐

精彩专题

上传我的资料

每篇奖励 +2积分

资料评价:

/13
仅支持在线阅读

意见
反馈

立即扫码关注

爱问共享资料微信公众号

返回
顶部