ORACL深入浅出 主讲人:邹振兴 深入浅出Oracle 主讲:邹振兴.

Slides:



Advertisements
Similar presentations
第二章 简单的 SQL 语句. 本章要点  创建一个简单的表  SQL 语句介绍  最简单的查询语句 select  带有限制条件的查询  查询结果的排序显示.
Advertisements

Tool Command Language --11级ACM班 金天行.
第14章 預存程序 14-1 預存程序的基礎 14-2 建立與執行預存程序 14-3 預存程序的參數傳遞 14-4 預存程序的傳回值
Chap 13 視界與資料庫程式設計.
Oracle数据库 Oracle 子程序.
PL/SQL程序设计 过程, 函数 Trigger 对象关系数据库技术.
主机DB2数据库应用与编程 任课老师:王湖南 四川大学计算机(软件)学院.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
全国计算机等级考试 二级基础知识 第二章 程序设计基础.
在PHP和MYSQL中实现完美的中文显示
Oracle数据库入门.
第13章 PL/SQL程序设计.
数据库技术 第十章 数据库完整性 中国科学技术大学网络学院 阚卫华.
第四章:触发器   触发器类似于过程、函数,因为它们都是拥有说明部分、语句执行部分和异常处理部分的有名的PL/SQL块。与包类似,触发器必须存储在数据库中,并且不能被块进行本地化说明。但是,对于过程而言,可以从另一个块中通过过程调用显式地执行一个过程,同时在调用时可以传递参数。对于触发器而言,当触发事件发生时就会显式地执行该触发器,并且触发器不接受参数。
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
作业4讲评.
ORACLE 第五讲 PL/SQL编程基础.
Transact-SQL 語言設計教學.
第五章 使用 PL/SQL.
第三章:包   包(package)是一个可以将相关对象存储在一起的PL/SQL结构。包包含了两个分离的部件------包说明(specification)和包主体(body)。每个部件都单独被存储在数据字典中。包只能存储在数据库中,不能是本地的。除了可以将相关对象作为一组存在一起以外,包也是十分有用的,因为它们在依赖性方面的限制是比较小的。也有许多性能上的优点。
SQL Injection.
走进编程 程序的顺序结构(二).
辅导课程六.
实验4:PL-SQL编程 1.实验目的 2.实验原理 PL/SQL是一种过程化语言,属于第三代语言,本实验在与熟悉使用PL/SQL编程.
SPARQL若干问题的解释 刘颖颖
医院职工公费医疗系统.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
数据库基础 1.
第十章 IDL访问数据库 10.1 数据库与数据库访问 1、数据库 数据库中数据的组织由低到高分为四级:字段、记录、表、数据库四种。
第二章 Java语言基础.
数据库应用技术 SQL Server 2005.
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
第四章 PL/SQL控制结构 If-then:如果条件为true,则执行一行或多行代码,如果条件为假,转到end if之后。
第七章 操作符重载 胡昊 南京大学计算机系软件所.
ORACLE 第九讲 触发器.
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
第4章 PHP流程控制语句.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
1.3 C语言的语句和关键字 一、C语言的语句 与其它高级语言一样,C语言也是利用函数体中的可执行 语句,向计算机系统发出操作命令。按照语句功能或构成的不 同,可将C语言的语句分为五类。 goto, return.
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
$9 泛型基础.
4.2 视图 (1) 视图是一个虚拟表,其内容来自对表查询的基础上。
SQL 范引娣.
VB与Access数据库的连接.
第三章 SQL Server数据管理.
Web安全基础教程
成绩是怎么算出来的? 16级第一学期半期考试成绩 班级 姓名 语文 数学 英语 政治 历史 地理 物理 化学 生物 总分 1 张三1 115
PL/SQL程序设计.
信号量(Semaphore).
第4章 Excel电子表格制作软件 4.4 函数(一).
Oracle Database 10g基础教程 清华大学出版社
第九节 赋值运算符和赋值表达式.
iSIGHT 基本培训 使用 Excel的栅栏问题
3.16 枚举算法及其程序实现 ——数组的作用.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
Visual Basic程序设计 第13章 访问数据库
临界区问题的硬件指令解决方案 (Synchronization Hardware)
GIS基本功能 数据存储 与管理 数据采集 数据处理 与编辑 空间查询 空间查询 GIS能做什么? 与分析 叠加分析 缓冲区分析 网络分析
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第六章 Excel的应用 五、EXCEL的数据库功能 1、Excel的数据库及其结构 2、Excel下的数据排序 (1)Excel的字段名行
基于列存储的RDF数据管理 朱敏
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
VB与Access数据库的连接.
WEB程序设计技术 数据库操作.
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
学习目标 1、什么是列类型 2、列类型之数值类型.
Presentation transcript:

ORACL深入浅出 主讲人:邹振兴 深入浅出Oracle 主讲:邹振兴

第一章 事务与锁 什么是事务? 如何Oracle使用事务。 在Java中使用事务。 什么是锁? 演示更新丢失的问题。 锁的分类。 阻塞与死锁。 深入浅出Oracle 主讲:邹振兴

什么是事务 什么是事务? 事务四大特性(ACID) 事务是一种机制,这种机制能保证在事务内的DML(数据操作语句)做为一个不可分割的单元进行执行。 举例说明事务。 演示sql servert2005事务处理。 演示Oracle事务处理。 事务四大特性(ACID) 原子性(A) 一致性(C) 隔离性(I) 永久性(D) 深入浅出Oracle 主讲:邹振兴

什么是事务 事务处理的两种方式 比较sql server 2005与Oracle事务处理方式的区别。 显示事务:用户通过编码方式开启事务 隐式事务:数据库默认认为所有操作都是事务 比较sql server 2005与Oracle事务处理方式的区别。 深入浅出Oracle 主讲:邹振兴

如何Oracle使用事务 Oracel事务关键字 讲解Oracel程序员一天 Savepoint a ; 设置事务保存点 Rollback to a ;回滚到事务保存点a,事务不结束 Commit ;提交事务,事务结束 Rollback; 回滚所有事务,事务结束 讲解Oracel程序员一天 深入浅出Oracle 主讲:邹振兴

在Java Jdbc中使用事务 演示如何在Java Jdbc中如何使用事务 驱动包位置:oracle安装路径->oracle->jdbc->lib->classes12.jar 演示案例:DBUtil.java 深入浅出Oracle 主讲:邹振兴

什么是锁 生活中的锁: Oracle中的锁: 为什么会有锁的出现。 锁的作用就是保护私有的空间。 演示Oracle中更新丢失的问题。 讲解此问题的两种思路:一、在第一个用户修改之前不允许其它用户修改。二、在修改之前,查看此数据的版本号。 深入浅出Oracle 主讲:邹振兴

锁的分类 悲观锁定 此锁持悲观态度,认为在用户修改数据期间,一定会有用户再对其修改。那么此锁会在用户事务内一直保持锁定状态,其它用户无法进行修改。 在查询语句后接 for update nowait此可加锁。查询多少数据,锁定多少数据。 乐观锁定 此锁持乐观态度,认为在用户修改数据期间,其它用户不会再对其修改,直到最后提交数据时才判断数据是否已更改。 深入浅出Oracle 主讲:邹振兴

锁的分类 乐观锁定的实现方式: 增加标识列来区分是否已修改 通过Oracle ORA_ROWSCN机制来实现乐观锁定

阻塞与死锁 如果你有两个会话,每个会话都持有另一个会话想要的资源,此时就会出现死锁(deadlock)。例如,如果我的数据库中有两个表A 和B,每个表中都只有一行,就可以很容易地展示什么是死锁。我要做的只是打开两个会话(例如,两个SQL*Plus 会话)。在会话A 中更新表A,并在会话B 中更新表B。现在,如果我想在会话B 中更新表A,就会阻塞。会话A 已经锁定了这一行。这不是死锁;只是阻塞而已。我还没有遇到过死锁,因为会话A 还有机会提交或回滚,这样会话B 就能继续。 深入浅出Oracle 主讲:邹振兴

阻塞与死锁 如果我再回到会话A,试图更新表B,这就会导致一个死锁。要在这两个会话中选择一个作为“牺牲品”,让它的语句回滚。例如,会话B 中对表A 的更新可能回滚,得到以下错误:想要更新表B 的会话A 还阻塞着,Oracle 不会回滚整个事务。只会回滚与死锁有关的某条语句。会话B 仍然锁定着表B 中的行,而会话A 还在耐心地等待这一行可用。收到死锁消息后,会话B 必须决定将表B 上未执行的工作提交还是回滚,或者继续走另一条路,以后再提交。一旦这个会话执行提交或回滚,另一个阻塞的会话就会继续,好像什么也没有发生过一样。 深入浅出Oracle 主讲:邹振兴

总结 开发多用户、数据库驱动的应用时,最大的难点之一是:一方面要力争取得最大限度的并发访问,与此同时还要确保每个用户能以一致的方式读取和修改数据。为此就有了锁定(locking)机制,这也是所有数据库都具有的一个关键特性,Oracle 在这方面更是技高一筹。不过,Oracle 的这些特性的实现是Oracle所特有的,就像SQL Server 的实现只是SQL Server 特有的一样,应用执行数据处理时,要正确地使用这些机制,而这一点要由你(应用的开发人员)来保证。 深入浅出Oracle 主讲:邹振兴

第五章 使用PL/SQL PL/SQL简介 变量、常量 数据类型 流程控制 异常处理 深入浅出Oracle 主讲:邹振兴

PL/SQL简介 PL/SQL是Oracle在sql标准上的加强,使用Oracle能够基于对象编程 T-SQL是基于事务的结构化查询语言

PL/SQL块简介 PL/SQL 块是构成 PL/SQL 程序的基本组织单元,可以编写存储过程、函数、包、触发器等。 深入浅出Oracle 主讲:邹振兴

PL/SQL块简介 演示:PL/SQL打印Hello World。 演示:如何在PL/SQL块中向表中增加一条记录。 演示:查询学员'张秋丽'的年龄。 深入浅出Oracle 主讲:邹振兴

PL/SQL块 小结 每一个PL/SQL块将会自动开启一个事务,在PL/SQL块中必须结束事务,否则,将会阻塞。 PL/SQL块中不能执行select语句进行显示。 在命令行中执行pl-sql块需加/。 在命令行中打印变量需set serverout on; 深入浅出Oracle 主讲:邹振兴

变量与常量 在PL/SQL块的声明部分声明变量或常量 语法: declare sal number; pi constant number := 3.14; 赋值 1、使用赋值运算符“:=” 2、使用 SELECT INTO 语句 3、接收用户输入 深入浅出Oracle 主讲:邹振兴

变量与常量示例 Declare myname varchar2(20) not null :=‘张三’; myage number ; mypi constant number :=3.14; Begin myage:=26; select ename into myname from emp where empno=7369; --输出 End; 注意: 1、变量如果声明为not null,则必须初始化值 2、常量一旦定义则不能修改 深入浅出Oracle 主讲:邹振兴

日期时间 日期时间类型 declare mydate date; mytime timestamp; begin 存储日期和时间数据 常用的两种日期时间类型 DATE TIMESTAMP declare mydate date; mytime timestamp; begin select sysdate into mydate from dual; select sysdate into mytime from dual; dbms_output.put_line(mydate); dbms_output.put_line(mytime); end; 深入浅出Oracle 主讲:邹振兴

布尔类型(boolean) 用于存储逻辑值(TRUE、FALSE和NULL) 不能向数据库中插入BOOLEAN数据 深入浅出Oracle 主讲:邹振兴

属性类型 用于引用数据库列的数据类型,以及表示表中一行的记录类型 列类型%type,语法:表名.列名%type 行类型%rowtype,语法:表名%rowtype 优点 不需要知道被引用的表列的具体类型 如果被引用对象的数据类型发生改变,PL/SQL 变量的数据类型也随之改变 深入浅出Oracle 主讲:邹振兴

属性类型示例 问题1:假设现在不知道emp表Job列的类型,但要保存员工7369的岗位到变量中,如何定义? declare myjob emp.Job%type; begin select Job into myjob from emp where empno=7369; dbms_output.put_line(myjob); end; 深入浅出Oracle 主讲:邹振兴

属性类型示例 问题2:假设要输出emp表员工7369的所有信息,怎么办?定义8个列类型变量,依次输出? declare myemp emp%rowtype; begin select * into myemp from emp where empno=7369; dbms_output.put_line(myemp.ename||myemp.job); end; 深入浅出Oracle 主讲:邹振兴

异常处理 在运行程序时出现的错误叫做异常 发生异常后,语句将停止执行,控制权转移到 PL/SQL 块的异常处理部分 异常有两种类型: 预定义异常 - 当 PL/SQL 程序违反 Oracle 规则或超越系统限制时隐式引发 用户定义异常 - 用户可以在 PL/SQL 块的声明部分定义异常,自定义的异常通过 RAISE 语句显式引发 深入浅出Oracle 主讲:邹振兴

预定义异常 Others 处理所有异常 在用户试图将重复的值存储在使用唯一索引的数据库列中时出现 在将字符串转换为数字时出现 DUP_VAL_ON_INDEX 在将字符串转换为数字时出现 INVALID_NUMBER 在表中不存在请求的行时出现 NO_DATA_FOUND 在执行SELECT INTO语句后返回多行时出现 TOO_MANY_ROWS 在以零作为除数时出现 ZERO_DIVIDE 深入浅出Oracle 主讲:邹振兴

预定义异常 declare myname emp.ename%type; begin select ename into myname from emp; Exception when too_many_rows then dbms_output.put_line('值过多'); end; 深入浅出Oracle 主讲:邹振兴

预定义异常 declare myname emp.ename%type; begin select ename into myname from emp where empno=1; Exception when no_data_found then dbms_output.put_line('没有数据'); end; 深入浅出Oracle 主讲:邹振兴

用户自定义异常 declare myException Exception; begin if ... then raise myException; end if; Exception when myException then ... end; 深入浅出Oracle 主讲:邹振兴

流程控制 条件结构 If语句 Case语句 循环结构 Loop循环 While循环 For循环 深入浅出Oracle 主讲:邹振兴

条件结构 1) if...then...end if; 2) if...then...else if...end if ….end if; 嵌套if 3) if...then...elsif...then...else...end if; 多重if 4)case...when...end case; 编写一个PL/SQL块,用户输入一个员工名,如果该员工的工资低于2000,则将该员工工资增长10%。 深入浅出Oracle 主讲:邹振兴

接收用户输入的两个数,通过条件结构判断两个数的关系 declare num1 number; num2 number; begin num1:=‘&请输入一个数’; num2:='&num2';--接收用户输入'&name' if num1<num2 then dbms_output.put_line('小于'); elsif num1>num2 then dbms_output.put_line('大于'); else dbms_output.put_line('等于'); end if; end; 深入浅出Oracle 主讲:邹振兴

when 'A' then dbms_output.put_line('优秀'); declare grade varchar2(10); begin grade:='&grade'; case grade when 'A' then dbms_output.put_line('优秀'); when 'B' then dbms_output.put_line('良好'); when 'C' then dbms_output.put_line('一般'); when 'D' then dbms_output.put_line('差'); else dbms_output.put_line('没这个'); end case; end; 深入浅出Oracle 主讲:邹振兴

循环结构 使用三种循环实现输出100次我爱你 深入浅出Oracle 主讲:邹振兴

dbms_output.put_line(counter||':我爱你'); --if counter=100 then 1)无条件(无限)循环 --跳出循环 exit,exit when... declare counter number:=0; begin loop counter:=counter+1; dbms_output.put_line(counter||':我爱你'); --if counter=100 then -- exit;--退出循环 --end if; exit when counter=100; end loop; end; 深入浅出Oracle 主讲:邹振兴

dbms_output.put_line(counter||':我爱你'); end loop; end; 2)有条件循环 declare counter number:=0; begin while(counter<100) loop counter:=counter+1; dbms_output.put_line(counter||':我爱你'); end loop; end; 深入浅出Oracle 主讲:邹振兴

dbms_output.put_line(num||':我爱你'); end loop; end; 3)循环固定次数:数字区间:下限..上限 begin for num in 1..100 loop dbms_output.put_line(num||':我爱你'); end loop; end; 深入浅出Oracle 主讲:邹振兴

动态SQL 应用: 1、DDL 语句命令和会话控制语句不能在 PL/SQL 中直接使用,但是可以通过动态 SQL 来执行 深入浅出Oracle 主讲:邹振兴

动态SQL 动态 SQL 是指在PL/SQL程序执行时生成的 SQL 语句 执行语法: execute immediate 'sql语句' [into 变量列表] --将查询的值赋值给变量 [using 参数列表] --使用参数填补占位符(:name) 深入浅出Oracle 主讲:邹振兴

Eg:利用动态SQL建表 begin execute immediate 'create table test ( tid number)'; end; 问题:能否建表后执行插入数据操作? 深入浅出Oracle 主讲:邹振兴

Eg:根据员工编号获得员工姓名 declare myname emp.ename%type; begin execute immediate 'select ename from emp where empno=:no' into myname using '&no'; dbms_output.put_line(myname); end; 问题:如果Sql语句有多个条件怎么写? 深入浅出Oracle 主讲:邹振兴

总结 1、:=赋值运算符 2、||连接操作符 3、'&name'接受用户输入参数值 4、:name 动态SQL中占位符,使用using填补 深入浅出Oracle 主讲:邹振兴

第六章 游标管理 什么是游标 显示游标的使用 游标类型的使用 隐式游标的使用 深入浅出Oracle 主讲:邹振兴

什么是游标 提问:请编写pl-sql块,打印出所有的参加考试的学员信息。 分析问题:pl-sql块中无法使用select语句,使用变量也无法保存多行数据。 解决问题:要是Oracle提供类似于Java集合的结构就能轻松解决问题。 深入浅出Oracle 主讲:邹振兴

显示游标1 显式游标在 PL/SQL 块的声明部分定义查询,该查询可以返回多行 显式游标的操作过程: 关闭游标 变量 打开游标 数据库 30 George 3 44 Roger 2 45 James 1 Stud_mrks Stud_name stud_no 打开游标 数据库 提取行 关闭游标 变量 深入浅出Oracle 主讲:邹振兴

显示游标2 定义: CURSOR <游标名> IS <SELECT 语句>[FOR UPDATE | FOR UPDATE OF 字段] ; 操作: OPEN <游标名>; --打开游标 FETCH <游标名> INTO 变量1,变量2,变量3,....变量n;     或者 FETCH <游标名> INTO 行对象; --取出游标当前位置的值 CLOSE <游标名>; --关闭游标 深入浅出Oracle 主讲:邹振兴

显示游标属性 %NOTFOUND --如果FETCH语句失败,则该属性为"TRUE",否则为"FALSE"; %ROWCOUNT --返回游标当前的行数; %ISOPEN --如果游标是开的则返回"TRUE",否则为"FALSE"; 深入浅出Oracle 主讲:邹振兴

输出所有员工编号与姓名 declare rowemp emp%rowtype;--行变量 cursor empcur is select * from emp;--定义游标 begin open empcur;--打开游标 loop fetch empcur into rowemp; dbms_output.put_line(rowemp.empno||rowemp.ename); exit when empcur%notfound; end loop; close empcur;--关闭游标 end; 深入浅出Oracle 主讲:邹振兴

For循环游标 循环游标用于简化游标处理代码 自动打开游标,提取记录,关闭游标 当用户需要从游标中提取所有记录时使用 循环游标的语法如下: FOR <record_index> IN <cursor_name> LOOP <executable statements> END LOOP; <record_index>是类型为%rowtype的记录变量 使用游标for循环的时候不能使用open语句,fetch语句和close语句, 否则会产生错误。 深入浅出Oracle 主讲:邹振兴

输出所有员工编号与姓名 declare cursor empcur is select * from emp;--定义游标 begin for rowemp in empcur loop dbms_output.put_line(rowemp.empno||rowemp.ename); end loop; end; 深入浅出Oracle 主讲:邹振兴

带参数的游标 提高游标的灵活性 语法: CURSOR <游标名>(参数列表) IS <SELECT 语句> ; 深入浅出Oracle 主讲:邹振兴

根据部门编号输出该部门员工姓名 declare cursor empcur(dtno emp.deptno%type) is select * from emp where deptno=dtno;--定义游标 begin for rowemp in empcur(20) loop dbms_output.put_line(rowemp.ename); end loop; end; 深入浅出Oracle 主讲:邹振兴

游标加锁 [FOR UPDATE | FOR UPDATE OF 字段] 即在程中有“UPDATE”,“INSERT”,“DELETE”语句对数据库操作时,游标自动给指定的表或者字段加锁,防止同时有别的程序对指定的表或字段进行“UPDATE”,“INSERT”,“DELETE”操作。 在使用“DELETE”,“UPDATE”后还可以在程序中使用CURRENT OF <游标名> 子句引用当前行进行更新操作。 深入浅出Oracle 主讲:邹振兴

使用游标更新工资,翻倍 declare cursor mycursor is select sal from emp for update; begin for r in mycursor loop update emp set sal=sal*2 where current of mycursor; end loop; end; 深入浅出Oracle 主讲:邹振兴

REF游标与游标变量 REF 游标和游标变量用于处理运行时动态执行的 SQL 查询 创建游标变量需要两个步骤: 声明 REF 游标类型 TYPE <ref_cursor_name> IS REF CURSOR [RETURN <return_type>]; 打开游标变量的语法如下: OPEN cursor_name FOR select_statement; 深入浅出Oracle 主讲:邹振兴

获取部门10的工资 declare Type salcursor is ref cursor;--声明游标类型 salcurvar salcursor;--定义游标变量 mysal number; begin open salcurvar for select sal from myemp where deptno=10; loop fetch salcurvar into mysal; dbms_output.put_line(mysal); exit when salcurvar%notfound; end loop; end; 深入浅出Oracle 主讲:邹振兴

游标变量优点 游标变量的功能强大,可以简化数据处理。 游标变量的优点有: 可从不同的 SELECT 语句中提取结果集 可以作为过程的参数进行传递 可以引用游标的所有属性 可以进行赋值运算 深入浅出Oracle 主讲:邹振兴

使用游标变量执行动态Sql declare Type salcursor is ref cursor;--声明游标类型 salcurvar salcursor;--定义游标变量 mysal number; begin open salcurvar for 'select sal from myemp where deptno=:dno'--动态SQL字符串 using ‘&no’;--填补占位符的参数 loop fetch salcurvar into mysal; dbms_output.put_line(mysal); exit when salcurvar%notfound; end loop; end; 深入浅出Oracle 主讲:邹振兴

隐式游标 在PL/SQL中使用DML语句时自动创建隐式游标 隐式游标自动声明、打开和关闭,其游标名称为 SQL 深入浅出Oracle 主讲:邹振兴

隐式游标属性 %NOTFOUND --如果DML语句没有影响到任何行时,则该属性为"TRUE",否则为"FALSE"; %ROWCOUNT --返回DML语句影响的行数; %ISOPEN - 游标是否打开,隐式游标始终为FALSE 使用:游标名称+属性 SQL%NOTFOUND 深入浅出Oracle 主讲:邹振兴

隐式游标属性 begin update emp set comm=100 where empno=7369; if SQL%Found=true then dbms_output.put_line('更新成功'); dbms_output.put_line('受影响的行数'||SQl%rowcount); end if; If SQL%NotFound=true then dbms_output.put_line(‘不存在'); end; 深入浅出Oracle 主讲:邹振兴

总结 游标用于处理查询结果集中的数据 游标类型有:隐式游标、显式游标和 REF 游标 隐式游标由 PL/SQL 自动定义、打开和关闭 显式游标用于处理返回多行的查询 在声明 REF 游标时,不需要将 SELECT 语句与 其关联 深入浅出Oracle 主讲:邹振兴

第七章 子程序与程序包 什么是子程序 子程序一:存储过程 子程序二:函数 子程序三:自主事务处理 组织子程序:程序包 深入浅出Oracle 主讲:邹振兴

子程序1 命名的 PL/SQL 块,编译并存储在数据库中。 子程序的各个部分: 子程序的分类: 声明部分 可执行部分 异常处理部分(可选) 过程 - 执行某些操作 函数 - 执行操作并返回值 深入浅出Oracle 主讲:邹振兴

子程序2 子程序的优点: 模块化 可重用性 可维护性 安全性 将程序分解为逻辑模块 可以被任意数目的程序调用 简化维护操作 通过设置权限,使数据更安全 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 过程是用于完成特定任务的子程序 例如: 在柜台购买车票 前往售票厅 排队等候 询问关于车票的信息 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 创建简单过程 create or replace procedure SayHi as begin dbms_output.put_line('hi'); end; 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 调用 --1、在命令窗口下 execute SayHi; --2、在SQL Window下 begin SayHi(); end; 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 带参数过程,参数不用指定长度 create or replace procedure SayHi(str varchar2) as begin dbms_output.put_line(str); end; 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 根据员工编号查询员工姓名,并打印,没找到数据则异常处理 create or replace procedure SearchName(emp_no number) is empname varchar(20); begin select ename into empname from emp where empno=emp_no; dbms_output.put_line(empname); end; 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 过程参数的三种模式: IN OUT IN OUT 用于接受调用程序的值 默认的参数模式 用于向调用程序返回值 用于接受调用程序的值,并向调用程序返回更新的值 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 根据员工编号返回员工姓名给另一程序 create or replace procedure SearchName(emp_no in number,empname out varchar2) is begin select ename into empname from emp where empno=emp_no; end; 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 declare emp_no number; empname varchar2(20); begin emp_no:='&no'; SearchName(emp_no,empname); dbms_output.put_line(empname); end; 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 交换两个数 create or replace procedure Swap(num1 in out number,num2 in out number) is temp number; begin temp:=num1; num1:=num2; num2:=temp; end; 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 declare num1 number:=10; num2 number:=20; begin dbms_output.put_line('num1='||num1); dbms_output.put_line('num2='||num2); Swap(num1,num2); dbms_output.put_line('调用过程后'); end; 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 --返回游标的存储过程 create or replace procedure getAllEmp(returnCursor out sys_refcursor) as begin open returnCursor for select * from emp; end; --使用存储过程返回的游标 declare type classcursor is ref cursor; mycursor classcursor; var_emp emp%rowtype; begin getAllEmp(returnCursor => mycursor); loop fetch mycursor into var_emp; dbms_output.put_line(var_emp.ename); exit when mycursor%notfound; end loop; end; 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 创建过程的语法: create [or replace] procedure 过程名称[(参数列表)] is|as [变量] begin 可执行部分; [Exception] end; 深入浅出Oracle 主讲:邹振兴

子程序一:存储过程 使用Java程序调用几种存储过程。 Test.java 深入浅出Oracle 主讲:邹振兴

子程序二:函数(function) 函数是可以返回值的命名的 PL/SQL 子程序。 参数与返回值类型不用指定长度 深入浅出Oracle 主讲:邹振兴

子程序二:函数 简单函数 create or replace function FSayHi return varchar2 is begin return 'Hi'; end; 深入浅出Oracle 主讲:邹振兴

子程序二:函数 调用函数 1、结合查询 select FSayHi from dual; 2、返回值给变量 declare str varchar2(20); begin str:=FSayHi; dbms_output.put_line(str); end; 深入浅出Oracle 主讲:邹振兴

子程序二:函数 带参函数 create or replace function FSayHi(str varchar2) return varchar2 is begin return str; end; select FSayHi('大家好') from dual; 深入浅出Oracle 主讲:邹振兴

子程序二:函数 --通过员工编号返回员工姓名 create or replace function FSearchName(emp_no number) return varchar2 is empname varchar2(20); begin select ename into empname from emp where empno=emp_no; return empname; end; select FSearchName(7369) from dual; 深入浅出Oracle 主讲:邹振兴

子程序二:函数 创建函数语法 create [or replace] function 函数名称[(参数列表)] return is | as begin 可执行部分; [Exception] end; 深入浅出Oracle 主讲:邹振兴

子程序二:函数 删除过程与函数 授予其他用户执行子程序的权限 drop procedure 过程名; drop function 函数名; grant execute on 子程序名 to 用户名; 深入浅出Oracle 主讲:邹振兴

过程与函数比较 过 程 函 数 作为 PL/SQL 语句执行 作为表达式的一部分调用 在规格说明中不包含 RETURN 子句 函 数 作为 PL/SQL 语句执行 作为表达式的一部分调用 在规格说明中不包含 RETURN 子句 必须在规格说明中包含 RETURN 子句 不返回任何值 必须返回单个值 可以包含 RETURN 语句,但是与函数不同,它不能用于返回值 必须包含至少一条 RETURN 语句 深入浅出Oracle 主讲:邹振兴

子程序三:自主事务处理 自主事务处理 PRAGMA AUTONOMOUS_TRANSACTION 用于标记子程序为自主事务处理 主事务处理启动独立事务处理 然后主事务处理被暂停 自主事务处理子程序内的 SQL 操作 然后终止自主事务处理 恢复主事务处理 PRAGMA AUTONOMOUS_TRANSACTION 用于标记子程序为自主事务处理 深入浅出Oracle 主讲:邹振兴

子程序三:自主事务处理 自主事务处理测试: 创建过程1,执行删除员工7369操作,并回滚 创建过程2,执行删除员工7499操作,并调用过程1 创建程序调用过程2 问哪个删除操作会回滚? 深入浅出Oracle 主讲:邹振兴

子程序三:自主事务处理 create or replace procedure testp1 is --pragma autonomous_transaction;--标识子程序为自主事务处理 begin delete from myemp where empno=7369; rollback; end; 深入浅出Oracle 主讲:邹振兴

子程序三:自主事务处理 create or replace procedure testp2 is begin delete from myemp where empno=7499; testp1; end; 深入浅出Oracle 主讲:邹振兴

组织子程序:程序包 程序包是对相关过程、函数、变量、游标和异常等对象的封装 程序包由规范和主体两部分组成 声明程序包中公共对象。包括类型、变量、常量、异常、游标规范和子程序规范等 程序包 规范 声明程序包私有对象和实现在包规范中声明的子程序和游标 主体 深入浅出Oracle 主讲:邹振兴

组织子程序:程序包 如何将众多的函数与过程组织起来? 定义包 create or replace package mypack is 根据员工编号判断用户是否存在 (函数) 如果存在则打印出员工姓名 (过程) 定义包 create or replace package mypack is procedure PrintName(eno number); function IsHaveEmp(eno number) return boolean; end; 深入浅出Oracle 主讲:邹振兴

create or replace package body mypack 包主体 create or replace package body mypack is procedure PrintName(eno number) mybool boolean; myname varchar2(20); begin mybool:=IsHaveEmp(eno); if mybool =true then select ename into myname from emp where empno=eno; dbms_output.put_line(myname); else dbms_output.put_line('不存在该员工'); end if; end; function IsHaveEmp(eno number) return boolean counter number; select count(*) into counter from emp where empno=eno; if counter>0 then return true; return false; 深入浅出Oracle 主讲:邹振兴

组织子程序:程序包 返回查询结果集(游标) 包主体 create or replace package testpack as Type mytype is ref cursor; procedure GetAllEmp(mycur out mytype,tname in varchar2); end; 深入浅出Oracle 主讲:邹振兴

create or replace package body testpack as 包规范 create or replace package body testpack as procedure GetAllEmp(mycur out mytype,tname in varchar2) str varchar2(100); begin str:='select * from '|| tname; open mycur for str; end; 深入浅出Oracle 主讲:邹振兴

总结 Pl-sql块是oracle编程中最重要的结构。 游标是oracle编程中最生要的工具。 包可以多个存储过程与函数组织起来。 深入浅出Oracle 主讲:邹振兴