资源预览内容
第1页 / 共277页
第2页 / 共277页
第3页 / 共277页
第4页 / 共277页
第5页 / 共277页
第6页 / 共277页
第7页 / 共277页
第8页 / 共277页
第9页 / 共277页
第10页 / 共277页
亲,该文档总共277页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
进入夏天,少不了一个热字当头,电扇空调陆续登场,每逢此时,总会想起进入夏天,少不了一个热字当头,电扇空调陆续登场,每逢此时,总会想起那一把蒲扇。蒲扇,是记忆中的农村,夏季经常用的一件物品。记忆中的故那一把蒲扇。蒲扇,是记忆中的农村,夏季经常用的一件物品。记忆中的故乡,每逢进入夏天,集市上最常见的便是蒲扇、凉席,不论男女老少,个个手持乡,每逢进入夏天,集市上最常见的便是蒲扇、凉席,不论男女老少,个个手持一把,忽闪忽闪个不停,嘴里叨叨着一把,忽闪忽闪个不停,嘴里叨叨着“怎么这么热怎么这么热”,于是三五成群,聚在大树,于是三五成群,聚在大树下,或站着,或随即坐在石头上,手持那把扇子,边唠嗑边乘凉。孩子们却在周下,或站着,或随即坐在石头上,手持那把扇子,边唠嗑边乘凉。孩子们却在周围跑跑跳跳,热得满头大汗,不时听到围跑跑跳跳,热得满头大汗,不时听到“强子,别跑了,快来我给你扇扇强子,别跑了,快来我给你扇扇”。孩。孩子们才不听这一套,跑个没完,直到累气喘吁吁,这才一跑一踮地围过了,这时子们才不听这一套,跑个没完,直到累气喘吁吁,这才一跑一踮地围过了,这时母亲总是,好似生气的样子,边扇边训,母亲总是,好似生气的样子,边扇边训,“你看热的,跑什么?你看热的,跑什么?”此时这把蒲扇,此时这把蒲扇,是那么凉快,那么的温馨幸福,有母亲的味道!蒲扇是中国传统工艺品,在是那么凉快,那么的温馨幸福,有母亲的味道!蒲扇是中国传统工艺品,在我国已有三千年多年的历史。取材于棕榈树,制作简单,方便携带,且蒲扇的表我国已有三千年多年的历史。取材于棕榈树,制作简单,方便携带,且蒲扇的表面光滑,因而,古人常会在上面作画。古有棕扇、葵扇、蒲扇、蕉扇诸名,实即面光滑,因而,古人常会在上面作画。古有棕扇、葵扇、蒲扇、蕉扇诸名,实即今日的蒲扇,江浙称之为芭蕉扇。六七十年代,人们最常用的就是这种,似圆非今日的蒲扇,江浙称之为芭蕉扇。六七十年代,人们最常用的就是这种,似圆非圆,轻巧又便宜的蒲扇。蒲扇流传至今,我的记忆中,它跨越了半个世纪,圆,轻巧又便宜的蒲扇。蒲扇流传至今,我的记忆中,它跨越了半个世纪,也走过了我们的半个人生的轨迹,携带着特有的念想,一年年,一天天,流向长也走过了我们的半个人生的轨迹,携带着特有的念想,一年年,一天天,流向长长的时间隧道,袅长的时间隧道,袅应用于Web的面向对象关系型数据库管理系统Oracle本章目标本章目标iPL/SQL 简介简介 iPL/SQL 功能 i变量和常量变量和常量i对变量赋值 iPL/SQL 结构结构 i异常简介 预定义的异常 用户定义的异常2PL/SQL 功能(续)功能(续)i对诸如对诸如 SQL*Forms 等非过程工具增加了功能等非过程工具增加了功能 i使用 SQL*Forms 的开发人员可以输入使用单一触发器的整个 PL/SQL 程序块 i用用 PL/SQL 开发的应用程序可以移植到任何计开发的应用程序可以移植到任何计算机硬件和运行算机硬件和运行 Oracle 的操作系统的操作系统 i%TYPE 属性基于列定义的声明提供了与数据词典的集成 9PL/SQL 结构结构 i一个标准一个标准 PL/SQL 代码段称作程序块代码段称作程序块 i一个程序块是由三个部分或节构成的 声明部分声明部分 可执行部分 异常处理部分异常处理部分 10PL/SQL 结构(续)结构(续)11PL/SQL 结构(续)结构(续)i声明部分声明部分 定义对象的可选部分 i可执行部分可执行部分 构成可执行语句的必要部分 i异常处理部分异常处理部分 构成错误处理代码的可选部分 12PL/SQL 结构(续)结构(续)iDECLARE表示程序块声明部分的开始 声明对于程序块而言是局部的 iBEGIN表示程序块可执行部分的开始 iEND表示程序块的结束 13PL/SQL 结构(续)结构(续) i可以将语句在可以将语句在 PL/SQL 中分组中分组 i命名组称为子程序 i未命名组是匿名程序块未命名组是匿名程序块 i程序块可以包括称为嵌套程序块的多个块 i只允许在可执行程序和异常处理部分进行嵌套只允许在可执行程序和异常处理部分进行嵌套 i最多允许 200 级嵌套 14PL/SQL 结构(续)结构(续) i可以用任何编辑器编写可以用任何编辑器编写 PL/SQL程序,并将其程序,并将其保存为具有保存为具有 .sql 扩展名的文件扩展名的文件i也可以使用 SQL*Plus中的“ED”命令创建 PL/SQL 程序文件i使用使用 “ ”命令执行命令执行 PL/SQL 程序文程序文件件 15变量变量 i可以使用变量存储查询结果以便以后处理,或可以使用变量存储查询结果以便以后处理,或使用变量来计算要插入到数据库表中的值使用变量来计算要插入到数据库表中的值 i在 SQL 或 PL/SQL语句中,都可以将 PL/SQL变量用于表达式的任何位置i在其他语句(包括声明性语句)中对其引用前在其他语句(包括声明性语句)中对其引用前必须先进行声明必须先进行声明 16变量(续)变量(续) i是通过指定数据类型的名称来声明的 i可以被声明为任何 Oracle 内部数据类型i示例 oldfare NUMBER(5);m_name VARCHAR(15);cont BOOLEAN;17常量常量 i除了必须添加关键字除了必须添加关键字 CONSTANT 并赋值外,并赋值外,常量的声明方式与变量非常相似常量的声明方式与变量非常相似i示例 bonus_multiplier CONSTANT NUMBER(3,2) := 0.33;18使用属性声明使用属性声明 iPL/SQL 对象(如变量和常量)和数据库对象(如列和表)与某些属性关联 i这些属性可以用于简化变量和常量声明 19%TYPE 属性属性 i提供变量或列的数据类型提供变量或列的数据类型 i在对引用到数据库中的列的变量进行声明时有用 需要知道列的确切数据类型 如果列定义发生变化,则变量的数据类型在运行时也将随之更改 i示例示例 oldfare fare.first_fare%TYPE;newfare oldfare%TYPE;20%ROWTYPE属性属性 i当记录变量具有与表或视图中的行或从游标获当记录变量具有与表或视图中的行或从游标获取的行相同的结构时有用取的行相同的结构时有用 i记录中的字段具有与表/视图中的列相同的名称和数据类型 i示例示例 emp_rec employee%ROWTYPE;i可以使用下列属性引用特定字段 emp_rec.emp_num;21使用赋值操作符进行赋值使用赋值操作符进行赋值 i通过使用赋值操作符通过使用赋值操作符“:=”,将变量放在将变量放在“:=”左侧,左侧,而将包含数据量、变量、算术操作符或而将包含数据量、变量、算术操作符或 PL/SQL 函数调用的表达式放置在右侧来对变函数调用的表达式放置在右侧来对变量赋值量赋值i示例 emp_rec.dept_code := MKTG;num := 100;22使用使用 SELECT INTO 进行赋值进行赋值 i还可以按如下方法使用 SELECT INTO 对变量赋值 SELECT INTO FROM WHERE ;示例 SELECT first_fare INTO oldfareFROM fare WHERE route_code = SAN-LOU;23使用使用 SELECT INTO 进行赋值(续)进行赋值(续)iSELECT 语句执行后,将出现下列情况之一 只检索了一行 检索了多行 不检索任何行 i仅当它检索一行时,SELECT 才成功操作 i其他两种情况将导致错误并产生异常处理程序 24接受用户输入的值接受用户输入的值 i使用使用“&”操作符及赋值操作符可以接受用户输操作符及赋值操作符可以接受用户输入的值入的值 i示例 mbranch_code := &mcode;num := #i“mcode”是绑定变量,不应该声明,但是需要是绑定变量,不应该声明,但是需要声明声明 mbranch_code25条件控制条件控制 i选择结构测试某个条件,然后根据条件在两序选择结构测试某个条件,然后根据条件在两序列语句中选择一列执行列语句中选择一列执行 i有三种语句形式 IF-THENIF-THEN-ELSEIF-THEN-ELSIF26IF-THEN 结构结构 i仅当条件值为仅当条件值为 TRUE 时,才执行语句序列时,才执行语句序列 i如果条件判定为 FALSE 或 NULL,则不执行任何操作 i这两种情况下控制都将转到这两种情况下控制都将转到 IF-THEN structure 结构后的下一个语句结构后的下一个语句 IF THEN语句;END IF;27IF-THEN-ELSE 结构结构 i仅当条件值为仅当条件值为 FALSE 或或 NULL 时,才执行时,才执行 ELSE 子句中的语句序列子句中的语句序列 IF THEN语句;ELSE语句;END IF;28IF-THEN-ELSIF 结构结构 i此结构可以从几个互斥的、排它的选项中选择此结构可以从几个互斥的、排它的选项中选择操作行为操作行为 iIF 语句可以具有任意数目的 ELSIF 子句 i最终的最终的 ELSE 是可选项是可选项i将按自顶向下的顺序逐项检测条件 29IF-THEN-ELSIF 结构(续)结构(续) IF THEN语句;ELSIF THEN语句;ELSIF THEN语句;ELSE语句;END IF;30循环控制循环控制 i使用使用 LOOP 或或 GOTO 语句可以重复或跳过程语句可以重复或跳过程序块的选取部分序块的选取部分 i有三种形式的 LOOP 语句 LOOPWHILE-LOOPFOR-LOOP31LOOP 语句语句 iLOOP 将重复某些语句序列将重复某些语句序列 i被重复的语句位于关键词 LOOP 和 END LOOP 之间 i每执行一次循环迭代过程,就执行一次语句序每执行一次循环迭代过程,就执行一次语句序列,然后控制又回到循环的开始位置列,然后控制又回到循环的开始位置 LOOP语句;END LOOP;32EXIT 语句语句 i如果不需要或不可能让循环进一步处理,用于如果不需要或不可能让循环进一步处理,用于完成循环完成循环 i有两种形式的 EXIT 语句EXITEXIT-WHEN33EXIT 语句(续)语句(续) i强制循环无条件完成强制循环无条件完成 i必须放在循环内 LOOP语句;IF THENEXIT; -立即退出循环 END IF;END LOOP;-控制到此处恢复 34EXIT-WHEN 语句语句 i允许循环有条件完成允许循环有条件完成 i在遇到 EXIT 语句时对 WHEN 子句中的条件进行判断 i如果判定条件为如果判定条件为 TRUE,则循环完成则循环完成 语句;EXIT WHEN ;END LOOP;35WHILE-LOOP 语句语句 i将条件与将条件与 LOOP-END LOOP 中的语句序列相关中的语句序列相关联联 i在每次循环前判定条件 i如果条件值为如果条件值为 TRUE,就执行一次语句序列,就执行一次语句序列,然后控制又回到循环的开始位置然后控制又回到循环的开始位置 i如果条件判定为 FALSE 或 NULL,则绕过循环,并且控制转到下一个语句 36WHILE-LOOP 语句(续)语句(续) i循环执行的次数取决于条件且只有完成循环后循环执行的次数取决于条件且只有完成循环后才可知才可知 WHILE LOOP语句;END LOOP;37FOR-LOOP 语句语句 i循环在指定的整数范围内进行循环在指定的整数范围内进行 i对于一定范围内的每个整数,都执行一次该语句i此范围为循环架构的一部分,它位于此范围为循环架构的一部分,它位于 FOR 和和 LOOP 之间之间 i当首次进入循环时,范围只判定一次 i每执行一次循环,循环计数器就会增加38FOR-LOOP 语句(续)语句(续) i不能为循环计数器赋值不能为循环计数器赋值 i在运行时可以动态分配循环范围 FOR IN 逆转 lower_bound . higher_bound LOOP语句;END LOOP;39GOTO 语句语句 i无条件分支到一个标签无条件分支到一个标签 i执行时,语句将更改 PL/SQL 程序块的控制流i编制编制 GOTO 语句代码需要有两个部分语句代码需要有两个部分定义标签名称 使用 GOTO 语句将控制转到标签40GOTO 语句(续)语句(续) i标签名称标签名称 可以选择将其用于命名 PL/SQL程序块或程序块中的语句使用尖括号进行定义使用尖括号进行定义 ()IF 条件 THEN语句;END IF;语句;GOTO if_fare_label;41GOTO 语句(续)语句(续) i在下列位置可以使用在下列位置可以使用 GOTO 语句来转移控制语句来转移控制 从程序块到可执行语句 从异常处理程序分支到封闭的程序块 42GOTO 语句(续)语句(续) i不允许不允许在下列位置使用 GOTO 语句来转移控制从某个从某个 IF 语句或循环子句内转到其他语句语句或循环子句内转到其他语句从封闭程序块转到某个子程序块从异常处理程序转到当前程序块从异常处理程序转到当前程序块子程序之外转到关键字转到关键字43NULL 语句语句 i明确指定不进行操作(例如,除了将控制转移到下一个明确指定不进行操作(例如,除了将控制转移到下一个语句而不进行任何操作)语句而不进行任何操作) i它提高了可读性 IF newfare 90 THEN语句;ELSENULL;END IF;44注释的使用注释的使用 i添加注释可以提高程序的可读性并帮助理解添加注释可以提高程序的可读性并帮助理解iPL/SQL 支持两种注释样式单行注释单行注释i可以在行中的任何地方以双分号 (-) 开始i可以扩展到行尾多行注释多行注释i这些注释以 /*开始并以*/结束 i可以跨越多行 45异常简介异常简介 i错误条件称为异常错误条件称为异常i错误发生时,产生异常,这些异常包括常规执行停止并且控制转移到了 PL/SQL 程序块或子程序的异常处理部分 i要处理产生的异常,需要编写单独的称作异常要处理产生的异常,需要编写单独的称作异常处理程序的例程处理程序的例程 46异常介绍(续)异常介绍(续) i有两类异常预定义异常(内部异常)预定义异常(内部异常) 用户定义的异常用户定义的异常 47异常的范围规则异常的范围规则 i不能在同一程序块两次声明异常,但可以在两不能在同一程序块两次声明异常,但可以在两个不同的程序块声明同一个异常个不同的程序块声明同一个异常i在程序块中声明的异常对于程序块是局部的,而对于所有子程序块则是全局的i封闭的程序块不能引用在子程序块中声明的异常,因为程序块只能引用局部或全局异常48预定义异常预定义异常 i在在 PL/SQL 程序块验证一个程序块验证一个 Oracle 规则或超过了系统依规则或超过了系统依赖限制时隐式地发生赖限制时隐式地发生 i每个 Oracle 错误都有一个编号,但必须通过名称来处理异常 iPL/SQL 预定义了某些通用的预定义了某些通用的 Oracle 错误作为异常错误作为异常 iPL/SQL 在全局范围全局范围内声明这些预定义异常 49预定义异常(续)预定义异常(续) i某些预定义的异常 CURSOR_ALREADY_OPENNO_DATA_FOUNDTOO_MANY_ROWSVALUE_ERRORZERO_DIVIDEi可以使用“OTHERS”异常来处理所有未在程序块中定义的其他错误50预定义异常(续)预定义异常(续) i示例 异常WHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE(Route code not found);WHEN OTHERS THEN语句;END;i可选的可选的 OTHERS 异常处理程序总是程序块中的异常处理程序总是程序块中的最后一个处理程序最后一个处理程序 51预定义异常(续)预定义异常(续) i一个程序块仅可以有一个一个程序块仅可以有一个 OTHERS 处理程序处理程序 i使用 OTHERS 处理程序将确保可以处理所有异常i每次在程序块异常处理部分中仅可以激活一个异常每次在程序块异常处理部分中仅可以激活一个异常 i如果嵌套程序块没有异常处理程序,则执行下一个外部程序块的异常处理程序52预定义异常(续)预定义异常(续) i可以在一个异常处理程序中通过关键字 OR 将异常分隔开来处理多个异常Exception WHEN NO_DATA_FOUND OR TOO_MANY_ROWS THEN语句; WHEN OTHERS THEN语句;END;53用户定义的异常用户定义的异常i需要在需要在 PL/SQL 程序块、子程序或数据库触发程序块、子程序或数据库触发器的声明部分对用户定义的异常进行定义器的声明部分对用户定义的异常进行定义 i可以通过将异常命名并定义为数据类型 EXCEPTION 进行声明 i示例 DECLAREpast_due EXCEPTION;zero_error EXCEPTION;54用户定义异常(续)用户定义异常(续) i与变量相同,用户定义的异常必须具有名称与变量相同,用户定义的异常必须具有名称 i与变量不同,不能为用户定义的异常赋值,并且不能将其用于 SQL 语句 i需要使用需要使用 RAISE 语句明确产生语句明确产生 55用户定义异常(续)用户定义异常(续) i仅当出现的错误无法完成处理时,程序块才仅当出现的错误无法完成处理时,程序块才 RAISE 一个异常一个异常i可以在表达式范围内的任意位置对给定表达式的 RAISE 语句进行编码IF mrec.ss_fare = 0 THENRAISE zero_error;END IF;56用户定义异常(续)用户定义异常(续) i处理程序中发生的异常被立即传送到封闭的程处理程序中发生的异常被立即传送到封闭的程序块,将对其进行搜索为新产生的异常查找一序块,将对其进行搜索为新产生的异常查找一个处理程序个处理程序 i从这里开始,将按常规方式发送异常 i要重新产生一个异常,应在局部处理程序中放要重新产生一个异常,应在局部处理程序中放入一个入一个 RAISE 语句语句57异常处理程序异常处理程序 i用于捕获已产生的异常用于捕获已产生的异常 i由 WHEN 子句构成 ,指定一个异常,后跟一个当异常产生时要执行的语句序列i当异常在游标的当异常在游标的 FOR 循环中产生时,游标将被循环中产生时,游标将被隐式地关闭隐式地关闭i控制不返回到开始执行的地方不返回到开始执行的地方58错误函数错误函数 i可以在异常处理程序中使用两个错误函数SQLCODEi用于查找发生了什么错误 SQLERRMi用于获得错误消息i不能在 SQL 语句中直接使用i必须将这些值赋给必须将这些值赋给 SQL 语句中的局部变量语句中的局部变量 59错误函数(续)错误函数(续) iSQLCODE对于预定义的异常对于预定义的异常i错误返回一个负数并将控制传回给处理程序 i为“未找到数据”错误返回 +100对于用户定义的异常对于用户定义的异常 i返回 +160错误函数(续)错误函数(续) iSQLERRM对于预定义的异常对于预定义的异常 i返回与发生的错误相关的消息 i消息以错误代码开始 对于用户定义的异常对于用户定义的异常 i返回 “User-Defined Message”消息 还将接受一个错误号,并返回与该错误号相关的消息还将接受一个错误号,并返回与该错误号相关的消息 61错误函数(续)错误函数(续) DECLAREmsqlcode NUMBER;msqlmsg CHAR(255);BEGIN语句;EXCEPTIONWHEN OTHERS THENmsqlcode := SQLCODE;msqlmsg := SQLERRM;DBMS_OUTPUT.PUT_LINE(Error occurred- | TO_CHAR(msqlcode) | msqlmsg);END;62应用于应用于Web的面向对象关系型数据库管理系统:的面向对象关系型数据库管理系统:Oracle游标和复合数据类型 63本章目标本章目标i游标简介i游标类型隐式游标显式游标i游标功能 i定义游标i操纵游标 i游标属性 64本章目标(续)本章目标(续)i游标 FOR 循环i参数化游标iUPDATE OF 和 CURRENT OF 的游标 iPL/SQL 表 iPL/SQL 记录65游标简介游标简介 i要处理要处理 SQL 语句,语句, PL/SQL 打开一个称作环境打开一个称作环境区域的工作区区域的工作区 iPL/SQL 使用该区域执行 SQL 语句和存储处理信息 i称作称作“游标游标”的的 PL/SQL 结构允许您命名环境区结构允许您命名环境区域,访问其信息及在某些情况下控制其处理过域,访问其信息及在某些情况下控制其处理过程程66游标简介(续)游标简介(续) i查询返回多行时,可以将游标显式地定义为查询返回多行时,可以将游标显式地定义为 在查询所返回的首行之外的处理 对当前正在处理的行进行跟踪 i由多行查询返回的行集称作活动集 67游标类型游标类型iPL/SQL 使用两类游标 隐式游标隐式游标i由 Oracle 自动定义并打开,用于处理每个 SQL语句i最近打开的环境区域被称为“SQL%”游标 显式游标显式游标i如果查询返回多行,则可定义显式游标来对当前正在处理的行进行跟踪68游标功能游标功能i游标名是一个未声明的标识符,仅用于引用查询游标名是一个未声明的标识符,仅用于引用查询 i不能对游标赋值,也不能在表达式中使用游标名i显式游标可以有参数显式游标可以有参数i游标参数可以出现在查询中常量出现的任何位置上 i可以将游标参数初始化为默认值可以将游标参数初始化为默认值 69游标的功能(续)游标的功能(续) i可以将实参的不同值传递到游标,按需要采用或替换默可以将实参的不同值传递到游标,按需要采用或替换默认值认值i游标参数的范围对于游标来讲是局部变量 i当游标为当游标为 OPENED 时,游标参数的值可以用于相关的时,游标参数的值可以用于相关的查询查询 70定义游标定义游标i可以通过在可以通过在 PL/SQL 程序块的声明部分命名游程序块的声明部分命名游标或将它与某个查询关联来定义一个游标标或将它与某个查询关联来定义一个游标CURSOR IS;i示例CURSOR emp_cur ISSELECT empno, ename, job, salFROM emp;71操纵游标操纵游标i可以使用下列语句操纵游标可以使用下列语句操纵游标OPENFETCHCLOSEi在使用 OPEN、 CLOSE 或 FETCH 语句引用这些语句之前必须对游标进行声明 72OPEN 语句语句 i初始化或打开游标初始化或打开游标 i在查询返回任何行之前必须打开游标 i打开游标将执行查询并识别活动集合打开游标将执行查询并识别活动集合 OPEN i示例OPEN emp_cur;73FETCH 语句语句 i一次只能在一个活动集合中检索行一次只能在一个活动集合中检索行 i可以重复执行,直到检索到了所有行 FETCH INTO var1, , varN;ORFETCH INTO record_variable;i示例FETCH emp_cur INTO mrec;74CLOSE 语句语句 i关闭游标并让活动集合成为未定义内容关闭游标并让活动集合成为未定义内容 CLOSE ;i示例CLOSE emp_cur;i只要游标关闭,可以通过使用只要游标关闭,可以通过使用 OPEN 语句重新语句重新打开它打开它 75显式游标的属性显式游标的属性i每个游标有四个属性可以用于访问游标的环境每个游标有四个属性可以用于访问游标的环境区域区域%NOTFOUND%FOUND%ROWCOUNT%ISOPENi要使用这些属性,只要简单地将它们添加到游标名后即可76显式游标的属性(续)显式游标的属性(续) i%NOTFOUND如果因为没有多行而使最后的 FETCH 失败,则判定为 TRUE如果最后的 FETCH 返回一行,则判定为 FALSEi%FOUND如果最后的 FETCH 返回一行,则判定为 TRUE如果因为没有多行而使最后的 FETCH 失败,则判定为 FALSE 77显式游标的属性(续)显式游标的属性(续) i%ROWCOUNT返回当前从活动集合获取的行数i%ISOPEN如果打开显示游标,则判定为 TRUE如果关闭显示游标,则判定为 FALSE78显式游标的属性(续)显式游标的属性(续) i示例IF emp_cur%ISOPEN THENFETCH emp_cur INTO m_rec;IF emp_cur%FOUND THENmsr_no := emp_cur%ROWCOUNT;END IF;ELSEOPEN emp_cur;END IF;79游标游标 FOR 循环循环 i将它的循环索引声明为将它的循环索引声明为 %ROWTYPE 的记录的记录i隐式地打开游标i从活动集反复获取行的值并传送到记录中的字段从活动集反复获取行的值并传送到记录中的字段i在处理完所有行,并且循环退出时,隐式地关闭游标80游标游标 FOR 循环(续)循环(续) i为满足与游标名相关的查询的每一行执行循环为满足与游标名相关的查询的每一行执行循环结构中的语句结构中的语句i游标 FOR 循环用于简化代码编写 81游标游标 FOR 循环(续)循环(续)DECLARECURSOR emp_cur ISSELECT empno, ename, job, sal FROM emp;BEGINFOR mrec IN emp_curLOOPINSERT INTO tempVALUES( mrec.empno,mrec.ename,mrec.job, mrec.sal);END LOOP;END;82参数化的游标参数化的游标i游标也可接收参数游标也可接收参数i这些参数仅可用于游标的 SELECT 语句的输入i游标参数可以在查询中常量出现的任何位置上游标参数可以在查询中常量出现的任何位置上出现出现i可以在 OPEN 语句或游标 FOR 循环中提供参数值83参数化的游标(续)参数化的游标(续) DECLARECURSOR emp_cur ISSELECT empno, ename, job, sal FROM empWHERE job = pjob;mjob emp.job%TYPEBEGINmjob := &job;FOR mrec IN emp_cur(mjob) LOOPstatements;END LOOP;END;84游标游标 FOR UPDATE OF 和和 CURRENT OFiCURRENT OF 子句用于在子句用于在 UPDATE 或或 DELETE 语句中以引用游标当前行语句中以引用游标当前行i必须使用 FOR UPDATE OF 子句声明游标,并在一行上打开并定位i如果游标没有打开,则如果游标没有打开,则 CURRENT OF 子句将子句将产生错误产生错误85游标游标 FOR UPDATE OF 和和 CURRENT OF (续)(续) i如果游标已经打开,但没有处理 FETCH 或最后一个 FETCH 没有返回任何行 ,则将产生预定义例外 NO_DATA_FOUND86游标游标 FOR UPDATE OF 和和 CURRENT OF (续)(续) DECLARECURSOR emp_cur ISSELECT empno, ename, job, sal FROM empWHERE job = pjob FOR UPDATE OF sal;BEGINFOR mrec IN emp_cur LOOPUPDATE emp SET sal = sal * 0.15WHERE CURRENT OF emp_cur;END LOOP;END;87隐式游标的属性隐式游标的属性i虽然 OPEN、 CLOSE 和 FETCH 语句不能用于操作 SQL% 游标,但属性可以用于访问游标的环境区域i在游标自动打开之前,属性判定为 NULL88隐式游标的属性(续)隐式游标的属性(续) i下列四个游标属性可以用于访问 SQL% 游标的环境区域SQL%NOTFOUNDSQL%FOUNDSQL%ROWCOUNTSQL%ISOPEN89隐式游标的属性(续)隐式游标的属性(续) iSQL%NOTFOUND如果 INSERT 、 UPDATE 或 DELETE 语句没有影响行,则判定为 TRUE ,否则判定为 FALSEiSQL%FOUND逻辑上与 SQL%NOTFOUND 相反 如果 INSERT 、 UPDATE 或 DELETE 影响了一行或多行,则判定为 TRUE ,否则判定为 FALSE90隐式游标的属性(续)隐式游标的属性(续) iSQL%ROWCOUNT返回 INSERT 、 UPDATE 或 DELETE 语句影响的行数iSQL%ISOPENOracle 执行完与其关联的 SQL语句后,将自动关闭隐式游标 对于隐式游标,总是将 SQL%ISOPEN 判定为 FALSE91隐式游标的属性(续)隐式游标的属性(续) i示例DELETE FROM emp WHERE empno = 7864;IF SQL%NOTFOUND THEN.END IF;92PL/SQL 表表 iTABLE 类型的对象称为 PL/SQL 表i可以将其可视化为单维的、具有无限多个元素的垂直数组i表大小不受限制,即添加新行时它的大小将增加iPL./SQL 表使用主键,对行进行类似于数组那样的访问93PL/SQL 表(续)表(续) iPL/SQL 表的声明分为两个步骤 定义一个 TABLE 类型 TYPE IS TABLE OF列类型 | 变量数据类型 NOT NULLINDEX BY BINARY_INTEGER;声明该类型的 PL/SQL 表 ;94PL/SQL 表(续)表(续) i示例TYPE name_tab_typ IS TABLE OF CHAR(15)INDEX BY BINARY_INTEGER;name_table name_tab_typ;95PL/SQL 表(续)表(续) i可以通过使用具有类似于数组语法的主键值来引用行 (I)其中 I 是索引下标 i示例name_table(3)96PL/SQL 表(续)表(续) i还可以将 PL/SQL 表达式的值赋予给特定行 (I) := plsql_expression;i示例name_table(5) := MICKY;97PL/SQL 记录记录 i类型为 RECORD 的对象称为 PL/SQL 记录iPL/SQL 记录具有唯一命名的字段,这些字段可以属于不同的数据类型 98PL/SQL 记录(续)记录(续) i通过两个步骤对 PL/SQL 记录进行了声明 定义一个 RECORD 类型 TYPE IS RECORD(fieldname1 NOT NULL : fieldnameN NOT NULL);(%TYPE 和 %ROWTYPE 可用于指定 声明该类型的 PL/SQL记录 ;99PL/SQL 记录(续)记录(续) i只有对字段进行了初始化后才可以添加 NOT NULL 约束i示例TYPE route_rec_type IS RECORD(route_code VARCHAR2(7) NOT NULL := SAN-LOU,first_fare fare.first_fare%TYPE,eco_fare fare.eco_fare%TYPE);route_rec route_rec_type;100PL/SQL 记录(续)记录(续) i可以在声明中初始化记录 i示例 TYPE timetype IS RECORD(tsecond SMALLINT :=0, tminute SMALLINT := 0, thour SMALLINT := 0);i声明了 timetype 类型的记录后,字段初始值为零 101PL/SQL 记录(续)记录(续) i可以使用点号引用记录中的字段 .i示例route_rec.eco_fare102PL/SQL 记录(续)记录(续) i可以一次对所有字段赋值 通过将一个记录赋值给另一个具有相同类型的记录 route_rec1 := route_rec2;使用 SELECT INTO 或 FETCH INTO 语句 SELECT route_code, first_fare, eco_fare INTO route_rec1 FROM fareWHERE route_code = SAN-LOU;(列名称必须按照与记录中字段相同的顺序出现)103PL/SQL 记录(续)记录(续) i一个记录可以是另一个记录的组件iPL/SQL 允许声明并引用嵌套记录104PL/SQL 记录(续)记录(续)i示例TYPE timetype IS RECORD(tminute SMALLINT, thour SMALLINT);TYPE meetingtype IS RECORD(mday DATE, mtime timetype);meeting meetingtype;seminar meetingtype;105PL/SQL 记录(续)记录(续) i示例(续) TYPE partytype IS RECORD(pday DATE, ptime timetype);party partytype;106PL/SQL 记录(续)记录(续)iPL/SQL 允许嵌套记录赋值给另一个具有相同数据类型的记录 seminar.time := meeting.time;i如果所包括的记录属于不同的数据类型,也允许一个嵌套记录赋值给另一个记录 party.time := meeting.time;107应用于应用于Web的面向对象关系型数据库管理系统:的面向对象关系型数据库管理系统:OracleREF 游标、过程和函数 108本章目标本章目标i游标类型和变量 i子程序简介 i子程序的优点 i存储程序i函数iRETURN 语句 i过程和函数的参数模式 i查看存储子程序的错误 i存储子程序的优点 109游标类型和变量游标类型和变量iPL/SQL 程序不能将游标作为参数传递到另一程序不能将游标作为参数传递到另一个程序个程序iPL/SQL 程序仅能打开游标并处理程序自身内的相应信息i要解决功能限制,用程序可以声明两个不同的要解决功能限制,用程序可以声明两个不同的游标类型及相应的游标变量游标类型及相应的游标变量 110游标类型和变量(续)游标类型和变量(续)i根据游标的不同声明方式,游标可以是 强型强型弱型111游标类型和变量(续)游标类型和变量(续)i强型游标 游标类型的声明包括为游标类型指定了形态或属性的游标类型的声明包括为游标类型指定了形态或属性的 RETURN 子句子句 强型游标类型限制随后使用该类型的游标变量的定义示例TYPE emp_cur IS REF CURSOR RETURN emp.empno%TYPE;emp_cursor1 cur_emp;112游标类型和变量(续)游标类型和变量(续)i弱型游标 程序可以使用弱型游标类型声明任何形态的游标变量程序可以使用弱型游标类型声明任何形态的游标变量 因为没有返回值,所以游标变量的形态是独立的 这增加了游标变量的灵活性,有利于进一步的更改这增加了游标变量的灵活性,有利于进一步的更改 示例TYPE emp_cur IS REF CURSOR;113子程序子程序i子程序退出时,声明部分的对象是本地的并且子程序退出时,声明部分的对象是本地的并且终止其存在终止其存在 i可以使用支持 PL/SQL 的任何 Oracle 工具进行定义 i它们可以在它们可以在 PL/SQL 程序块、过程、函数和数程序块、过程、函数和数据包中声明据包中声明114子程序的优点子程序的优点i具有可扩展性具有可扩展性 可以自定义 PL/SQL 语言以满足应用程序的需要 i提高可复用性和可维护性提高可复用性和可维护性子程序只要有效,就完全可以用于任何数目的应用程序中简化了维护/优化过程,因为如果定义更改只有子程序受到影响115子程序的优点(续)子程序的优点(续)i具有模块化特性具有模块化特性可以将程序拆分为可管理的、明确定义的逻辑块支持自顶向下的设计和逐步细化的解决问题的方法i抽象内容帮助抽象内容帮助允许与细节在精神上分离这种截取方式允许程序员在主程序的测试并调试完成后再进行过程/函数的定义116存储过程存储过程 i执行特定操作的子程序执行特定操作的子程序i存储于数据库中并可由任意匿名块调用i能够接受参数能够接受参数i在参数声明中的数据类型区分符应为无限制的117存储过程(续)存储过程(续) i具有两个部分具有两个部分 说明i以关键字 PROCEDURE 开始,以过程名或参数列表结束 主体i以关键字 IS 开始,以关键字 END 结束,后面可以跟可选过程名称 118存储过程(续)存储过程(续) CREATE OR REPLACE PROCEDURE (参数1, 参数N) IS局部声明BEGIN可执行语句;EXCEPTION 例外处理程序;END ;参数代表 变量名 IN|OUT|IN OUT 数据类型 := | DEFAULT 值 119存储过程(续)存储过程(续) i示例 CREATE PROCEDURE branch_sum(p_brnch branch.branch_code%TYPE) ISdeclare variables;BEGIN可执行语句; EXCEPTIONWHEN NO_DATA_FOUND THEN语句 ;END branch_sum;120存储过程(续)存储过程(续)i创建过程时, Oracle 自动执行下列步骤 编译过程存储所编译的代码在数据库中存储过程iPL/SQL 编译程序用于编译代码编译程序用于编译代码 i如果发生错误,也可创建过程,但是无效 121存储过程(续)存储过程(续) i可以使用可以使用 SHOW ERRORS 命令或下列命令查命令或下列命令查看编译错误看编译错误 SELECT * FROM USER_ERRORS;iOracle 将编译过程装入 SGA 中 i其他用户也可以执行存储在其他用户也可以执行存储在 SGA 中的相同过程中的相同过程122存储过程(续)存储过程(续) iOracle 分三个步骤执行过程分三个步骤执行过程验证用户访问i如果为非法用户,则拒绝访问验证过程有效性i如果为非法过程,则不执行执行过程i可以通过下列方式检查过程的有效性可以通过下列方式检查过程的有效性 SELECT OBJECT_NAME, OBJECT_TYPE, STATUSFROM USER_OBJECTSWHERE OBJECT_TYPE = PROCEDURE;123存储过程的优点存储过程的优点 i增强了数据安全性增强了数据安全性 可以授权用户访问能执行表的存储过程,但不授权他们访问表自身i提高了数据库性能提高了数据库性能 通过网络发送的信息有所减少 编译不需要执行代码 过程存在于共享池中,所以不需要进行磁盘检索 124存储过程的优点(续)存储过程的优点(续) i节省内存节省内存 只需要在内存中装入过程的一个拷贝便可供多个用户执行 i提高了开发的工作效率提高了开发的工作效率 通过编写单一的过程可以避免冗余程序代码,并且提高了生产效率 i完整性完整性 只需要测试一次,以保证它能够返回正确的结果 125调用存储过程调用存储过程 i可以作为可以作为 PL/SQL 语句调用过程语句调用过程 示例branch_sum(NYK);i可以从可以从 SQL*Plus 中调用单独的过程中调用单独的过程 示例SQL EXECUTE branch_sum(NYK);126维护存储过程维护存储过程 i可以使用可以使用 DROP 命令删除过程命令删除过程 DROP PROCEDURE ;i示例DROP PROCEDURE branch_sum;127函数函数i返回值的子程序返回值的子程序 i具有一个 RETURN 子句 i存储于数据库中并可由任意匿名程序块调用存储于数据库中并可由任意匿名程序块调用 i通常可以接受参数 i在参数声明中的数据类型区分符应为无限制的在参数声明中的数据类型区分符应为无限制的128函数(续)函数(续)i具有两个部分具有两个部分 说明说明i以关键字 FUNCTION 开始,以 RETURN 子句结束 主体主体i以关键字 IS 开始,以关键字 END 结束,后面可以跟可选函数名称129函数(续)函数(续)CREATE OR REPLACE FUNCTION (参数1, 参数N) RETURN datatype IS局部声明BEGIN可执行语句 ;EXCEPTION例外处理程序END ;参数代表的是变量名 IN|OUT|IN OUT 数据类型 := | DEFAULT 值 130函数(续)函数(续) i示例 CREATE FUNCTION day_fn(mday NUMBER) RETURN CHAR ISdisp_day CHAR(15);BEGIN可执行语句 ;RETURN disp_day;EXCEPTION 语句 ;END day_fn;131调用函数调用函数 i作为 PL/SQL 语句调用函数 示例chardays := day_fn(3);i作为表达式的一部分调用函数 示例IF day_fn(3) = TUESDAY THEN语句 ;END IF;132维护函数维护函数 i可以使用 DROP 命令删除函数 DROP FUNCTION ;i示例DROP FUNCTION day_fn;133RETURN 语句语句 i立即完成子程序的执行,并将控制返回给调用者 i内置过程 不可以包含表达式 在实现过程的正常结束之前将控制返回给调用者 i内置函数 必须包含表达式,并在执行时判定 134过程和函数的参数模式过程和函数的参数模式 i用于定义正式参数的行为 i可以与其他子程序一起使用 i三个参数模式 IN (默认)OUTIN OUTi避免在函数中使用 OUT 和 IN OUT 模型135过程和函数的参数模式(续)过程和函数的参数模式(续) iIN允许将值传送到被调用的子程序 在子程序内部,它的作用如同常数 实际对应参数可以是一个常数、数据量、初始化变量或表达式 可以被初始化为默认值136过程和函数的参数模式(续)过程和函数的参数模式(续) iOUT允许值返回到子程序的调用者 在子程序的内部,它的作用如同未初始化的变量 实际的对应参数应为一个变量;不能为一个常量或一个表达式 其值不能对另一个变量赋值,也不能对其自身再次赋值 137过程和函数的参数模式(续)过程和函数的参数模式(续) iIN OUT允许传送初始值,并将更新的值返回给调用者 在子程序内部,它的作用如同未初始化的变量 实际的对应参数应为一个变量;不能为一个常量或一个表达式 它可以被赋值,它的值也可以对另一个变量赋值 138调试存储子程序调试存储子程序 i可以使用 DBMS_OUTPUT 提供的数据包调试存储子程序 i可以使用 PUT 和 PUT_LINE 语句将变量和表达式的值输出到显示器 i还可以使用 SHOW ERRORS 命令查看编译错误 SHOW ERRORS PROCEDURE | FUNCTION | PACKAGE ;139存储子程序的优点存储子程序的优点 i更高的工作效率 通过采用存储子程序的库设计应用程序,可以避免冗余编码,从而提高工作效率 i更佳的性能 通过使用子程序可以减少从到 Oracle的调用,因此提高了应用程序的性能140存储子程序的优点(续)存储子程序的优点(续) i节省内存 只需要将子程序的一个拷贝装入到内存中就可以供多个用户执行,这样应用程序就可以需要更少的内存 i应用程序完整性 通过采用存储子程序的库来开发所有应用程序,降低了编码错误的可能性 141存储子程序的优点(续)存储子程序的优点(续) i更加严密的安全性 存储子程序可以帮助加强数据安全 DBA 通过仅授权访问子程序来限制用户进行特定数据库操作 142应用于应用于Web的面向对象关系型数据库管理系统:的面向对象关系型数据库管理系统:Oracle使用数据包和数据库触发器 143本章目标本章目标i数据包 i数据包的优点 i数据包说明 i数据包主体 i使用游标变量 i数据库触发器简介 144本章目标(续)本章目标(续)i创建数据库触发器 iINSTEAD OF 触发器 i触发器的限制 i启用/禁用触发器 i放置触发器 i编译和调试触发器145数据包数据包 i将逻辑相关的将逻辑相关的 PL/SQL 类型、对象和子程序进类型、对象和子程序进行分组的数据库对象行分组的数据库对象 i不能对它们进行调用,也不能对其传送参数或嵌套 i这里有两个部分 说明主体146数据包的优点数据包的优点 i模块化特性模块化特性允许您将相关的类型、对象和子程序封装入一个命名的 PL/SQL 模块具有简单、清晰、定义明确的接口,便于理解具有简单、清晰、定义明确的接口,便于理解 可以协助应用程序开发147数据包的优点(续)数据包的优点(续) i更简捷的应用程序设计更简捷的应用程序设计 在设计应用程序时,只需要最初在数据包中提供接口信息 可以没有主体而对说明进行编码和编译可以没有主体而对说明进行编码和编译 也可以编译引用数据包的子程序 在就绪可以完成应用程序之前不必定义数据包主体在就绪可以完成应用程序之前不必定义数据包主体 148数据包的优点(续)数据包的优点(续) i信息隐藏信息隐藏 可以指定哪些类型、项目和子程序是公有的还是私有的 私私有有子子程程序序的的定定义义是是隐隐含含的的,这这样样如如果果定定义义更更改改只只会会影影响响数数据据包包(而不会影响应用程序)(而不会影响应用程序) 简化了维护和增强,并保护了数据包的完整性 149数据包的优点(续)数据包的优点(续) i增加了功能性增加了功能性数据包的公共变量和游标在会话期间持续存在 它们可以被环境中所执行的所有子程序共享它们可以被环境中所执行的所有子程序共享它们也允许您在事务间维护数据,不用将数据存储在数据库中150数据包的优点(续)数据包的优点(续) i更佳的性能更佳的性能 首次调用数据包的子程序时,整个数据包将装载进内存 以以后后对对数数据据包包中中相相关关子子程程序序的的调调用用就就不不用用进进行行磁磁盘盘输输入入/输输出出操操作了作了如果程序包的函数发生更改,Oracle 不用重新编译调用子程序,因为它们不依赖数据包主体 151数据包说明数据包说明 i是一个与应用程序的接口是一个与应用程序的接口 i声明可用的类型、变量、常数、例外、游标和子程序 i让公用声明对应用程序可见让公用声明对应用程序可见 i可以被认为是可操作的接口 152数据包说明(续)数据包说明(续) i声明的范围对于数据库构架而言是局部的,对声明的范围对于数据库构架而言是局部的,对数据包而言是全局的数据包而言是全局的 i列出可以用于应用程序的数据包资源 153数据包说明(续)数据包说明(续) i是使用是使用 CREATE PACKAGE 命令创建的命令创建的 CREATE OR REPLACE PACKAGE AS- 公共类型和对象声明 - 子程序说明 END ;154数据包说明(续)数据包说明(续) i示例 CREATE PACKAGE airlines ASTYPE flight_day_type is RECORD(flightno flight_sch.flightno%TYPE, flight_day1 NUMBER(1);CURSOR flight_cur RETURN flight_day_type;disp_day CHAR(15);FUNCTION day_fn(mday NUMBER) RETURN CHAR;PROCEDURE branch_sum (p_brnch branch.branch_code%TYPE);END airlines;155数据包主体数据包主体 i实现数据包说明 i完全定义游标和子程序 i将实现细节和私有声明从应用程序隐含 i可以将其设想为“黑箱” i可被替换增强或在不更改接口的情况下被替换 i可以在不重新编译调用程序的情况下对其进行更改 156数据包主体(续)数据包主体(续) i声明范围对于数据包主体是局部的 i除了在数据包主体内将不能访问到声明的类型和对象 i只在首次引用数据包时,运行一次数据包的初始化部分 157数据包主体(续)数据包主体(续) i使用 CREATE PACKAGE BODY 命令生成 CREATE OR REPLACE PACKAGE BODY AS - 私有类型和对象声明 - 子程序主体 BEGIN- 初始化语句 END ;158数据包主体(续)数据包主体(续) CREATE PACKAGE BODY airlines ASCURSOR flight_cur RETURN flight_day_type ISSELECT flightno, reoute_code, flight_day1, flight_day2FROM flight_sch;FUNCTION day_fn(mday NUMBER) RETURN CHAR ISBEGIN语句 ;END day_fn;. .END airlines;159引用数据包对象引用数据包对象 i必须使用点符号引用数据包对象和子程序必须使用点符号引用数据包对象和子程序 数据包名.类型名 数据包名.对象名数据包名.子程序名i示例airlines.day_fn(4);160维护数据包维护数据包i可以使用可以使用 DROP 命令删除数据包命令删除数据包 DROP PACKAGE i示例DROP PACKAGE airlines;i要删除一个结构,应将其从数据包中删除,然要删除一个结构,应将其从数据包中删除,然后重新编译数据包后重新编译数据包161使用游标变量使用游标变量 i与游标类似,游标变量指向多行查询结果集的当前行与游标类似,游标变量指向多行查询结果集的当前行 i与游标不同,可以为任意类型兼容的查询打开游标变量 i可以为游标变量赋新值,可以将它传送给子程序可以为游标变量赋新值,可以将它传送给子程序 i它为集中数据检索提供了灵活和方便的方式 162使用游标变量(续)使用游标变量(续) i通常通过将它传送到存储的过程来打开,该过程声明一个通常通过将它传送到存储的过程来打开,该过程声明一个游标变量作为它的正式变量之一游标变量作为它的正式变量之一 i当将其作为打开它的子程序的一个正式参数进行声明时,必须指定 IN OUT 模式,从而子程序可以将打开的游标传送回调用者 i使用相同的或不同的使用相同的或不同的 REFCURSOR 绑定变量可以让过程绑定变量可以让过程执行多次执行多次 163使用游标变量(续)使用游标变量(续) CREATE PACKAGE dept_data ASTYPE dcur_typ IS REF CURSOR RETURN dept%ROWTYPE;PROCEDURE dept_cv(d_cv IN OUT dcur_typ);END dept_data;CREATE PACKAGE BODY dept_data ASPROCEDURE dept_cv(d_cv IN OUT dcur_typ) ISBEGINOPEN d_cv FOR SELECT * FROM dept;END dept_cv;END dept_data;164使用游标变量(续)使用游标变量(续) i要在要在 SQL 提示符处查看游标变量的值提示符处查看游标变量的值 声明一个类型为 REFCURSOR 的变量 SQL VARIABLE v_dept REFCURSOR执行指定的过程SQL EXECUTE dept_data.dept_cv(:v_dept);打印绑定变量以查看结果SQL PRINT v_dept165使用游标变量(续)使用游标变量(续)i要集中检索数据,可以在存储过程中组合类型要集中检索数据,可以在存储过程中组合类型兼容的查询兼容的查询 CREATE PACKAGE emp_data ASTYPE ecur_typ IS REF CURSOR RETURN emp%ROWTYPE;PROCEDURE emp_cv(e_cv IN OUT ecur_typ, choice IN NUMBER);END emp_data;166使用游标变量(续)使用游标变量(续) CREATE PACKAGE BODY emp_data ASPROCEDURE emp_cv(e_cv IN OUT ecur_typ, choice IN NUMBER) ISBEGINIF choice = 1 THENOPEN e_cv FOR SELECT * FROM empWHERE sal 2500;ELSIF choice = 2 THENOPEN e_cv FOR SELECT * FROM empWHERE deptno = 20;END IF;END emp_cv;END emp_data;167使用游标变量(续)使用游标变量(续) i以上程序可这样被执行 SQL VARIABLE v_emp REFCURSORSQL SET AUTOPRINT ONSQL EXECUTE emp_data.emp_cv(:v_emp,1);(将显示工资超过 2,500 的 emp 表中的所有行) 168使用游标变量(续)使用游标变量(续) i为了更加灵活,您可以将游标变量和选择器传送到存储过程,它可以使用不同的返回类型执行查询 CREATE PACKAGE gen_cur ASTYPE generic_cur_typ IS REF CURSOR;PROCEDURE open_cv(gen_cv IN OUT generic_cur_typ, choice IN NUMBER);END gen_cur;169使用游标变量(续)使用游标变量(续) CREATE PACKAGE BODY gen_cur ASPROCEDURE open_cv(gen_cv IN OUT generic_cur_typ, choice IN NUMBER) ISBEGINIF choice = 1 THENOPEN gen_cv FOR SELECT * FROM emp;ELSIF choice = 2 THENOPEN gen_cv FOR SELECT * FROM dept;ELSIF choice = 3 THENOPEN gen_cv FOR SELECT * FROM salgrade;END IF;END open_cv;END gen_cur;170使用游标变量(续)使用游标变量(续) i以上程序可这样被执行以上程序可这样被执行 SQL VARIABLE cur REFCURSORSQL SET AUTOPRINT ONSQL EXECUTE gen_cur.open_cv(:cur,2);(将显示 dept 表中的所有行) 171数据库触发器简介数据库触发器简介i它是一个与某个特定数据库表关联的存储它是一个与某个特定数据库表关联的存储 PL/SQL 程序单元程序单元 i只要当 SQL 操作影响到表时, Oracle 就自动执行(触发)触发器 i将隐式地调用它们将隐式地调用它们 i触发器能帮助自定义数据库 i仅在需要时才使用它们仅在需要时才使用它们 172使用数据库触发器使用数据库触发器 i自动生成提交的列值自动生成提交的列值 i可以防止无效事务 i加强复杂的安全授权加强复杂的安全授权 i在分布式数据库节点间加强引用完整性 i加强复杂的商务规则加强复杂的商务规则 173使用数据库触发器(续)使用数据库触发器(续)i提供透明的事件日志提供透明的事件日志 i可以提供复杂的审计 i可以维护同步表复制可以维护同步表复制 i可以搜集表访问的统计 i可以自动获取列值可以自动获取列值 i可以将 DML 操作限制在规律的事务时间 174使用数据库触发器的场合使用数据库触发器的场合 i触发器主要用于促进引用的完整性触发器主要用于促进引用的完整性 i只能在无法使用下列表级别限制时使用它们 NOT NULLUNIQUE KEYPRIMARY KEYFOREIGN KEYCHECK175创建数据库触发器创建数据库触发器 CREATE OR REPLACE TRIGGER BEFORE|AFTERINSERT|DELETE|UPDATE OF ON FOR EACH ROWWHEN ()iON 子句中的名称识别与数据库触发器关联的数据库表 176创建数据库触发器(续)创建数据库触发器(续) i触发器事件指定了影响表的触发器事件指定了影响表的 SQL DML 语句语句 ( INSERT、 DELETE 或 UPDATE)iAFTER 指定了触发器在处理完成后触发 iBEFORE 指定了触发器在处理完成前触发 177创建数据库触发器(续)创建数据库触发器(续) i默认情况下,触发器每个表触发一次默认情况下,触发器每个表触发一次iFOR EACH ROW 选项指定触发器每行触发一次 i要使触发器触发,WHEN 子句中布尔型表达式的值必须判定为 TRUEi可以将 REPLACE 添加到 CREATE 语句以自动删除和重建触发器 178创建数据库触发器(续)创建数据库触发器(续) CREATE TRIGGER flight_updateAFTER INSERT ON reservationFOR EACH ROWBEGINIF :new.THEN语句 ;ELSIF :new.THEN语句 ;END IF;END;179创建数据库触发器(续)创建数据库触发器(续) i前缀 : new 为一个引用最近更新列值的相关名 i在数据库触发器内,可以引用用来更改行的 :new 和 :old 值 i单独触发器也处理多个操作 i使用条件谓词识别用于调用代码部分的语句的类型 180创建数据库触发器(续)创建数据库触发器(续) IF Inserting THEN语句 ;END IF;IF Updating THEN语句 ;END IF;IF Deleting THEN语句 ;END IF;181INSTEAD OF 触发器触发器 i用途:对那些由于基本表包括连接而不能直接用途:对那些由于基本表包括连接而不能直接通过通过 INSERT、 UPDATE 和和 DELETE 语句修语句修改的视图提供了明晰的修改方法改的视图提供了明晰的修改方法 i由于是 Oracle 触发了触发器而不是触发器语句来触发,所以称它为 INSTEAD OF 182INSTEAD OF 触发器(续)触发器(续) i触发器对用户是透明的,因为用户根据视图编触发器对用户是透明的,因为用户根据视图编写正常的写正常的 DML 语句,语句, INSTEAD OF 触发器负触发器负责更改责更改 i可以将它置于“对象视图”中以插入、更新或删除基本关系表中的数据 183INSTEAD OF 触发器(续)触发器(续) CREATE TRIGGER emp_insertINSTEAD OF INSERT ON emp_viewBEGIN语句 ;END;184触发器的限制触发器的限制 iSELECT 语句必须是语句必须是 SELECT INTO 语句或内语句或内部游标声明部游标声明 i不允许 DDL 声明和事务控制语句 i如如果果由由触触发发器器调调用用,则则存存储储子子程程序序不不能能包包括括事事务控制语句务控制语句 i:old 和 :new 值的类型不能是 LONG 和 LONG RAW185启用启用/禁用触发器禁用触发器 i可以启用也可以禁用触发器可以启用也可以禁用触发器 i在发出触发语句时,执行启用的触发器 i不执行禁用的触发器不执行禁用的触发器 i默认情况下,所有触发器在首次创建时都是启用的 186启用启用/禁用触发器(续)禁用触发器(续) i禁用特定触发器禁用特定触发器 ALTER TRIGGER DISABLE;i禁用特定表的所有触发器 ALTER TABLE DISABLE ALL TRIGGERS;i启用特定触发器启用特定触发器 ALTER TRIGGER ENABLE;i启用特定表的所有触发器 ALTER TABLE ENABLE ALL TRIGGERS;187删除触发器删除触发器 i可以使用可以使用 DROP 命令删除触发器命令删除触发器 DROP TRIGGER ;188编译和调试触发器编译和调试触发器 i触发器编译涉及三个阶段触发器编译涉及三个阶段 语法检查 语义检查语义检查 代码生成 i在发出 CREATE TRIGGER 命令时,将完整编译触发器 i如果在编译期间出错,仍然会创建触发器,但如果在编译期间出错,仍然会创建触发器,但是执行它的所有指令都将失败是执行它的所有指令都将失败 189编译和调试触发器(续)编译和调试触发器(续) i要手动重新编译触发器,可以使用要手动重新编译触发器,可以使用 ALTER TRIGGER 命令 ALTER TRIGGER COMPILE;iSHOW ERRORS 命令可以用于查看编译错误 SHOW ERRORS TRIGGER ;190应用于应用于Web的面向对象关系型数据库管理系统:的面向对象关系型数据库管理系统:Oracle使用方法和集合 191本章目标本章目标i方法简介 i对象类型方法 i方法类型 i使用 MAP 和 ORDER 方法对对象进行排序 i集合类型 VARRAY嵌套表 192方法简介方法简介 i方法是在对象类型说明中用关键字方法是在对象类型说明中用关键字 MEMBER 声明的子程序声明的子程序 i方法是作为对象类型定义组成部分的一个过程或函数 i方法不能与对象类型或其任何属性同名方法不能与对象类型或其任何属性同名 193方法简介(续)方法简介(续) i与数据包程序相似,大多数方法有两个部分与数据包程序相似,大多数方法有两个部分说明说明 i由方法名称组成 i可选参数列表 i对于函数是一个返回类型 主体主体i是执行特定操作的代码 194对象类型方法对象类型方法 i对象的方法定义对象的行为对象的方法定义对象的行为 i这些方法称为 Member 方法 iMember 方法首次在对象类型中定义,然后便方法首次在对象类型中定义,然后便创建了方法主体创建了方法主体 i方法是使用 CREATE 语句在对象类型中定义的 195对象类型方法(续)对象类型方法(续) CREATE OR REPLACE TYPE AS OBJECT(attribute1 datatype, : attributeN datatypeMEMBER PROCEDURE (parameter, mode, datatype),MEMBER FUNCTION (parameter, mode, datatype) RETURN datatype,PRAGMA RESTRICT_REFERENCES (,WNDS/RNDS/WNPS/RNPS);196对象类型方法(续)对象类型方法(续) iPRAGMA RESTRICT_REFERENCES 告知 Oracle 函数操作处于下列状态之一 WNDS (不能写入数据库状态)(不能写入数据库状态) i不能修改数据库 RNDS (不能读出数据库状态) i不能执行查询 WNPS (不能写入数据包状态)(不能写入数据包状态) i不能更改数据包变量的值 RNPS (不能读出数据包状态) i不能引用数据包变量的值 197对象类型方法(续)对象类型方法(续) i示例 CREATE TYPE flight_sch_type AS OBJECT(flightno CHAR(4),airbusno CHAR(5),route_code CHAR(7),flight_day1 NUMBER(1),flight_day2 NUMBER(1),MEMBER FUNCTION day_fn(flt_day1 IN NUMBER) RETURN CHAR,PRAGMA RESTRICT_REFERENCES(days_fn,WNDS);198对象类型方法(续)对象类型方法(续) i同样使用同样使用 CREATE 语句创建方法主体语句创建方法主体 CREATE OR REPLACE TYPE BODY ASMEMBER FUNCTION (parameter dataype) RETURN IS;MEMBER PROCEDURE (parameter datatype);END;199对象类型方法(续)对象类型方法(续) i示例 CREATE OR REPLACE TYPE BODY flight_sch_type ASMEMBER FUNCTION day_fn(flt_day1 NUMBER) RETURN CHAR ISdisp_day CHAR(15);BEGINIF flight_day1 = 1 THENdisp_day := Sunday;ELSIF flight_day1 = 2 THEN.END IF;RETURN disp_day;END;200调用对象方法调用对象方法 i基于类型创建表后,就可以在查询中调用对象方法基于类型创建表后,就可以在查询中调用对象方法 SELECT , .FROM ;i示例示例 SELECT flightno, route_code, f.day_fn(flight_day1) FLIGHTDAYFROM flight_sch_tab f;201调用对象方法调用对象方法 i可以在关系表中调用对象方法可以在关系表中调用对象方法 SELECT , .FROM ;i示例示例 SELECT f.flight_det.flightno, f.flight_det.route_code,f.flight_det.days_fn(f.flight_det.flight_day1) FLIGHTDAYFROM flight_sch_tabs f;202方法类型方法类型 i方法的三种类型 Constructor 方法 Accessor 取值方法 Mutator 赋值方法 203方法类型(续)方法类型(续) iConstructor 方法 每一种对象类型都有一个 constructor 方法,这种方法是系统定义的函数,与该对象类型同名 用于初始化并返回该对象类型的实例 正式的参数与对象类型的属性匹配 204方法类型(续)方法类型(续) iAccessor 方法 允许您访问对象类型的值允许您访问对象类型的值 作为 member 函数主要用于允许对对象类型中的特定属性值进行检索 在对象和程序的隐式执行过程中提供额外的防护在对象和程序的隐式执行过程中提供额外的防护 205方法类型(续)方法类型(续) iMutator 方法 允许为对象类型设置属性值而不必对其直接引用允许为对象类型设置属性值而不必对其直接引用 是用于设置特定属性值或属性集的 member 过程 在对象和程序的隐式执行过程中提供额外的防护在对象和程序的隐式执行过程中提供额外的防护 206使用使用 MAP 和和 ORDER 方法方法对数据进行排序对数据进行排序 i对象类型的实例没有预定义的次序对象类型的实例没有预定义的次序 i要将它们排序,必须使用 MAP 方法 iMAP 方法是一个无参数的函数,它具有标量返回类型方法是一个无参数的函数,它具有标量返回类型 DATE、NUMBER、VARCHAR2 或或 ANSI SQL 类型(例类型(例如如 CHARACTER 或或 REAL)iMAP 方法将对象值映射为标量值将对象值映射为标量值(标量值较易于比较),然后比较标量值 207使用使用 MAP 和和 ORDER 方法方法对数据进行排序(续)对数据进行排序(续) i另外,还可以使用另外,还可以使用 ORDER 方法方法 iORDER 方法可接受两个参数:内置参数 SELF 和具有相同类型的其他对象,并返回一个数字结果 iORDER方法只是将对象值进行比较方法只是将对象值进行比较 i可以声明 MAP 方法或 ORDER 方法,但不能对两者都声明 208使用使用 MAP 和和 ORDER 方法方法对数据进行排序(续)对数据进行排序(续) i在排序或合并大量对象时,可使用在排序或合并大量对象时,可使用 MAP 方法,因为一方法,因为一个调用将所有对象都映射为标量,然后对标量进行排序个调用将所有对象都映射为标量,然后对标量进行排序 iORDER 方法效率较低,因为必须对其反复调用(该方法每次只能比较两个对象) 209集合类型集合类型i集合与大多数集合与大多数 3GL 中使用的数组相似中使用的数组相似i包括相似类型其他对象的对象称为集合 i它是一组有序的相同类型的元素它是一组有序的相同类型的元素i集合中每个元素由决定其集合位置的唯一的下标来标识210集合类型(续)集合类型(续) i有两类集合有两类集合 嵌套表 可变大小数组 (VARRAY)i它们只能有一维它们只能有一维 i必须由整数作为索引 211VARRAYi还称为变化数组还称为变化数组 i它是存储在单个列的值集合 i数据库中单个列指向一组元素数据库中单个列指向一组元素 i可以将单个标识符与整个集合相关联 212VARRAY (续)(续) i可以作为一个整体引用整个集合或单独访问可以作为一个整体引用整个集合或单独访问元素元素 i要访问单独的元素,可使用标准的下标语法 array_name(subscript)i最大大小是在定义时指定的最大大小是在定义时指定的 i索引有固定的下界 1 和可扩展的上界213创建创建 VARRAY 的步骤的步骤 i创建一个类型,为单个行项目保留信息创建一个类型,为单个行项目保留信息 i创建一个数组类型称为 Varray 类型,保留特定类型的多个值 i根据数组类型创建具有其中一个列的表(称为根据数组类型创建具有其中一个列的表(称为数组列)数组列) 214创建创建 VARRAYi创建创建 VARRAY 的语法是的语法是 CREATE TYPE AS VARRAY(limit) OF ;i更新一个更新一个 VARRAY 的语法的语法 INSERT INTO VALUES(column_values, (attribute1_value,.),(attribute2_value,.);215更新更新 VARRAYi不能更新独立的元素不能更新独立的元素 i如果其中一个元素更改,则必须更新整个 VARRAYi语法语法 UPDATE SET = (attribute1_value,.),(attribute2_value,.)WHERE ;216在在 PL/SQL 记录中使用变化的数组记录中使用变化的数组 i具有一个或多个列并且具有有限数目的行具有一个或多个列并且具有有限数目的行 i可以在 PL/SQL 程序中声明 定义一个定义一个 RECORD 类型类型 定义一个 VARRAY 类型 TYPE ISVARRAY(no_of_elements) OF ;声明该类型的声明该类型的 VARRAY ;217在在 PL/SQL 记录中使用变化的数组(续)记录中使用变化的数组(续) i示例 TYPE part_record IS RECORD(part_id INTEGER, unit_price NUMBER(7,2),description VARCHAR2(50);TYPE part_varray IS VARRAY(3) OF part_record;current_parts part_varray;218嵌套表嵌套表 i作为另一个表的一部分存储的表作为另一个表的一部分存储的表 i主要用于在表之间映射“主-详”关系 i嵌套表的行不是按照任何特定顺序存储的嵌套表的行不是按照任何特定顺序存储的 i当检索 PL/SQL 变量时,为行提供了从 1 开始的连续下标219创建嵌套表的步骤创建嵌套表的步骤 i创建能够为独立行项目(它代表嵌套表详细信创建能够为独立行项目(它代表嵌套表详细信息)保留信息的类型息)保留信息的类型 i创建表类型为多行嵌套表保留详细信息(这将是嵌套详细信息 嵌套表类型) i创建一个主表,其中一列将保留嵌套表类型创建一个主表,其中一列将保留嵌套表类型 220创建嵌套表创建嵌套表 i语法 CREATE TYPE AS TABLE OF ;221在嵌套表中插入记录在嵌套表中插入记录 i语法 INSERT INTO VALUES(,.),nested_column(attribute1_value,);222显示嵌套表中的数据显示嵌套表中的数据 i语法 SELECT ,.FROM THE (SELECT FROM WHERE ) , WHERE ;223 “ THE” 运算符运算符 i识别识别 SQL 语句将在其中操作的嵌套表语句将在其中操作的嵌套表 i查询会返回外表(master 表)行 i规范了嵌套表的查询规范了嵌套表的查询 i允许您与嵌套表一起查询整个主表 224更新嵌套表更新嵌套表 i语法 UPDATE THE (SELECT FROM WHERE ) SET . = ,.,WHERE ;225从嵌套表中删除从嵌套表中删除 i语法 DELETE FROM THE (SELECT FROM WHERE ) WHERE ;226 VARRAY 与嵌套表之间的差别与嵌套表之间的差别VARRAY数组i定义时指定的最大大小定义时指定的最大大小 i数据是按行存储的 i存储在数据库中时保留排存储在数据库中时保留排序和下标序和下标 嵌套表 i无最大大小无最大大小 i没有在存储表中按行存储数据 i存储在数据库中时没有保存储在数据库中时没有保留顺序和下标留顺序和下标 227什么时候使用嵌套表而不用什么时候使用嵌套表而不用 VARRAYi数据元素的次序并不重要的情况下数据元素的次序并不重要的情况下 i当对嵌套表类型的属性要求索引时 i对数据元素的输入数量没有设置限制时对数据元素的输入数量没有设置限制时 i需要查询数据元素时 228PL/SQL 中的嵌套表和中的嵌套表和 VARRAYiPL/SQL 支持几种不同的集合方法,程序可以支持几种不同的集合方法,程序可以利用这些集合方法来操纵嵌套表和利用这些集合方法来操纵嵌套表和 varrayi若要使用集合方法,则以 PL/SQL 语句命名集合(嵌套表或 varray),使用点标记以集合方法作为后缀 229Collection 方法方法 iEXISTS(n)如果嵌套表 / varray 中存在 nth 个元素,则返回 TRUE 否则返回 FALSEiCOUNT返回目前在一嵌套表 / varray 中的元素数目 iLIMIT只用于 varray,返回 varray 可包含元素的最大数目230Collection 方法(续)方法(续) iDELETE删除嵌套表 / varray 中的部分或所有元素 iFIRST返回嵌套表 / varray 的第一个元素 iLAST返回嵌套表 / varray 的最后一个元素 iTRIM(n)从嵌套表 / varray 底部去掉 n 个元素 231Collection 方法(续)方法(续) iPRIOR(n)返回嵌套表或 varray 中 nth 元素的前一个元素 iNEXT(n)返回嵌套表或 varray 中 nth 元素的后一个元素 iEXTEND(m, n)将 m 个 nth 元素的副本追加到嵌套表或 varray232Collection 方法(续)方法(续) i示例 record_count := current_parts.COUNT;current_parts_rec := current_parts.FIRST;current_parts.DELETE(3);current_parts.DELETE(4, 6);current_parts.DELETE;233应用于应用于Web的面向对象关系型数据库管理系统:的面向对象关系型数据库管理系统:Oracle使用大型对象和对象表 234本章目标本章目标i大型对象(LOB)i操作大型对象 iDBMS_LOB 数据包 i用户定义的数据类型 i使用用户定义数据类型创建关系表 i定义对象表 235本章目标(续)本章目标(续)i操作对象 i查看数据 iREF 运算符 i定义对象之间的关系 iDEREF 和 VALUE 运算符236大型对象类型大型对象类型 iBFILE、BLOB、CLOB 和 NCLOBi它们允许您存储无结构数据组成的程序块,如文本、图形图像、视频剪辑和声波,其大小最大可达 4 GBi允许随机或按片访问数据 i基于 LOB 数据类型的列称为 LOB 列 237大型对象类型(续)大型对象类型(续) iLOB 由两个不同的组件构成 值 i是要存储的实际数据 定位器 i是指定数据库中对象位置的指示器 238大型对象类型(续)大型对象类型(续) iLOB 列存储对象的定位器 i可以存储 LOB在数据库内部(内部 LOB 或嵌入)数据库外(外部 LOB 或脱机),例如在操作系统文件中 iLOB 在单一列实例中最多可以存储 4GB 数据 239创建具有创建具有 LOB 列的表列的表 i与使用其他数据类型创建表相似 i示例 CREATE TABLE books(book_code CHAR(5), book_image BFILE, book_review CLOB);240更新更新 LOB 中的数据中的数据 i通常正被更新的表在后台被自动锁定 i执行事务时,释放锁定 i对于 LOB 值,必须显式地锁定行 i若要释放该锁,可触发 COMMIT 语句 i只有对内部存储的 LOB 才需要显式锁定 241更新更新 LOB 中的数据(续)中的数据(续) i使用 FOR UPDATE 子句完成显式锁定 i示例 SELECT book_review FROM booksWHERE book_code = B0189FOR UPDATE;UPDATE booksSET book_review = Absolutely ThrillingWHERE book_code = B0189;COMMIT;242显示显示 LOB 中的数据中的数据 i使用 SELECT 语句只能显示 CLOB 数据类型中的数据i示例 SELECT book_code, book_reviewFROM books;243DBMS_LOB 数据包数据包 i提供了用来访问和操纵 LOB 的例程 i所有例程都基于 LOB 定位器工作 i将一个 LOB 定位器选入局部 PL/SQL LOB 变量,并使用该参数作为 DBMS_LOB 例程访问 LOB 值的输入参数 244DBMS_LOB.READ 过程过程i在指定偏移处开始从 LOB 读取数据 DBMS_LOB.READ(loc, num, offset, buff)其中loc 是 LOB 定位器num 是将要读取的字节/字符数量offset 是以字节/字符表示的距 LOB 起始位置的偏移量buff 是读取操作的输出缓冲区245DBMS_LOB.SUBSTR 函数函数i从指定偏移处开始返回部分 LOB 值 DBMS_LOB.SUBSTR(loc, num, offset)其中loc 是 LOB 定位器 num 是将要读取的字节/字符数量offset 是以字节/字符表示的距 LOB 起始位置的偏移量246DBMS_LOB.INSTR 函数函数 i返回 LOB 中第 n 处发生的匹配模式的位置 DBMS_LOB.INSTR(loc, ptrn, offset, ocrs)其中loc 是 LOB 定位器ptrn 是测试模式offset 是一字节/字符为单位的模式匹配开始位置的偏移量ocrs 是发生号(从 1 开始)247DBMS_LOB.GETLENGTH 函数函数 i获得 LOB 值的长度 DBMS_LOB.GETLENGTH(loc)其中loc 是 LOB 定位器248DBMS_LOB.COMPARE 函数函数 i比较两个 LOB 值DBMS_LOB.COMPARE(loc1, loc2, num, offset1, offset2)其中loc 是要进行比较的第一个 LOB 的定位器 loc2 是要进行比较的第二个 LOB 的定位器num 是要比较的字节/字符数量offset1 是以字节/字符为单位的第一个 LOB 的偏移量offset2 是以字节/字符为单位的第二个 LOB 的偏移量249DBMS_LOB.WRITE 过程过程i将数据写入到 LOB 的指定偏移位置 DBMS_LOB.WRITE(loc, num, offset, buff)其中loc 是 LOB 定位器num 是要写入的字节/字符数量offset 是以字节/字符为单位的距 LOB 起始位置进行写操作的偏移量buff 是写操作的输入缓冲区250DBMS_LOB.APPEND 过程过程 i将源 LOB 的内容追加到目的 LOBDBMS_LOB.APPEND(loc1, loc2)其中 loc1 是目的 LOB 定位器loc2 是源 LOB 定位器251DBMS_LOB.ERASE 过程过程 i删除 LOB 的全部或部分内容DBMS_LOB.ERASE(loc, num, offset)其中loc 是 LOB 定位器num 是将要删除的字节/字符数量offset 是以字节/字符表示的距 LOB 起始位置的偏移量252DBMS_LOB.TRIM 过程过程 i将 LOB 值截短到指定的较小长度DBMS_LOB.TRIM(loc, newlen)其中loc 是 LOB 定位器newlen 是以字节/字符为单位的截断后的 LOB 值的长度253DBMS_LOB.COPY 过程过程i将源 LOB 的全部或部分内容复制到目标 LOBDBMS_LOB.COPY(loc1, loc2, num, offset1, offset2)其中loc1 是目的 LOB 的定位器loc2 是源 LOB 的定位器num 是将要复制的字节/字符数量offset1 是以字节/字符为单位的目的 LOB 中的偏移量offset2 是以字节/字符为单位的源 LOB 中的偏移量254DBMS_LOB BFILE 例程例程i特定 BFILE 数据类型的只读例程FILEEXISTS 函数i检查服务器上是否存在该文件FILEISOPEN 函数i检查文件是否打开FILEOPEN 过程i打开文件FILEGETNAME 过程i获得目录别名和文件名FILECLOSE 过程i关闭文件255DBMS_LOB BFILE 例程(续)例程(续) i示例DBMS_LOB.FILEEXISTS(loc)DBMS_LOB.FILEISOPEN(loc)DBMS_LOB.FILEOPEN(loc)DBMS_LOB.FILECLOSE(loc)其中loc 是 BFILE LOB 的定位器256DBMS_LOB BFILE 例程(续)例程(续) i示例DBMS_LOB.FILEGETNAME(loc, dir_alias, file_name)其中loc 是 BFILE LOB 的定位器dir_alias 是目录别名的输出变量file_name 是文件名的输出变量257用户定义的数据类型用户定义的数据类型i用户通过组合先前定义的数据类型可以创建自己的数据类型i也称为对象类型i对象类型由属性和成员组成258声明简单对象类型声明简单对象类型i它由内置数据类型构成i示例CREATE OR REPLACE TYPE address_typeAS OBJECT(add1 VARCHAR2(20), add2 VARCHAR2(20), add3 VARCHAR2(25);i使用 DESC 语句查看目的地259声明复合对象类型声明复合对象类型i使用其他类型创建的i可以使用一个简单的类型 i与创建简单类型相似i示例CREATE TYPE name_typeAS OBJECT(name VARCHAR2(20), address address_type);260使用用户定义的类型创建关系表使用用户定义的类型创建关系表 i表可以具有多个由用户定义类型构成的一个或多个列i使用 CREATE 语句i示例CREATE TABLE branch(branch_code CHAR(4), branch_addr address_type);261对象表对象表i基于单一类型i包含属性、类型数和 128 个字节的对象标识 (OID) i系统的每个行对象都将生成 OIDiOID 列是伪列,对象表说明中将不会显示此列262创建对象表创建对象表i使用 CREATE 语句i示例CREATE TABLE friendsOF name_type;263操作对象操作对象i使用 INSERT、UPDATE 或 DELETE 语句来操纵使用类型创建的对象i处理关系表和对象表时可对这些 SQL 语句进行少量修改 264操作对象(续)操作对象(续)iConstructor 方法隐式定义的方法函数创建类型实例constructor 名称与类型的名称是相同的例如必须在 INSERT 语句中创建类型时调用265在对象表中插入数据在对象表中插入数据i插入的方式与在一般关系表中插入相似i插入到使用对象类型来声明列的表中时,方式略有不同i示例INSERT INTO friends VALUES(JAMES, address_type(503 Napt appt, South Lane, Frankfurt);266查看数据查看数据i使用 SELECT 语句i示例SELECT * FROM branch;SELECT * FROM friends;267访问对象表中的数据访问对象表中的数据 i若要查看用户定义类型中的属性值,则需要使用点号i表必须有别名i可以使用带有点前缀的表别名来引用表的值i示例SELECT f.address.add3FROM friends f;268REF 运算符运算符i为每个行对象赋予一个 OID 值iREF 运算符使您可以引用对象表中现有行的 OID 值 iREF 运算符将表别名作为输入,并且为行对象返回 OID i示例SELECT REF(f)FROM friends f;269定义对象之间的关系定义对象之间的关系 i可以使用数据类型 REF 声明相似或不同对象之间的关系 i称为引用的 REF 允许您创建行对象指针i它将创建对被引用对象位置的引用i该指针用于查询、更新或删除对象270定义对象之间的关系(续)定义对象之间的关系(续) iREF 由目标对象的 OID、数据库标识符(列)和对象表构成iOID 用于创建使用 REF 和 DEREF 运算符的外键列的关系iSQL 和 PL/SQL 语句必须使用 REF 函数来处理对象引用 271将两个表将两个表/对象相关联的步骤对象相关联的步骤-方法方法 1 i创建一个其属性之一为另一个表的外来键的类型i创建一个基于此类型的对象表i创建具有外键列的关系表,此外键列将引用该类型,而且将范围或使用情况限制到基于该类型创建的表中因为很多对象表都可以根据同一类型创建,所以要求限定范围272将两个表将两个表/对象相关联的步骤对象相关联的步骤-方法方法 2i创建一个其属性之一为另一个表的外来键的类型i创建一个基于此类型的对象表i创建一个类型,该类型具有引用第一个类型的外键列i创建对象表并定义引用范围 273DEREF 运算符运算符i若要查看被引用值,请使用 DEREF 运算符i它使用了 REF 列的列名i语法SELECT DEREF(.)FROM ;iDEREF 运算符返回从关系表到对象表的引用值 274VALUE 运算符运算符i要查看相同的结构(如下所示使用 DEREF 运算符从对象表自身进行查看),使用 VALUE 运算符 i语法SELECT VALUE()FROM ;i调试引用时很有用,因为它允许直接从对象表查询格式化的值275 Thanks276
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号