实验五PLSQL高级编程
- 格式:doc
- 大小:35.00 KB
- 文档页数:5
文档标识此版本文档的正式核准分发控制文档修订历史目录1. 文件组织 (1)2. 文件结构 (2)2.1. 文件的声明 (2)2.2. 包头(package header) (2)2.3. 包体(package body) (4)3. PL/SQL语言规范 (4)3.1. 变量规范 (4)3.2. 包规范 (4)3.3. 游标规范 (4)3.4. 事务处理规范 (5)3.5. 数据封装规范 (5)3.6. 数据访问规范 (5)3.7. 日志书写规范 (5)3.8. 错误处理规范 (6)3.9. 书写规范 (6)3.10. 书写优化性能建议 (7)3.11. 其他经验性规则 (8)4. 增量脚本维护规范 (9)4.1. 增量脚本回归规范 (9)4.2. 增量脚本文件命名规范 (9)4.3. 增量脚本内部处理规范 (9)1.文件组织PACKAGE脚本的文件名以pk_开头,扩展名为sql,每个包的包头和包体分开在不同文件中,包头文件名为(包名称)+”_hdr.sql”,包体文件名为(包名称)+”_bdy.sql”,一个文件中只能有一个包。
每个pkg里面的sp的功能点需参见客户需求测试脚本文件以功能点编号+后缀(ini) 命名2.文件结构2.1. 文件的声明文件的声明描述了文件和文件踪迹变化,位于文件的开头(参见示例1-1),主要内容有:(1)英文名称本存储过程(函数)的英文名(2)模块名称本存储过程(函数)的中文名称(3)模块功能本存储过程(函数)实现的功能简单描述( 4 ) 创建日期在此栏目中描述此模块作者,创建日期,版本号等信息( 5 ) 修改历史记录变更人,变更时间,变更内容( 6 ) 备注记录需要特殊描述或者提醒其他人注意的内容2.2. 包头(package header)包头声明了包中的各个部件(过程和函数)。
注意事项:一、过程名、函数名要用小写字母,过程名以pr_开头,函数名以fn_开头。
二、每个部件(过程或函数)要有说明,包括:模块名称、模块编号、模块功能、修改历史。
plsql编译【1.PL/SQL简介】PL/SQL(Procedural Language/Structured Query Language)是一种过程式编程语言,用于在关系型数据库管理系统(RDBMS)中进行存储过程、触发器和函数的开发。
它源于Oracle数据库系统,并已成为许多数据库管理系统中的标准编程语言。
【2.PL/SQL编译过程】PL/SQL编译过程主要包括以下几个步骤:1.解析:解析器读取PL/SQL代码,识别出其中的关键字、标识符、操作符和分隔符等,生成抽象语法树(AST)。
2.语义分析:对AST进行语义分析,检查代码中的语法错误和语义错误。
3.编译:将经过语义分析的代码编译为字节码,以便在数据库服务器上执行。
4.代码优化:编译器会对生成的字节码进行优化,提高代码的执行效率。
5.生成执行计划:根据优化后的字节码生成执行计划,用于数据库服务器的执行。
【3.编译器组件】编译器主要包括以下几个组件:1.词法分析器:负责识别PL/SQL代码中的关键字、标识符、操作符和分隔符等。
2.语法分析器:将词法分析器生成的抽象语法树进行解析,检查代码的语法结构。
3.语义分析器:对语法分析器生成的AST进行语义分析,检查代码的语义正确性。
4.代码生成器:将经过优化的AST编译为字节码。
5.优化器:对生成的字节码进行优化,提高代码的执行效率。
【4.代码优化】编译器会对生成的字节码进行以下方面的优化:1.消除冗余操作:删除代码中不必要的计算,减少执行次数。
2.常量折叠:将常量运算结果提前计算,减少执行次数。
3.谓词提升:将谓词(如大于、小于等)提升为逻辑表达式,提高代码可读性。
4.索引使用:优化查询语句,提高查询效率。
【5.编译与执行】编译完成后,生成的字节码会被加载到数据库服务器上,并根据执行计划进行执行。
执行过程中,数据库服务器会负责解释和执行字节码,完成相应的操作。
【6.常见问题及解决方法】1.语法错误:检查代码中的关键字、标识符、操作符等是否符合语法规范。
ORACLE PL/SQL编程详解第一章:PL/SQL 程序设计简介SQL语言只是访问、操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发。
PL /SQL是一种高级数据库程序设计语言,该语言专门用于在各种环境下对ORACLE数据库进行访问。
由于该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理。
除此之外,可以在ORACLE数据库的某些客户端工具中,使用PL/SQL语言也是该语言的一个特点。
本章的主要内容是讨论引入PL/SQL语言的必要性和该语言的主要特点,以及了解PL/SQL语言的重要性和数据库版本问题。
还要介绍一些贯穿全书的更详细的高级概念,并在本章的最后就我们在本书案例中使用的数据库表的若干约定做一说明。
1.1 SQL与PL/SQL1.1.1 什么是PL/SQL?PL/SQL是Procedure Language & Structured Query Language 的缩写。
ORACLE的SQL是支持ANSI(American national Standards Institute)和ISO92 (International Standards Organization)标准的产品。
PL/SQL是对SQL语言存储过程语言的扩展。
从ORACLE6以后,ORACLE的RDBMS附带了PL/SQL。
它现在已经成为一种过程处理语言,简称PL/SQL。
目前的PL/SQL包括两部分,一部分是数据库引擎部分;另一部分是可嵌入到许多产品(如C语言,JAVA语言等)工具中的独立引擎。
可以将这两部分称为:数据库PL/SQL和工具PL/SQL。
两者的编程非常相似。
都具有编程结构、语法和逻辑机制。
工具PL/SQL另外还增加了用于支持工具(如ORACLE Forms)的句法,如:在窗体上设置按钮等。
本章主要介绍数据库PL/SQL内容。
实验5PL/SQL编程基础【实验目的与要求】⏹掌握PL/SQL基本语法⏹掌握PL/SQL流程控制方法及相关语句的编写【实验内容与步骤】5.0.实验准备工作1.测试用表的创建与数据添加(1).创建测试表Create Table TESTTABLE(RECORDNUMBER number(4)Not Null,CURRENTDATE Date Not Null)Tablespace"USER";--这里的表空间其实可以省去,这样它就会在当前用户的表空间中创建一个表(2).使用for语句在测试表中加入测试数据Declaremaxrecords Constant Int:=20;i Int:=1;BeginFor i In1..maxrecords LoopInsert Into scott.TESTTABLE(recordnumber,currentdate)--scott 为模式名,应根据实际改动Values(i,Sysdate);dbms_output.put_line('现在输入的内容是:'||i||''||Sysdate);Commit;--这里要commit否则将不会将数据提交到表中End Loop;dbms_output.put_line('记录已经按照计划全部插入,请查看!');End;//注:scott为登录用户名,需根据情况改动.(3).查询表中数据,给出查询结果截图:5.1.最简单的PL/SQL程序1.输出"Hello,World"/***************************************第一个例子:输出"Hello,World"***************************************/set serverout on--设置SQL*Plus将服务器所返回的写出来begin--块开始DBMS_OUTPUT.put_line('Hello,World');--在控制台输出信息,类似C语言的Printf或者java语言中的System.out.print end;--块结束运行结果为:2.接收数据并输出/***************************************在此基础上,完成Hello,某某,某某从客户端得到***************************************/declarev_name varchar2(20);begin--块开始v_name:='&v_name';--与“客户端”交互,类似C语言的scanf语句DBMS_OUTPUT.put_line('测试结果为:Hello,'||v_name);end;--块结束运行结果为:5.2.简单变量的使用1.变量的声明与引用set serveroutput on;--PL/SQL变量之简单类型declarev_dept_id number(5):=1111;v_age binary_integer:=12;v_dept_name varchar2(20):='人事部';v_rate constant number(4,2):=22.12;v_valid boolean not null:=TRUE;v_hire_date date not null:=sysdate+7;beginv_dept_id:=2222;dbms_output.put_line(v_dept_id);end;/运行结果为:2.Into子句赋值的使用:declarev_deptno number(2);v_loc varchar2(15);beginselect deptno,locinto v_deptno,v_locfrom deptwhere dname='SALES';--这要求结果有且仅有一条记录DBMS_OUTPUT.PUT_LINE(V_deptno||'and'||v_loc);--输出end;运行结果为:实验练习:编写一PL/SQL程序,实现依次从客户端(键盘)接收各字段的值,并放于变量中,输完一条记录的所有字段值后,将值写到数据库表Emp中。
plsql教程PL/SQL是一种与Oracle数据库一起使用的过程化编程语言。
它是操纵、定义和控制Oracle数据库对象的语言,并提供了一种编写存储过程、触发器、函数、包等数据库程序模块的方式。
PL/SQL的基本语法与SQL相似,可以执行SQL语句和存储过程的调用。
以下是一些常用的PL/SQL代码示例:1. 声明变量和常量:```DECLAREnum1 NUMBER := 10;text1 VARCHAR2(20) := 'Hello';constant1 CONSTANT NUMBER := 5;BEGIN-- 执行代码END;```2. 条件语句:```IF num1 > 0 THENNULL;ELSIF num1 = 0 THENNULL;ELSENULL;END IF;```3. 循环语句:```FOR i IN 1..5 LOOPNULL;END LOOP;WHILE num1 > 0 LOOP NULL;num1 := num1 - 1; END LOOP;LOOPNULL;EXIT WHEN num1 = 0; num1 := num1 - 1; END LOOP;```4. 异常处理:```BEGIN-- 执行代码EXCEPTIONWHEN OTHERS THEN -- 处理异常END;```5. 创建存储过程:```CREATE OR REPLACE PROCEDURE procedure_name (param1 IN NUMBER, param2 OUT VARCHAR2) IS-- 变量声明BEGIN-- 执行代码param2 := 'Hello';END;```这些只是PL/SQL语言的一部分功能和用法。
通过学习和实践,您可以掌握更多PL/SQL的知识和技巧,提高数据库编程的效率和质量。
实验五:PL/SQL编程基础(1)一、实验目的1.熟悉掌握PL/SQL编程中的变量定义语句2.熟悉掌握PL/SQL编程中的条件语句和循环语句等流程控制语句。
3.能熟练使用上述基本语句编写PL/SQL代码完成指定的数据处理功能。
二、实验内容1、练习PL/SQL中各种类型变量的定义和使用。
参见教材p140实验1,自己举例练习PL/SQL中各种类型变量的定义和使用(包括标量变量、%type类型变量、自定义记录变量、%rowtype变量)。
将所有举例的PL/SQL语句记录下来。
set serveroutpu ondeclarea number:=3;b number:=4;c number;beginc:=(a+b);dbms_output.put_line(c);end;/set serveroutpu ondeclarevar_name emp.ename%type;var_no emp.empno%type;var_sal emp.sal%type;beginselect empno,ename,salinto var_no,var_name,var_salfrom empwhere empno=’7369’;dbms_output.put_line(var_no||’’||var_name||’’var_sal);end;/set serveroutpu ondeclaretype employee_type is record(no_number number,name_string varchar(20),sal_number number);employee employee_type;beginselect empno,ename,salinto employeefrom empwhere empno='7369';dbms_output.put(employee.no_number);dbms_output.put(''||_string);dbms_output.put(''||employee.sal_number);end;/set serveroutput ondeclarerow_employee emp%rowtype;beginselect *into row_employeefrom empwhere empno=’7499’;dbms_output.put(row_employee.empno||’’);dbms_output.put((row_employee.empename||’’);dbms_output.put((row_employee.job||’’);dbms_output.putline(row_employee.sal);end;/2、练习使用基本流程控制语句编写PL/SQL代码完成指定的数据处理功能。
实验4 PL/SQL高级编程开发语言及实现平台或实验环境:Oracle 10g实践目的(1) 掌握存储过程、存储函数、包、触发器高级数据库对象的基本作用。
(2) 掌握存储过程、存储函数、包、触发器的建立、修改、查看、删除操作。
实验要求(1) 记录执行命令和操作过程中遇到的问题及解决方法,注意从原理上解释原因。
(2) 掌握存储过程、存储函数、包、触发器的命令。
实验内容1.创建存储过程(1) 将下列的未命名的PL/SQL,转换成存储过程,存储过程名自己设定,注意比较未命名的PL/SQL 与命名的PL/SQL 的差别,如没有where current of 是什么情况。
declarecursor emp_cursor is select * from emp where deptno=10 for update;beginfor emp_record in emp_cursor loopdbms_output.put_line(emp_record.sal);update emp set sal=sal*1.1 where current of emp_cursor;end loop;end;/(2)(3)任选一个(2) 创建存储过程“dept_count_pro”,通过传入参数传入部门号deptno(如10),显示员工表“emp”中不同部门的员工人数,并执行该存储过程。
(3) 创建存储过程“num_pro”,通过传入参数传入3个数,完成3 个数的从小到大排序,通过 3 个传出参数保存排序后的 3 个数,并执行该存储过程,显示排序结果。
2.查看存储过程(1) 利用SQL*Plus 或iSQL*Plus 从user_source 数据字典中查看存储过程。
3.删除存储过程(1) 利用SQL*Plus或iSQL*Plus删除某个存储过程。
4.创建函数(1) 创建存储函数“emp_fun”,通过传入参数传入员工的编号,根据传入的员工编号,检查该员工是否存在。
《PL/SQL编程》/*procedural language/sql*/--1、过程、函数、触发器是pl/sql编写的--2、过程、函数、触发器是在oracle中的--3、pl/sql是非常强大的数据库过程语言--4、过程、函数可以在java程序中调用--提高效率:优化sql语句或写存储过程--pl/sql移植性不好--IDE(Integration Develop Environment)集成开发环境--命令规则:--变量(variable) v_--常量(constant) c_--指针、游标(cursor) _cursor--例外、异常(exception) e_--可定义的变量和常量:--标量类型:scalar--复合类型:composite --存放记录、表、嵌套表、varray --参照类型:reference--lob(large object)《PL/SQL 基本语法》--例:创建存储过程create or replace procedure pro_addisbegininsert into mytest values('韩xx','123');end;exec pro_add; --调用--查看错误信息show error;--调用过程exec 过程(c1,c2,...);call 过程(c1,c2,...);--打开/关闭输出选项set serveroutput on/off--输入&--块结构示意图declare --定义部分,定义常量、变量、游标、例外、复杂数据类型begin --执行部分,执行pl/sql语句和sql语句exception --例外处理部分,处理运行的各种错误end; --结束--《实例演示》declarev_ival number(4) :=100; --声明并初始化变量--v_dtm date;v_dtm syslogs.dtm%type; --取表字段类型v_content varchar(512);beginv_ival := v_ival * 90; --赋值运算insert into syslogs values(seq_syslogs.nextval,10,sysdate,'v_ival='||v_ival,user);--数据库存储dbms_output.put_line('v_ival'||v_ival);select count(*) into v_ival from syslogs;--使用select查询赋值--select ename,sal into v_name,v_sal from emp where empno=&aa;insert into syslogs values (seq_syslogs.nextval,10,sysdate,'日志条数='||v_ival,user); dbms_output.put_line('日志条数'||v_ival);--获取日志序号==11的日志时间和日志内容select dtm , contentinto v_dtm,v_contentfrom syslogswhere logid=14;insert into syslogs values(seq_syslogs.nextval,'10',sysdate,'v_dtm='||v_dtm||'v_content='||v_content,user); dbms_output.put_line('v_dtm='||v_dtm||'v_content='||v_content);--修改日志序号=11的日志记录人update syslogsset whois='PL/SQL.'||v_ivalwhere logid = 14;--delete syslogs where logid=15;--分支流程控制if v_ival>50 thendbms_output.put_line('日志需要清理了~');elsedbms_output.put_line('日志空间正常!');end if;--Loop循环v_ival :=0;loopexit when v_ival>3;--循环体v_ival := v_ival+1;dbms_output.put_line('loop循环:'||v_ival);end loop;--While循环v_ival := 0;while v_ival < 4loop--循环体v_ival := v_ival+1;dbms_output.put_line('while循环:'||v_ival);end loop;--For循环for v_count in reverse 0..4 loop --reverse递减dbms_output.put_line('for循环:'||v_count);end loop;commit;--提交事物end;select * from syslogs;《PL/SQL 异常处理》--PL/SQL异常处理:oracle内置异常,oracle用户自定义异常declarev_title logtypes.tid%type;v_ival number(9,2);--自定义的异常ex_lesszero exception ;begin--select title into v_title--from logtypes --; too_many_rows--where tid = 30 ; --NO_DATA_FOUND 异常v_ival := 12/-3;if v_ival < 0 then--直接抛出异常--raise ex_lesszero ;--使用系统存储过程抛出异常raise_application_error(/*错误代码,-20000~-20999*/-20003,/*异常描述*/'参数不能小于0!');end if;commit;exception--异常处理代码块when no_data_found thendbms_output.put_line('发生系统异常:未找到有效的数据!');when too_many_rows thendbms_output.put_line('发生系统异常:查询结果超出预期的一行!');when ex_lesszero thendbms_output.put_line('发生用户异常:数值不能为负!'||sqlcode||'异常描述:'||sqlerrm);when others then --other例如Exceptionrollback;dbms_output.put_line('发生异常!'||sqlcode||'异常的描述:'||sqlerrm);end;《PL/SQL 游标的使用》declare--游标的声明cursor myCur isselect tid,title from logtypes ;--定义接收游标中的数据变量v_tid logtypes.tid%type;v_title logtypes.title%type;--通过记录来接受数据v_typercd myCur%rowtype ;begin--打开游标open myCur ;--取游标中的数据loop--遍历游标中的下一行数据fetch myCur into v_tid,v_title ;--检测是否已经达到最后一行exit when myCur%notfound ;--输出游标中的数据dbms_output.put_line('读取tid='||v_tid||' title='||v_title);end loop;--关闭游标close myCur;--打开游标open myCur ;loopfetch myCur into v_typercd ;exit when myCur%notfound ;dbms_output.put_line('--//读取tid='||v_typercd.tid||' title='||v_typercd.title);end loop;--关闭游标close myCur ;--for循环游标for tmp_record in myCur loopdbms_output.put_line('++//读取tid='||tmp_record.tid||' title='||tmp_record.title);end loop;end;《PL/SQL 存储过程★》-- 可以声明入参in,out表示出参,但是无返回值。
实验五PL/SQL编程语言的使用与程序设计【开发语言及实现平台或实验环境】Oracle10g【实验目的】(1)了解PL/SQL在Oracle中的基本概念;(2)掌握PL/SQL的各组成部分;(3)PL/SQL的运用。
【实验原理】1.PL/SQL字符集和所有其他程序设计语言一样,PL/SQL也有一字符集。
读者能从键盘上输入的字符集是PL/SQL的字符。
此外,在某些场合,还有使用某些字符的规定。
我们将要详细介绍:●用PL/SQL编程时可能使用的字符●算术运算符●关系运算符●杂符号1)合法字符用PL/SQL程序时,允许使用下列字符:●所有大、小写字母●数字0到9●符号:()+-*/〈〉=!~;:.‘@ %,“# $ ^ & _ | { } ?[ ]2)算术运算符下面列出了PL/SQL中常用的算术运算符。
如果读者使用过其他高级程序设计语言,想必不会陌生:表6 算术运算符运算符意义+ 加法- 减法* 乘法/ 除法** 幂关系运算符下面列出了PL/SQL中常用的关系运算符。
如果读者有使用其他程序设计语言的经验,一定见过这些符号:表7 关系运算符运算符意义<> 不等于!= 不等于^= 不等于< 小于> 大于= 等于3)杂符号PL/SQL为支持编程,还使用下述符号。
下面列出了部分符号,它们是最常用的,也是使用PL/SQL的所有读者都必须了解的。
表8 杂符号4)变量变量是PL/SQL中用来处理数据项所用的名字。
读者根据下列规则选择变量名称:●变量必须以字母(A~Z)开头。
●其后跟可选的一个或多个字母,数字(0~9)或特殊字符$、# 或_。
●变量长度不超过30个字符。
●变量名中不能有空格。
5)保留字保留字可视为PL/SQL版权所有的字符串。
在定义变量名时,读者不能使用这些保留字。
例如,词“loop”在PL/SQL中有特殊含义,因此下列代码是非法的:declareemployee varchar2(30);loop number;保留字不能用作变量名。
Oracle PL/SQL高级编程编者语:作者对Oracle开发管理有多年的经验,并在Oracle 数据库的基础上开发了自己的交易控制中间件,适用于金融、电信、交通等多个行业,现就主要开发资料参考资料共享给大家。
祝大家在Oracle平台上更上一层楼,共同进步。
Yangyb123@ 2006-2-14第一章集合 (3)1.1 索引表 (3)1.1.1 定义索引表 (3)1.1.2 将条目插入到索引表中 (3)1.1.3 对索引表中进行操作 (3)1.1.4 索引表中的函数 (4)1.2 嵌套表 (4)1.2.1 初始化嵌套表 (4)1.2.2 扩展嵌套表 (5)1.2.3 删除嵌套表中的条目 (5)1.3 变长数组 (6)1.3.1 定义变长数组 (6)1.3.2 扩展变长数组 (6)1.4 批绑定 (6)1.5 集合的异常处理 (7)第二章触发器 (7)2.1 触发器的创建 (7)2.2 触发器的管理 (7)2.3 触发器的新功能 (9)2.4 替代触发器 (11)2.5 触发器的局限性 (11)第三章对象 (11)3.1 对象的定义 (11)3.2 对象的存贮和检索 (12)第四章调试 (13)4.1 编写DEBUG程序包(例程) (13)4.2 调用函数 (13)第五章大对象类型 (14)5.1 大对象数据类型 (14)5.2 在Oracle8i数据库中使用外部文件: (15)5.3 DBMS_LOB 包 (15)5.3.1 函数说明 (15)5.3.2 应用举例 (18)5.3.3 内部 LOB 的函数和过程 (19)5.3.4 内部 LOB 的函数和过程的应用举例 (23)5.3.5 临时 LOB (23)第六章管理事务和锁定 (24)6.1 事务 (24)6.2 锁定 (25)第七章动态SQL (28)7.1 DBMS_SQL 程序包 (28)7.2 本机动态SQL (28)7.2.1 执行 DDL 语句 (28)7.2.2 使用绑定变量 (29)7.2.3 执行 PL/SQL 块 (29)第八章显示数据 (29)8.1 DBMS_OUTPUT 程序包 (29)8.1.1 开启屏幕显示 (30)8.1.2 关闭屏幕显示 (30)8.1.3 其他函数 (30)8.1.4 引发的异常 (30)8.2 UTL_FILE 程序包 (30)8.2.1 概述 (30)8.2.2 函数描述 (31)8.2.3 例程 (33)8.3 TEXT_IO 程序包 (34)第九章管理数据作业 (34)9.1 DBMS_JOB 包 (34)9.2 使用后台进程 (34)9.3 执行作业 (35)9.3.1 使用SUBMIT 将作业提交给作业队列 (35)9.3.2 使用RUN立即执行作业: (36)9.3.3 作业环境 (36)9.4 查看作业 (36)9.4.1 DBA_JOBS 视图的结构 (37)9.4.2 DBA_JOBS_RUNNING 视图的结构: (37)9.5 管理作业 (37)9.5.1 删除作业 (37)9.5.2 修改作业 (37)9.5.3 导入和导出作业 (38)9.5.4 处理损坏的作业 (38)9.5.5 例程 (38)第十章过程通信 (40)10.1 报警(DBMS_ALERT程序包) (40)10.1.1 建立报警的次序 (40)10.1.2 函数应用和说明 (40)10.1.3 应用举例 (42)10.2 DBMS_PIPE 程序包 (42)10.2.1 公有管道和私有管道 (43)10.2.2 使用管道 (43)10.2.3 DBMS_PIPE包的函数 (43)10.2.4 例程 (46)10.3 DBMS_ALERT 与 DBMS_PIPE 的比较 (47)第十一章 PL/SQL 和 JAVA (48)11.1 Oracle JAVA (48)11.2 装载、应用、删除JAVA (50)第一章集合1.1 索引表索引表是将数据保存在内存中!!!1.1.1 定义索引表-- 定义记录集TYPE yang_rec IS RECORD( ename varchar2(30), eid NUMBER );-- 定义索引表类型TYPE yang_tab IS TABLE OF yang_rec INDEX BY BINARY_INTEGER;-- 定义索引表对象的实例test_tab yang_tab;1.1.2 将条目插入到索引表中索引表中的每个元素都由一个唯一的整型值(索引)标识。
实验4 PL/SQL高级编程开发语言及实现平台或实验环境:Oracle 10g实践目的(1) 掌握存储过程、存储函数、包、触发器高级数据库对象的基本作用。
(2) 掌握存储过程、存储函数、包、触发器的建立、修改、查看、删除操作。
实验要求(1) 记录执行命令和操作过程中遇到的问题及解决方法,注意从原理上解释原因。
(2) 掌握存储过程、存储函数、包、触发器的命令。
实验内容1.创建存储过程(1) 将下列的未命名的PL/SQL,转换成存储过程,存储过程名自己设定,注意比较未命名的PL/SQL 与命名的PL/SQL 的差别,如没有where current of 是什么情况。
declarecursor emp_cursor is select * from emp where deptno=10 for update;beginfor emp_record in emp_cursor loopdbms_output.put_line(emp_record.sal);update emp set sal=sal*1.1 where current of emp_cursor;end loop;end;/(2)(3)任选一个(2) 创建存储过程“dept_count_pro”,通过传入参数传入部门号deptno(如10),显示员工表“emp”中不同部门的员工人数,并执行该存储过程。
(3) 创建存储过程“num_pro”,通过传入参数传入3个数,完成3 个数的从小到大排序,通过 3 个传出参数保存排序后的 3 个数,并执行该存储过程,显示排序结果。
2.查看存储过程(1) 利用SQL*Plus 或iSQL*Plus 从user_source 数据字典中查看存储过程。
3.删除存储过程(1) 利用SQL*Plus或iSQL*Plus删除某个存储过程。
4.创建函数(1) 创建存储函数“emp_fun”,通过传入参数传入员工的编号,根据传入的员工编号,检查该员工是否存在。
如果存在,则返回员工的姓名,否则返回“此员工不存在“,并执行该存储函数。
(2) 创建存储函数“dept_count_fun”,利用传入参数传入部门号(如10),返回员工表“emp”中不同部门的员工人数,并执行该存储函数,注意比较与存储过程“dept_count_pro”的差别。
5.查看存储函数(1) 从user_source 数据字典中查看存储函数。
6.删除存储函数(1) 删除存储函数“dept_count_fun”。
7.创建触发器(1)新建一个部门平均工资表,编写触发器实现当雇员表中新增、删除数据或者修改工资时,重新统计各部门平均工资。
create table avg_sal(deptno ,avg_s )as select deptno,avg(sal) from emp group by deptno;参考代码:create or replace trigger dml_aafter insert or delete or update on abeginif inserting theninsert into mylog values(user,sysdate,'I');elsif deleting theninsert into mylog values(user,sysdate,'D');elseinsert into mylog values(user,sysdate,'U');end if;end;(2)创建一个替代触发器,通过更新视图来更新基本表(如向通过向视图插入一条记录,来实现对部门表和员工表插入数据的操作。
create view emp_dept (empno,ename,deptno,dname)as select empno,ename,dept.deptno,dnamefrom emp,deptwhere dept.deptno=emp.deptno;参考代码:create or replace trigger tr_v_e_dinstead of insert on emp_deptfor each rowbegin触发体;end;/(3)(4)选做一个create or replace trigger del_deptidafter delete on deptfor each rowbegindelete from emp where deptno=:old.deptno;end del_deptid;/(3) 利用SQL*Plus或iSQL*Plus创建行级触发器“update_row_tri”,当dept 表的某一“deptno”值更改时,emp表中对应的“deptno”值也跟着进行相应的更改。
更改“dept”表的某一“deptno”值,查看“emp”表中对应的“deptno”值是否发生变化。
(4) 利用SQL*Plus 或iSQL*Plus 创建语句级触发器“delete_tri”,当删除dept表中某个部门编号时,将就emp表中该员工的所有信息一并删除。
删除“dept”表中某个员工的信息,查看“emp”表是否还有该部门员工的信息。
8.查看触发器(1) 从user_triggers 数据字典中查看触发器。
9.删除触发器(1) 删除触发器“delete_tri”。
10.包(1) 创建一个包,包体中包括上面创建过的一个过程,一个函数。
(2)创建一个包体。
(3)执行包。
(4)删除刚才建立的包名和包体。
DROP PACKAGE BODY 包名;DROP PACKAGE 包名;常见问题分析1.创建或修改存储过程/存储函数时出现“名称已由现有对象使用”,创建或修改触发器时出现触发器“XXX”已经存在数据库中已存在同名对象,修改数据库对象名称或在“CREATE”关键字后加上“ORREPLACE”即可。
2.查看数据字典信息时,SELECT 命令正确,却查不到数据虽然Oracle 的命令中是不区分大小写的,但查看Oracle 系统数据字典信息时所有的字母均需大写,即便是用户定义的表名。
例如,正确的命令是:SELECT * FROM DBA_SOURCE WHERE NAME='CSMONEY1_PRO';错误的命令是:SELECT * FROM DBA_SOURCE WHERE NAME='csmoney1_pro';3.定义相冲突功能的触发器时会出错,如定义两个触发器,都是对于同一个表,当更新被参照表时,参照表一个触发器是级联置空,一个是触发器是级联删除,则触发器在执行时会报错。
是触发器只能完成不冲突的动作。
4.利用存储过程/触发器增强参照完整性约束参照完整性是指若两个表之间具有父子关系,当删除父表数据时,必须确保相关的子表数据已经被删除;当修改父表的主键列数据时,必须确保相关子表数据已经被修改。
为了实现级联删除,可以在定义外键约束时指定ON DELETE CASCADE 关键字,或是创建存储过程/触发器完成,但使用约束却不能实现级联更新,此时需要使用存储过程/触发器增强参照完整性约束。
如果在级联更新的同时又想接收参数,那么只能使用存储过程了。
5.如何在Oracle中实现类似自动增加ID的功能Oracle本身并未提供像Access中的自动编号类型,但同样也可以实现类似自动增加ID的功能,即字段值自动增长并自动插入到字段中,这时需要借助序列和触发器共同来实现。
例如,水果表“fruit”中有两个字段“num”、“name”,分别记录序号和水果的名称,第一个字段值随着第二个字段值的插入自动按顺序添加并插入。
CREATE TABLE fruit( num V ARCHAR2(10) PRIMARY KEY,name V ARCHAR2(10));首先,创建一个序列NUM。
CREATE SEQUENCE numINCREMENT BY 1START WITH 1 MAXV ALUE 9999 MINV ALUE 1NOCYCLECACHE 20ORDER;其次,创建一个触发器。
CREATE TRIGGER fruit_triBEFORE INSERT ON fruitFOR EACH ROWBEGINSELECT TO_CHAR(NUM.nextval) INTO :NEW.num FROM DUAL;//将序列的下一个取值存储到fruit 表中的“name”字段,DUAL 为系统表END;插入新记录后再查看“fruit”表中的现有记录。
INSERT INTO fruit(name) V ALUES(‘菠萝’);SELECT * FROM fruit;6.函数执行几种方法:1)Select function_name (参数) from dual;2)varible 变量类型(长度);exec :变量:= function_name (参数) ;print 变量;(或者为select :变量from dual)7.存储过程执行几种方法1)exec procedure_name(parameter_value)2)call procedure_name(parameter_value)2)beginprocedure_name(parameter_value);end3)带有输出参数的过程执行varible 变量类型(长度);exec procedure_name(parameter_value,:变量); print 变量;(或者为select :变量from dual)。