ORACLEPL/SQL编程详解SQL语言只是访问、操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发。PL/SQL是一种高级数据库程序设计语言,该语言专门用于在各种环境下对ORACLE数据库进行访问。由于该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理。除此之外,可以在ORACLE数据库的某些客户端工具中,使用PL/SQL语言也是该语言的一个特点。本章的主要内容是讨论引入PL/SQL语言的必要性和该语言的主要特点,以及了解PL/SQL语言的重要性和数据库版本问题。还要介绍一些贯穿全书的更详细的高级概念,并在本章的最后就我们在本书案例中使用的数据库表的若干约定做一说明。1.1SQL与PL/SQL1.1.1什么是PL/SQL?PL/SQL是ProcedureLanguage&StructuredQueryLanguage的缩写。ORACLE的SQL是支持ANSI(AmericannationalStandardsInstitute)和ISO92(InternationalStandardsOrganization)标准的产品。PL/SQL是对SQL语言存储过程语言的扩展。从ORACLE6以后,ORACLE的RDBMS附带了PL/SQL。它现在已经成为一种过程处理语言,简称PL/SQL。目前的PL/SQL包括两部分,一部分是数据库引擎部分;另一部分是可嵌入到许多产品(如C语言,JAVA语言等)工具中的独立引擎。可以将这两部分称为:数据库PL/SQL和工具PL/SQL。两者的编程非常相似。都具有编程结构、语法和逻辑机制。工具PL/SQL另外还增加了用于支持工具(如ORACLEForms)的句法,如:在窗体上设置按钮等。本章主要介绍数据库PL/SQL内容。1.2PL/SQL的优点或特征1.2.1有利于客户/服务器环境应用的运行对于客户/服务器环境来说,真正的瓶颈是网络上。无论网络多快,只要客户端与服务器进行大量的数据交换。应用运行的效率自然就回受到影响。如果使用PL/SQL进行编程,将这种具有大量数据处理的应用放在服务器端来执行。自然就省去了数据在网上的传输时间。1.2.2适合于客户环境PL/SQL由于分为数据库PL/SQL部分和工具PL/SQL。对于客户端来说,PL/SQL可以嵌套到相应的工具中,客户端程序可以执行本地包含PL/SQL部分,也可以向服务发SQL命令或激活服务器端的PL/SQL程序运行。1.2.3过程化PL/SQL是Oracle在标准SQL上的过程性扩展,不仅允许在PL/SQL程序内嵌入SQL语句,而且允许使用各种类型的条件分支语句和循环语句,可以多个应用程序之间共享其解决方案。1.2.4模块化PL/SQL程序结构是一种描述性很强、界限分明的块结构、嵌套块结构,被分成单独的过程、函数、触发器,且可以把它们组合为程序包,提高程序的模块化能力。1.2.5运行错误的可处理性使用PL/SQL提供的异常处理(EXCEPTION),开发人员可集中处理各种ORACLE错误和PL/SQL错误,或处理系统错误与自定义错误,以增强应用程序的健壮性。1.2.6提供大量内置程序包ORACLE提供了大量的内置程序包。通过这些程序包能够实现DBS的一些低层操作、高级功能,不论对DBA还是应用开发人员都具有重要作用。当然还有其它的一些优点如:更好的性能、可移植性和兼容性、可维护性、易用性与快速性等。1.3PL/SQL可用的SQL语句PL/SQL是ORACLE系统的核心语言,现在ORACLE的许多部件都是由PL/SQL写成。在PL/SQL中可以使用的SQL语句有:INSERT,UPDATE,DELETE,SELECTINTO,COMMIT,ROLLBACK,SAVEPOINT。提示:在PL/SQL中只能用SQL语句中的DML部分,不能用DDL部分,如果要在PL/SQL中使用DDL(如CREATEtable等)的话,只能以动态的方式来使用。ORACLE的PL/SQL组件在对PL/SQL程序进行解释时,同时对在其所使用的表名、列名及数据类型进行检查。PL/SQL可以在SQL*PLUS中使用。PL/SQL可以在高级语言中使用。PL/SQL可以在ORACLE的开发工具中使用(如:SQLDeveloper或ProcedureBuilder等)。其它开发工具也可以调用PL/SQL编写的过程和函数,如PowerBuilder等都可以调用服务器端的PL/SQL过程。1.4运行PL/SQL程序PL/SQL程序的运行是通过ORACLE中的一个引擎来进行的。这个引擎可能在ORACLE的服务器端,也可能在ORACLE应用开发的客户端。引擎执行PL/SQL中的过程性语句,然后将SQL语句发送给数据库服务器来执行。再将结果返回给执行端2.1PL/SQL块PL/SQL程序由三个块组成,即声明部分、执行部分、异常处理部分。PL/SQL块的结构如下:DECLARE--声明部分:在此声明PL/SQL用到的变量,类型及游标,以及局部的存储过程和函数BEGIN--执行部分:过程及SQL语句,即程序的主要部分EXCEPTION--执行异常部分:错误处理END;其中:执行部分不能省略。PL/SQL块可以分为三类:1.无名块或匿名块(anonymous):动态构造,只能执行一次,可调用其它程序,但不能被其它程序调用。2.命名块(named):是带有名称的匿名块,这个名称就是标签。3.子程序(subprogram):存储在数据库中的存储过程、函数等。当在数据库上建立好后可以在其它程序中调用它们。4.触发器(Trigger):当数据库发生操作时,会触发一些事件,从而自动执行相应的程序。5.程序包(package):存储在数据库中的一组子程序、变量定义。在包中的子程序可以被其它程序包或子程序调用。但如果声明的是局部子程序,则只能在定义该局部子程序的块中调用该局部子程序。2.2PL/SQL结构PL/SQL块中可以包含子块;子块可以位于PL/SQL中的任何部分;子块也即PL/SQL中的一条命令;2.3标识符PL/SQL程序设计中的标识符定义与SQL的标识符定义的要求相同。要求和限制有:标识符名不能超过30字符;第一个字符必须为字母;不分大小写;不能用’-‘(减号);不能是SQL保留字。提示:一般不要把变量名声明与表中字段名完全一样,如果这样可能得到不正确的结果.例如:下面的例子将会删除所有的纪录,而不是’EricHu’的记录;DECLAREenamevarchar2(20):='EricHu';BEGINDELETEFROMscott.empWHEREename=ename;END;变量命名在PL/SQL中有特别的讲究,建议在系统的设计阶段就要求所有编程人员共同遵守一定的要求,使得整个系统的文档在规范上达到要求。下面是建议的命名方法:标识符命名规则例子程序变量V_nameV_name程序常量C_NameC_company_name游标变量Cursor_NameCursor_Emp异常标识E_nameE_too_many表类型Name_table_typeEmp_record_type表Name_tableEmp记录类型Name_recordEmp_recordSQL*Plus替代变量P_nameP_sal绑定变量G_nameG_year_sal2.4PL/SQL变量类型在前面的介绍中,有系统的数据类型,也可以自定义数据类型。下表给出ORACLE类型和PL/SQL中的变量类型的合法使用列表:2.4.1变量类型在ORACLE8i中可以使用的变量类型有:类型子类说明范围ORACLE限制CHARCharacterStringRowidNchar定长字符串民族语言字符集032767可选,确省=12000VARCHAR2Varchar,StringNVARCHAR2可变字符串民族语言字符集03276740004000BINARY_INTEGER带符号整数,为整数计算优化性能NUMBER(p,s)DecDoubleprecisionIntegerIntNumericRealSmallint小数,NUMBER的子类型高精度实数整数,NUMBER的子类型整数,NUMBER的子类型与NUMBER等价与NUMBER等价整数,比integer小LONG变长字符串0-214748364732,767字节DATE日期型公元前4712年1月1日至公元后4712年12月31日BOOLEAN布尔型TRUE,FALSE,NULL不使用ROWID存放数据库行号UROWID通用行标识符,字符类型例1.插入一条记录并显示;DECLARERow_idROWID;infoVARCHAR2(40);BEGININSERTINTOscott.deptVALUES(90,'财务室','海口')RETURNINGrowid,dname||':'||to_char(deptno)||':'||locINTOrow_id,info;DBMS_OUTPUT.PUT_LINE('ROWID:'||row_id);DBMS_OUTPUT.PUT_LINE(info);END;其中:RETURNING子句用于检索INSERT语句中所影响的数据行数,当INSERT语句使用VALUES子句插入数据时,RETURNING字句还可将列表达式、ROWID和REF值返回到输出变量中。在使用RETURNING子句是应注意以下几点限制:1.不能与DML语句和远程对象一起使用;2.不能检索LONG类型信息;3.当通过视图向基表中插入数据时,只能与单基表视图一起使用。例2.修改一条记录并显示DECLARERow_idROWID;infoVARCHAR2(40);BEGINUPDATEdeptSETdeptno=100WHEREDNAME='财务室'RETURNINGrowid,dname||':'||to_char(deptno)||':'||locINTOrow_id,info;DBMS_OUTPUT.PUT_LINE('ROWID:'||row_id);DBMS_OUTPUT.PUT_LINE(info);END;其中:RETURNING子句用于检索被修改行的信息。当UPDATE语句修改单行数据时,RETURNING子句可以检索被修改行的ROWID和REF值,以及行中被修改列的列表达式,并可将他们存储到PL/SQL变量或复合变量中;当UPDATE语句修改多行数据时,RETURNING子句可以将被修改行的ROWID和REF值,以及列表达式值返回到复合变量数组中。在UPDATE中使用RETURNING子句的限制与INSERT语句中对RETURNING子句的限制相同。例3.删除一条记录并显示DECLARERow_idROWID;infoVARCHAR2(40);BEGINDELETEdeptWHEREDNAME='办公室'RETURNINGrowid,dname||':'||to_char(deptno)||':'||locINTOrow_id,info;DBMS_OUTPUT.PUT_LINE('ROWID:'||row_id);DBMS_OUTPUT.PUT_LINE(info);END;其中:RETURNING子句用于检索被删除行的信息:当DELETE语句删除单行数据时,RETURNING子句可以检索被删除行的ROWID和REF值,以及被删除列的列表达式,并可将他们存储到PL/SQL变量或复合变量中;当DELETE语句删除多行数据时,RETURNING子句可以将被删除行的ROWID和REF值,以及列表达式值返回到复合变量数组中。在DELETE中使用RETURNING子句的限制与INSERT语句中对RETURNING子句的限制相同。2.4.2复合类型ORACLE在PL/SQL中除了提供象前面介绍的各种类型外,还提供一种称为复合类型的类型---记录和表.2.