数据库设计与优化

上传人:孙哥 文档编号:179376751 上传时间:2023-01-01 格式:DOCX 页数:25 大小:33.98KB
收藏 版权申诉 举报 下载
数据库设计与优化_第1页
第1页 / 共25页
数据库设计与优化_第2页
第2页 / 共25页
数据库设计与优化_第3页
第3页 / 共25页
资源描述:

《数据库设计与优化》由会员分享,可在线阅读,更多相关《数据库设计与优化(25页珍藏版)》请在装配图网上搜索。

1、数据库应用系统设计中的一个核心问题,就是如何设计一个能够满足用户当前与可预见的末来的 各项应用要求、性能良好的数据库。数据库设计是从用户的数据需求、处理要求及建立数据库的环境条件(软、硬件特性,其他限 制)出发,把给定的应用环境(现实世界)存在的数据加以合理地组织起来逐步抽象成已经选定 的某个数据库管理系统能够定义和描述的具体的数据结构的过程。数据库设计的成果是数据库模式和应用程序,而应用程序是以数据为基础的。因此,数据库设 计中最基本的是数据库模式的设计。但是,设计一个完善的数据库系统往往是一个不断反复的过 程,数据库模式必须反映数据处理的要求,保证常用的或大多数的数据处理,使用方便,性能满

2、 意,且应根据应用需求适当地修改,调整数据结构,优化数据模型,以便进一步提高数据库应用 系统的性能。1 规范数据模式 数据模式是关系数据库的重要组成部分,构造合适的数据模式是实现关系数 据库优化设计的一个重要方面。由于关系模型有较为严格的数学工具做支撑,故一般多以关系模 型做讨论的环境,从而形成了关系数据库设计理论。由于这种合适的数据模式应该符合一定的规 范化要求,因而又可称为关系数据库的规范化理论。11 规范化理论 所谓关系规范化就是按统一标准对关系进行优化,以提高关系的质量,为 构造一个高效的数据库应用系统打下基础。例如有一个反映轮船信息的数据库,由以下 8 个属性 组成:船号、船名、马力

3、、部件号、部件名、型号、重量及用量。将这8 个属性构造成一个合适 的关系模式,从而构造一个关系数据库,其构造方法很多。最简单的是,将 8个属性组成如下关 系:轮船(船号、船名、马力、部件号、部件名、型号、重量及用量)但是,在对这个关系操作 时会有 3 个问题:(1)冗余度大 一艘轮船有 N 个部件,就有 N 次重复船号、船名、马力的数据;(2)插入异常 一种部件,如果在某一阶段没有轮船用到,其对应的信息就无法插入,使 数据库在功能上产生了不正常的现象,同时也给用户带来极大的不便;(3)删除异常 一种部件,若只有一艘轮船用到,则删除他的信息,有关他选用的部件信 息同时也删除了,从而丢失了应用的数

4、据。从上面的分析可知,轮船关系不是一个“好”的数据库模式。一个“好”的模式应当避免发 生插入异规范化理论认为,关系中的各属性是相互关联的,他们互相依赖、互相制约,构成一个 结构严谨的整体。因此,在关系设计中,必须从语义中摸清这些关联,特别是依赖关系,只能把 那些相互关联密切的属性拼凑在一起。构造一个“好”的数据库模式,必须使他的关系模式的属 性之间满足某种内在的语义条件,而这种联系又可对关系的不同要求分为若干等级,这就是关系 规范化。以函数依赖为基础的关系模式的规范化等级主要有5种,即第1范式(1NF),第2范 式(2NF),第3范式(3NF), BC范式(BCNF)和第4范式(4NF),满足

5、这些范式条件的关系 模式可在不同程度上避免冗余、插入和更新异常问题。12 规范化理论的应用 为了消除关系模式在操作上的异常问题,优化数据模式,可进行 规范化处理。具体做法是:确定数据依赖,把每个关系模式的各个属性按数据分析阶段所得到的 语义写出其数据依赖,同时,考察不同的关系模式属性之间是否还存在某种数据依赖,得到一组 数据依赖及诸关系的全部数据依赖。按照数据依赖的理论,逐一分析这组关系模式,确定他们属 于第几范式,进行模式分解。例如,对上述轮船关系进行分解,提高范式等级,可构成一个轮船信息的数据库,他的数据 模式由 4个关系组成:轮船(船号、船名、马力);使用(船号、部件号、用量);部件(部

6、件 号、部件名、型号);型重(型号、重量)。这 4 个关系属于 3NF ,至此,是一个比较“好”的数据库了。2 改善数据库性能 关系数据库的性能的好坏,主要体现在查询的速度上,他是数据库应用 中的一个关键问题,是必须在数据库的设计中加以认真考虑的问题,特别是对那些响应时间要求 较苛刻的应用,应予以特别注意。可从以下几个方面提高查询速度,改善数据库性能,从而达到 数据库设计的优化目的。21 减少连接操作 连接操作对数据库的查询速度有着重要的影响,参与联接的关系越多, 查询越慢。因此,对一些常用的、性能要求较高的数据库查询,最好是一元查询,这与规范化的 要求相矛盾。有时为了保证性能,把规范化的关系

7、再合并起来,称之为逆规范化。当然,这样会 引起更新异常,破坏数据库完整性,必须采取相应的措施来保证数据库的完整性,从而也会增加 系统的开销。因此,决定做逆规范化时,一定要权衡利弊,仔细分析应用的数据存取需求和实际 的系统性能。22 减小关系大小及数据量 被查询关系的大小对查询速度影响很大。为了提高查询速度, 可以采用水平分割或垂直分割等方法把一个关系分成几个关系,使每个关系的数据量减少。例如, 对于有关学生的关系,既可以把全校集中在一个关系中,也可用水平分割的方法,分系建立关系, 从而减少了每个关系的元组数。前者对全校范围内的查询较方便,后者则可以显著提高对系的查 询速度;也可采用垂直分割的方

8、法,把常用数据和不常用的数据分开,以提高常用数据的查询速 度。例如:人事档案中,属性很多,有些需经常查询,有些则很少查询。如果放在一起,则关系 数据量很大,影响查询速度。分开可提高常用数据的查询速度。垂直分割提高了一些操作的速度, 但也可能使某些操作不得不执行连接操作,从而降低了效率。因此,决定是否进行垂直分割取决 于是否垂直分割后数据库上的所有操作的总效率得到了提高。同时,垂直分割还要确保无损连接 和保持函数依赖。3 节省存储空间 尽管随着硬件技术的发展,提供给用户使用的存储空间越来越大,但毕 竟是有限的,而数据库,尤其是一型的数据库,需要占用的存储空间比较大。因此,节省存储空 间仍是数据库

9、设计中要考虑的问题。为此,在数据库优化设计中,可采取以下措施:31 缩小每个属性占用的空间 一般用编码表示属性,用缩写名代替全称,可以节省存储 空间,但用户看起来就不那么直观了,须根据实际条件斟酌决定。32 采用假属性 在有些关系中,某些数据会多次出现,采用假属性可以减少重复数据占 用的存储空间。例如:在职工关系中,职工的经济状况这一属性,通常由职工号决定。一个大型 企业的职工人数较多。如每一个职工逐一填写经济状况,就要占用较多的空间,而其经济状况有 相同的和相似的情况,也即,经济状况这一属性不同值比较少,而在关系中可能有较多的重复。 为此,可把经济状况分为几种类型,用类型代替原来的经济状况(

10、这类经济状况的类型就是假属 性),另外建立一个较小的关系来描述每种经济状况的具体内容。这样,可大大减小数据占用存 储空间的用量。4结语 数据库设计不同于数学问题,他是一项综合性工作,受到各种各样因素的制约,有些要求往往是 彼此矛盾的。因此,设计结果常常是有得有失。因此,设计者必须根据实际情况,综合应用上述 技术,在基本合理的总体设计的基础上,做一些优化调整,力求最大限度地满足用户各种各样的 要求,实现数据库的优化设计。13 模式分解的 2条原则关系规范化是可以解决关系操作的问题,但进行模式分解时由于受到数据间的相互约束,因此分解不可能是随意的。在规范化化的关系分解过程中,不仅要着 眼于提高关系

11、的范式等级,而且应遵守以下 2 条原则:(1)无损分解原则 无损分解就是在关系分解过程中,既不丢失数据也不增加数据,同时 还能保持原有的函数依赖。一个关系分解为多个关系,原来的数据就存储到多个关系中,起码要 求分解后不能丢失原来的信息。(2)相互独立原则 所谓独立是指分解后的新关系之间相互独立,对一个关系内容的修改 不应该影响到另一关系。此外还应注意到,关系分解必须从实际出发,并不是范式等级越高,分解得越细就越好。若 把关系分解得过于琐碎,虽然对于消除数据冗余和更新异常等有好处,但在进行检索操作时往往 又需要进行链接,从而使检索效率大大降低。另外,在数据操作中经常是检索操作多于更新操作, 其结

12、果很可能是分解带来的好处与检索的效率降低相比,得不偿失。正因为如此,一般规范化只 需达到 3NF 就可以了。PLSQL开发笔记和小结关键字: plsql 开发笔记和小结PLSQL开发笔记和小结*PLSQL 基本结构* 基本数据类型变量1. 基本数据类型Number 数字型Int 整数型Pls_integer 整数型,产生溢出时出现错误Binary_integer 整数型,表示带符号的整数Char 定长字符型,最大 255 个字符Varchar2 变长字符型,最大 2000 个字符Long 变长字符型,最长 2GBDate 日期型Boolean 布尔型(TRUE、FALSE、NULL 三者取一)

13、在PL/SQL中使用的数据类型和Oracle数据库中使用的数据类型,有的含义是 完全一致的,有的是有不同的含义的。2. 基本数据类型变量的定义方法变量名 类型标识符not null:二值; declareage number(3):=26; -长度为 3,初始值为 26 begincommit;end;其中,定义常量的语法格式:常量名constant类型标识符not null:=值;declarepi constant number(9):=3.1415926;为 pi 的数字型常量,长度为 9,初始 值为 3.1415926begincommit;end;表达式变量、常量经常需要组成各种表达

14、式来进行运算,下面介绍在PL/SQL中常见表 达式的运算规则。1. 数值表达式PL/SQL程序中的数值表达式是由数值型常数、变量、函数和算术运算符组成的, 可以使用的算术运算符包括+ (加法)、-(减法)、* (乘法)、/ (除法 )和* (乘方)等。命令窗口中执行下列PL/SQL程序,该程序定义了名为result的整数型变量, 计算的是10+3*4-20+5*2 的值,理论结果应该是 27。set serveroutput onDeclare result integer;begin result:=10+3*4-20+5*2;dbms_output.put_line(运算结果是:|to_c

15、har(result); end;dbms_output.put_line函数输出只能是字符串,因此利用to_char函数将数值 型结果转换为字符型。2. 字符表达式字符表达式由字符型常数、变量、函数和字符运算符组成,唯一可以使用的字 符运算符就是连接运算符“|”。3. 关系表达式 关系表达式由字符表达式或数值表达式与关系运算符组成,可以使用的关系运算符包括以下9 种。 大于= 等于(不是赋值运算符:=)like 类似于in 在之中= 大于等于!= 不等于 或 between 在之间 关系型表达式运算符两边的表达式的数据类型必须一致。4. 逻辑表达式 逻辑表达式由逻辑常数、变量、函数和逻辑运算

16、符组成,常见的逻辑运算符包 括以下3 种。NOT :逻辑非OR :逻辑或AND :逻辑与运算的优先次序为 NOT、AND 和 OR。PLSQL 函数PL/SQL程序中提供了很多函数供扩展功能,除了标准SQL语言的函数可以使用 外,最常见的数据类型转换函数有以下3个。To_char :将其他类型数据转换为字符型。To_da te:将其他类型数据转换为日期型。To_number :将其他类型数据转换为数值型。 继续追加中 .系统输出打印利用pl/sql在数据库服务器端打印一句话:set serveroutput on-设置数据库输出,默认为关闭,每次重新打开窗口需要 重新设置。BEGINDBMS_

17、OUTPUT.PUT_LINE(Hello PL/SQL);END;pl/sql 程序中对大小写不敏感(打印声明的变量)set serveroutput onDECLAREv_char varchar2(20):=a;v_char1 varchar2(20):=b;BEGINDBMS_OUTPUT.PUT_LINE(v_char);DBMS_OUTPUT.PUT_LINE(v_char1);END;pl语句块是pl/sql里最小的编程块,其中可以再嵌套begin end begindbms_output.put_line(Hello World); dbms_output.put_line(2

18、*3=|(2*3); dbms_output.put_line(whats);end;PL/SQL 中的变量声明所有变量必须在declare中声明,程序中不允许声明。没有初始化的变量默认值为null,屏幕上null是看不见的,命名习惯:PL/SQL 中变量一般以v_开头(等同于存储过程中as和begin区域的变量定义习惯)。注意number也能存小数,最长38位,所以以后建议整数都用binary_integer 存。long是字符类型,boolean类型不能打印。标准变量类型:数字,字符,时间,布尔。declarev_number1 number;v_number2 number(3,2) ;

19、v_number3 binary_integer :=1;v_name varchar2(20) :=kettas;v_date date :=sysdate;v_long long :=ni hao;v_b boolean := true;beginif (v_number1 is null) then dbms_output.put_line( hello); end if;dbms_output.put_line(v_number1);dbms_output.put_line(v_number2);dbms_output.put_line(v_number3); dbms_output.

20、put_line(v_name); dbms_output.put_line(v_date); dbms_output.put_line(v_long);-dbms_output.put_line(v_b); - 执行该句 ORACLE 提示“调用 PUT_LINE 时参数个数或类型错误”end;备注:关于声明number(4,3)中括号中的两个数字的意义,前面的数字叫精度,后面 的叫刻度。刻度:当刻度为正数的时候,表示四舍五入到小数点后面的位数 当刻度为负数的时候,表示四舍五入到小数点前面的位数精度:从数字的最前面不为零开始到刻度精确到的位置v_Number number(4,3):=123

21、.123121、按刻度进行四舍五入得到 123.1232、确定刻度精确到的位置123123处,精度为6位(.符号不算)2、根据精度进行判断 6 位(4)精度上限值 -报错不能存储number(3,-3):=444451、根据刻度3 进行四舍五入得到 440002、小数点向前移动 3 位 44.此位置为刻度精确到的位置3、根据精度进行判断 2 位(3)精度上限值 -不报错可存储结果为 44000DECLAREv_Number number(4,3):=123.12312;实际精度6位大于上限精度值4位,提 示“ORA-O65O2: PL/SQL:数字或值错误:数值精度太高”BEGINDBMS_O

22、UTPUT.PUT_LINE(v_Number);ENDDECLAREv_Number number(7,3):=4555; -实际精度7位等于上限精度值,可以存储 BEGINDBMS_OUTPUT.PUT_LINE(v_Number);END*变量赋值方式*oracle 中变量赋值方式是值拷贝而非引用declarev_number1 number:=100;v_number2 number;beginv_number2:=v_number1;v_number1:=200;dbms_output.put_line(v_number1); -200dbms_output.put_line(v_n

23、umber2); -100end;*PLSQL 复合类型*记录类型 recordrecord类型最常用,声明的时候可以加not null,但必须给初始值,如果record 类型一致可以相互赋值,如果类型不同,里面的字段恰好相同,不能互相赋值。 引用记录型变量的方法是“记录变量名.基本类型变量名”。declaretype t_first is record( id number(3),name varchar2(20);v_first t_first;beginv_first.id:=1; v_first.name:=cheng; dbms_output.put_line(v_first.id)

24、; dbms_output.put_line(v_first.name); end;record 类型变量间赋值declaretype t_first is record(id number,name varchar2(20);v_first t_first;v_second t_first;beginv_first.id:=1;v_first.name:=susu;v_second:=v_first;- 相互赋值v_first.id:=2;v_first.name:=kettas; dbms_output.put_line(v_first.id); dbms_output.put_line(

25、v_first.name); dbms_output.put_line(v_second.id); dbms_output.put_line(v_second.name); end;表类型变量 table语法如下:type 表类型 is table of 类型 index by binary_integer;表变量名 表类型;类型可以是前面的类型定义,index by binary_integer子句代表以符号整数为 索引,这样访问表类型变量中的数据方法就是“表变量名(索引符号整数)”。table类型,相当于java中的Map容器,就是一个可变长的数组,key (符号整 数索引)必须是整数,可

26、以是负数,value (类型)可以是标量,也可以是record 类型。可以不按顺序赋值,但必须先赋值后使用。1. 定义一维表类型变量declaretype t_tb is table of varchar2(20) index by binary_integer; v_tb t_tb;beginv_tb(100):=hello;v_tb(98):=world;dbms_output.put_line(v_tb(100); dbms_output.put_line(v_tb(98);end;类型为 record 的表类型变量declaretype t_rd is record(id number

27、,name varchar2(20);type t_tb is table of t_rd index by binary_integer; v_tb2 t_tb;beginv_tb2(100).id:=1; v_tb2(100).name:=hello;-dbms_output.put_line(v_tb2(100).id);-dbms_output.put_line(v_tb2(100).name);dbms_output.put_line(v_tb2(100).id| |v_tb2(100).name); end;2. 定义多维表类型变量该程序定义了名为tabletypel的多维表类型,

28、相当于多维数组,tablel是多维 表类型变量,将数据表 tempuser.testtable 中 recordnumber 为 60 的记录提取 出来存放在 tablel 中并显示。declaretype tabletypel is table of testtable%rowtype index by binary_integer; tablel tabletypel;begin select*intotablel(60)fromtempuser.testtablewhererecordnumber=60;dbms_output.put_line(tablel(60).recordnumb

29、er|tablel(60).currentdate); end;备注:在定义好的表类型变量里,可以使用 count、delete、first、last、next、 exists和prior等属性进行操作,使用方法为“表变量名属性”,返回的是数 字。set serveroutput ondeclaretype tabletype1 is table of varchar2(9) index by binary_integer; table1 tabletype1;begintable1(1):= 成都市 ;table1(2):= 北京市 ;table1(3):= 青岛市 ;dbms_output

30、.put_line(总记录数:|to_char(tablel.count);dbms_output.put_line(第一条记录:|tablel.first); dbms_output.put_line( 最后条记录: |table1.last); dbms_output.put_line( 第二条的前一条记录: |table1.prior(2); dbms_output.put_line( 第二条的后一条记录: |table1.next(2); end;*%type 和%row type*使用%type定义变量,为了让PL/SQL中变量的类型和数据表中的字段的数据类 型一致,Oracle 9

31、i提供了type定义方法。这样当数据表的字段类型修改后, PL/SQL程序中相应变量的类型也自动修改。create table student(id number,name varchar2(20),age number(3,0);insert into student(id,name,age) values(1,susu,23); -查找一个字段的变量declarev_name varchar2(20);v_name2 student.name%type;beginselect name into v_name2 from student where rownum=1; dbms_outpu

32、t.put_line(v_name2);end;- 查找多个字段的变量declarev_id student.id%type;v_name student.name%type;v_age student.age%type;beginselect id,name,age into v_id,v_name,v_age from student where rownum=1; dbms_output.put_line(v_id| |v_name| |v_age);end;- 查找一个类型的变量,推荐用 *declarev_student student%rowtype;beginselect * i

33、nto v_student from student where rownum=1;dbms_output.put_line(v_student.id| |v_student.name| |v_student.age);end;- 也可以按字段查找,但是字段顺序必须一样,不推荐这样做declarev_student student%rowtype;beginselect id,name,age into v_student from student where rownum=1;dbms_output.put_line(v_student.id| |v_student.name| |v_stu

34、dent.age);end;declarev_student student%rowtype;beginselect id,name,age into v_student.id,v_student.name,v_student.age from student where id=1;-select * into v_student.id,v_student.name,v_student.age from student where id=1;dbms_output.put_line();end;备注: insert, update, delete, select 都可以,create tabl

35、e, drop table 不行。DPL, DML,和流程控制语句可以在pl/sql里用,但DDL语句不行。declarev_name student.name%type:=wang;begininsert into student(id,name,age) values(2,v_name,26); end;begininsert into student(id,name,age) values(5,hehe,25); end;declarev_name student.name%type:=hexian; beginupdate student set name=v_name where i

36、d=1; end;beginupdate student set name=qinaide where id=2; end;*PLSQL 变量的可见空间*变量的作用域和可见性,变量的作用域为变量申明开始到当前语句块结束。当外 部过程和内嵌过程定义了相同名字的变量的时候,在内嵌过程中如果直接写这个 变量名是没有办法访问外部过程的变量的,可以通过给外部过程定义一个名字,通过outername变量名来访问外部过程的变量(待测试.)。declarev_i1 binary_integer:=1;begindeclarev_i2 binary_integer:=2;begindbms_output.put

37、_line(v_i1);dbms_output.put_line(v_i2);end;dbms_output.put_line(v_i1);-dbms_output.put_line(v_i2); 解开后执行 Oracle 会提示“必须说明标识 符 V_I2”end;*PLSQL 流程控制* if判断declarev_b boolean:=true;begin if v_b thendbms_output.put_line(ok);end if;end;if else 判断declarev_b boolean:=true;beginif v_b thendbms_output.put_line

38、(ok);elsedbms_output.put_line(false);end if;end;if elsif else 判断 declarev_name varchar2(20):=cheng;beginif v_name=0701 then dbms_output.put_line(0701);elsif v_name=cheng then dbms_output.put_line(cheng);elsedbms_output.put_line(false);end if;end;loop循环,注意推出exit是推出循环,而不是推出整个代码块 declarev_i binary_inte

39、ger:=0;beginloopif v_i10 thenexit;end if;v_i:=v_i+1;dbms_output.put_line(hehe);end loop;dbms_output.put_line(over);end;loop 简化写法declarev_i binary_integer :=0;beginloopexit when v_i10;v_i :=v_i+1;dbms_output.put_line(hehe);end loop;dbms_output.put_line(over);end;while 循环declarev_i binary_integer:=0;b

40、eginwhile v_iv_id;beginv_id:=10;open c_student;close c_student;end;第三种游标的定义方式,带参数的游标,用的最多。declarecursor c_student(v_id binary_integer) is select * from book whereidv_id;beginopen c_student(10);close c_student;end;游标的使用,一定别忘了关游标。declarev_student book%rowtype;cursor c_student(v_id binary_integer) is s

41、elect * from book whereidv_id;beginopen c_student(10);fetch c_student into v_student;close c_student;dbms_output.put_line(v_student.name);end;如何遍历游标 fetch游标的属性 found, %notfound,%isopen,%rowcount。%found:若前面的fetch语句返回一行数据,则%found返回true,如果对未打 开的游标使用则报ORA-1OO1异常。%notf ound,与%found 行为相反。%isopen,判断游标是否打开。

42、%rowcount:当前游标的指针位移量,到目前位置游标所检索的数据行的个数, 若未打开就引用,返回 ORA-1001。注:no_data_found和%notfound的用法是有区别的,小结如下1) SELECT . . INTO 语句触发 no_data_found;2) 当一个显式光标(静态和动态)的where子句未找到时触发%notfound;3) 当UPDATE或DELETE语句的where子句未找到时触发sql%notfound;4) 在光标的提取(Fetch)循环中要用%notfound或%found来确定循环的退出条 件,不要用 no_data_found。下面是几个实例:cr

43、eate table BOOK(ID VARCHAR2(10) not null,BOOKNAME VARCHAR2(10) not null,PRICE VARCHAR2(10) not null,CID VARCHAR2(10) not null);insertcreate or replace procedure say_hello( i_name in varchar2,o_result_msg out varchar2)asv_price varchar2(100);e_myException exception;begininsert into book(id,bookname,p

44、rice) values (1,2,3); o_result_msg := success;exceptionwhen others thenrollback;o_result_msg := substr(sqlerrm, 1, 200);end;update or deletecreate or replace procedure say_hello(i_name in varchar2, o_result_msg out varchar2)asv_price varchar2(100); e_myException exception;beginupdate book set price

45、= 55 where bookname = i_name; delete from book where bookname = i_name;if sql%notfound thenraise e_myException;end if;/*if sql%rowcount 二 0 then-写法 2raise e_myException;end if;*/o_result_msg := success;exceptionwhen e_myException then rollback;o_result_msg := update or delete dail;end;selectcreate o

46、r replace procedure say_hello( i_name in varchar2, o_result_msg out varchar2)asv_price varchar2(100); e_myException exception;beginselect price into v_price from book where bookname = i_name; o_result_msg := success;exceptionwhen no_data_found then rollback;o_result_msg := select into dail;end;loop

47、方式遍历游标declarev_bookname varchar2(100);cursor c_book(i_id number) is select bookname from book where id = i_id; beginOpen c_book(i_id);LoopFetch c_book into v_bookname;exit when c_student%notfound;update book set price = 33 where bookname = v_bookname;End Loop;Close c_book;end;或declarev_bookname varc

48、har2(100);cursor c_book(i_id number) is select bookname from book where id = i_id; beginOpen c_book(i_id);Fetch c_book into v_bookname;While c_book%FoundLoopupdate book set price = 33 where bookname = v_bookname;Fetch c_book into v_bookname;End Loop;Close c_book;end;while循环遍历游标,注意,第一次游标刚打开就fetch, %f

49、ound为null,进 不去循环解决方法:while nvl(c_student%found,true) loopdeclarev_bookname varchar2(100);cursor c_book(i_id number) is select bookname from book where id = i_id; beginOpen c_book(i_id);while nvl(c_book%found,true) -或这种写法: while c_book%found is null or c_book%found loopFetch c_book into v_bookname;up

50、date book set price = 33 where bookname = v_bookname;End Loop;Close c_book;end;for 循环遍历,最简单,用的最多,不需要 声明 v_student,Open 和 Close 游标 和fetch操作(不用打开游标和关闭游标,实现遍历游标最高效方式)declarecursor c_book(i_id number) is select bookname from book where id = i_id; beginfor cur in c_book(i_id) - 直接将入参 i_id 传入 cursor 即可 lo

51、opupdate book set price = 53 where bookname = cur.bookname; end loop;end;goto例子,一般不推荐使用goto,会使程序结构变乱declarei number:=0;beginif i=0 thengoto hello;end if;begindbms_output.put_line(hello);goto over;end;begindbms_output.put_line(world);goto over;end;dbms_output.put_line(over);end;*Oracle 存储过程* 在谈存储过程书写

52、中的一些规则时,先看一下执行它的规则,在命令窗口执行存 储过程 sp_get_product_promptset serveroutput onvar ret1 varchar2(200);var ret2 varchar2(200);exec sp_get_product_prompt(83,:ret1,:ret2); - 或 executeprint ret1;print ret2;或set serveroutput ondeclareret1 varchar2(200);ret2 varchar2(200);beginsp_get_product_prompt(83,ret1,ret2)

53、;dbms_output.put_line(ret1);dbms_output.put_line(ret2);end;存储过程入参,不论类型,缺省情况下值都为null,入参和出参不能有长度,其 中关键字as可以替换成is,存储过程中变量声明在as和begin之间,同时,存 储过程中可以再调用其它的存储过程,如果要保证存储过程之间的事务处理不受 影响,可以定义为自治事务。create or replace procedure say_hello(v_name in varchar2,v_flag number,o_ret out number)asbeginif v_name is null a

54、nd v_flag is null then-v _name 和 v_flag 都等于 null o_ret := 10;elseo_ret := 100;end if;end;对于入参为null情况下给予缺省值create or replace procedure say_hello(i_name in varchar2,i_flag number,o_ret out number)asv_name varchar2(100);beginif i_name is null thenv_name := 0;elsev_name := i_name;end if;insert into phone(.,wname.,) values(.,v_name,.);end;或直接在 insert 语句中调用 nvl 函数赋缺省值insert into phone(.,wname.,) values(.,nvl(v_name, ),.); 如果将 写成,则 insert 进来的 v_name 值还是为等价于 null 值 带一个参数的存储过程输入参数in,输入参数不能进行:二赋值,但可以将它赋给as后面定义的变量; 输入参数in,可以作为变量进行条件判断;默认不写就是in;存储过程没有重载,这个有参的 say

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!