实验3PLSQL编程
- 格式:docx
- 大小:158.22 KB
- 文档页数:16
Oracle数据库基础实验5 PL/SQL游标、过程、函数、包的使用【实验学时】2学时【实验目的】1.了解PL/SQL语言中显式游标和隐式游标的概念和属性。
2.了解显式游标和隐式游标的差异。
3.掌握PL/SQL中cursor for循环的使用方法。
4.学会在PL/SQL程序中使用游标来解决实际问题。
5.学会在PL/SQL程序中进行异常处理的方法。
6.练习在PL/SQL中自定义异常。
7.理解过程和函数的作用。
8.学会编写过程、函数、包,并加以调用。
【实验内容】1.用显式游标编写程序,程序的功能是:计算每一个部门的平均工资。
注意异常的处理(例如,分母为0的异常)。
已写入文件afiedt.buf1 declare2 cursor c_dept is select * from dept order by deptno;3 cursor c_emp(p_dept emp.deptno%type)is selectename,sal from emp where deptno=p_dept4 order by ename;5 r_dept dept%rowtype;6 v_ename emp.ename%type;7 v_salary emp.sal%type;8 v_tot_salary emp.sal%type;9 begin10 open c_dept;11 loop12 fetch c_dept into r_dept;13 exit when c_dept%notfound;14dbms_output.put_line('department:'||r_dept.deptno||'-'||r_dept.dname);15 v_tot_salary:=0;16 open c_emp(r_dept.deptno);17 loop18 fetch c_emp into v_ename,v_salary;19 exit when c_emp%notfound;20dbms_output.put_line('name:'||v_ename||'salary:'||v_salary);21 v_tot_salary:=v_tot_salary+v_salary;22 end loop;23 close c_emp;24 dbms_output.put_line('total salary fordept:'||v_tot_salary);25 end loop;26 close c_dept;27* end;SQL> /PL/SQL 过程已成功完成。
西安邮电大学(计算机学院)课内实验报告实验:PL/SQL编程实验课程:大型数据库系统班级:学号:学生姓名:任课教师:一、实验目的(1)了解PL/SQL语言的结构。
(2)了解PL/SQL变量和常量的声明和使用方法。
(3)学习条件语句的使用方法。
(4)学习分支语句的使用方法。
(5)学习循环语句的使用方法。
(6)学习使用Oracle系统函数。
二、实验内容(1)练习条件语句的使用方法。
(2)练习分支语句的使用方法。
(3)练习循环语句的使用方法。
(4)练习使用Oracle系统函数。
三、实验前准备首先要了解PL/SQL语言是结构化程序设计语言。
块(Block)是PL/SQL程序中最基本的结构,所有PL/SQL程序都是由块组成的。
PL/SQL的块由变量声明、程序代码和异常处理代码3部分组成。
在PL/SQL中,常量和变量在使用前必须声明,可以使用DECLARE对变量进行声明。
四、实验步骤1.使用条件语句条件语句格式:IF <条件表达式> THEN<执行语句> …… <执行语句n>[ELSIF <条件表达式> THEN<执行语句> …… <执行语句n>……ELSE<执行语句>]END IF;执行下列程序,观察结果:SET ServerOutput ON;DECLARENum INTEGER := -11;BEGINIF Num < 0 THENdbms_output.put_line('负数');ELSIF Num >0 THENdbms_output.put_line('正数');ELSEdbms_output.put_line('0');END IF;END;2.使用分支语句分支语句格式:CASE <变量>WHEN <表达式1> THEN 值1WHEN <表达式2> THEN 值2……WHEN <表达式n> THEN 值nELSE 值n + 1END;执行下列程序,观察结果:SET ServerOutput ON;DECLAREvarDAY INTEGER := 3;Result VARCHAR2(20);BEGINResult := CASE varDAYWHEN 1 THEN '星期一'WHEN 2 THEN '星期二'WHEN 3 THEN '星期三'WHEN 4 THEN '星期四'WHEN 5 THEN '星期五'WHEN 6 THEN '星期六'WHEN 7 THEN '星期七'ELSE '数据越界'END;dbms_output.put_line(Result);END;3.使用循环语句(1)循环语句格式1:LOOP<程序块1>IF <条件表达式> THENEXITEND IF<程序块2>END LOOP;执行下列程序,观察结果:SET ServerOutput ON;DECLAREv_Num INTEGER := 1;v_Sum INTEGER := 0;BEGINLOOPv_Sum := v_Sum + v_Num;dbms_output.put_line(v_Num);IF v_Num = 3 THENEXIT;END IF;dbms_output.put_line(' + ');v_Num := v_Num + 1;END LOOP;dbms_output.put_line(' = ');dbms_output.put_line(v_Sum);END;(2)循环语句格式2:LOOP<程序块1>EXIT WHEN <条件表达式><程序块2>END LOOP;执行下列程序,观察结果:SET ServerOutput ON;DECLAREv_Num INTEGER := 1;v_Sum INTEGER := 0;BEGINLOOPv_Sum := v_Sum + v_Num;dbms_output.put_line(v_Num);EXIT WHEN v_Num = 3;dbms_output.put_line(' + ');v_Num := v_Num + 1;END LOOP;dbms_output.put_line(' = ');dbms_output.put_line(v_Sum); END;(3)循环语句格式3:WHILE <条件表达式>LOOP<程序块>END LOOP;执行下列程序,观察结果:SET ServerOutput ON;DECLAREv_Num INTEGER := 1;v_Sum INTEGER := 0;BEGINWHILE v_Num <= 3LOOPv_Sum := v_Sum + v_Num;dbms_output.put_line(v_Num);IF v_Num < 3 THENdbms_output.put_line(' + ');END IF;v_Num := v_Num + 1;END LOOP;dbms_output.put_line(' = ');dbms_output.put_line(v_Sum); END;(4)循环语句格式4:FOR <循环变量> IN <初始值> ..<终止值>LOOP<程序块>END LOOP;执行下列程序,观察结果:SET ServerOutput ON;DECLAREv_Num INTEGER;v_Sum INTEGER := 0;BEGINFOR v_Num IN 1..3LOOPv_Sum := v_Sum + v_Num;dbms_output.put_line(v_Num);IF v_Num < 3 THENdbms_output.put_line(' + ');END IF;END LOOP;dbms_output.put_line(' = ');dbms_output.put_line(v_Sum);END;4.使用系统函数常用函数有:数值型函数,字符型函数,日期型函数,统计函数五、实验结果六.评价分析及心得体会通过本次试验我学会了条件语句,分支语句,及循环语句的使用方法。
第三章PL/SQL编程3.1 PL/SQL基础知识3.1.1 什么是PL/SQL一、什么是PL/SQL?结合了Oracle进程语言和结构化查询语句的一种扩编语言。
利用PL/SQL能够编写具有很多高级功能的程序,尽管通过量个SQL语句也能实现一样的功能,可是相较而言,PL/SQL具有更为明显的一些优势二、在PL/SQL块中能够利用SELECT、INSERT、UPDATE、DELETE等DML 语句、事物操纵语句和SQL函数等。
PL/SQL块不许诺直接利用CREATE、DROP或ALTER等DDL语句,但能够通过动态SQL来执行它们。
三、PL/SQL块的结构声明部份执行部份异样处置部份四、常量和变量的声明语法是什么?变量:Variable_name data_type[ (size) ] [ := init_value ];常量:Variable_name CONSTANT data_type := value;。
四、完成例如1操作步骤:1.在jbit用户下创建表employee,导入数据2. 执行语句--方式一:通过SELECT INTO给变量赋值DECLAREv_ename VARCHAR2(20);v_rate NUMBER(7,2);c_rate_incr CONSTANT NUMBER(7,2):=1.10;BEGINSELECT ename, sal* c_rate_incr INTO v_ename, v_rateFROM employeeWHERE empno='7788';添加输出显示语句,参考P81 例如2中的“DBMS_OUTPUT.PUT_LINE()”语句DBMS_OUTPUT.PUT_LINE('姓名:'||v_ename||'工资:'||v_rate);END;显示结果图:(请截图)--方式二:通过赋值操作符“:=”给变量赋值DECLAREv_ename VARCHAR2(20);v_rate NUMBER(7,2);c_rate_incr CONSTANT NUMBER(7,2):=1.10;BEGINv_ename:='SCOTT';DBMS_OUTPUT.PUT_LINE('姓名:'||v_ename);END;显示结果图:(请截图)3.1.2 PL/SQL数据类型一、PL/SQL支持哪两种属性类型?请详细说明。
PL/SQL编程【实验目的】1.熟悉PL/SQL的数据类型和书写规则2.熟悉控制结构和游标的使用3.编写和运行函数、过程和触发器【实验内容】编写脚本文件,调试运行脚本文件,并记录结果。
1.在SQL*Plus中编写一个PL/SQL块,功能用于打印学生信息在DECLARE部分完成:(1)建立学生信息记录类型stu_record_type,包括学号,姓名,性别,籍贯,学习成绩和活动成绩。
均为可变长字符类型(2)编写本地子过程:学生信息打印过程PrintStuRecord,把(1)中定义的记录类型作为参数(3)定义学生信息记录变量stu_record在BEGIN…END部分完成:(1)为stu_record变量的各个元素赋值如下:学号:‘2001001’姓名:’李新’性别:‘m’籍贯:‘黑龙江省哈尔滨市’学习成绩:‘Excellent’活动成绩:‘Good’(2)对该变量的调用打印过程,输出到屏幕2.建立对bookinfo表的DML触发器,一旦bookinfo表发生了任何变化,立即触发,对bookinfo表的数据进行统计,结果存储在数据统计表中(1)如果没有则建立bookinfo表,选择建立在scott用户下,表结构为(bookno varchar2(36) Primary key,bookname varchar2(40) not null,authorname varchar2(10) not null,publishtime date,bookprice float)(2)建立数据统计表major_stats,包含两个字段:书的总数和作者的总数(3)创建触发器UpdateMajorStats,完成在bookinfo表中插入、删除和修改记录之后,对bookinfo表进行统计,结果存储在(2)建立的major_stats表中(4)在bookinfo表中插入、删除和更新信息,再查看major_stats表中数据的变化【实验结论】编写脚本文件,调试运行脚本文件,并记录结果。
Oracle数据库管理与开发I实验报告系所:专业:学生姓名:学生学号:提交日期:大连东软信息学院Dalian Neusoft University of Information[实验名称]:利用PLSQL进行系统功能模块的开发[实验日期]:[实验目的]:掌握PL/SQL程序设计[实验要求]:按要求利用PL/SQL进行功能模块开发[实验步骤描述]:1.编写一个PL/SQL块,输出所有员工的员工姓名、员工号、工资和部门号。
declarecursor c_emp isselect * from employees;beginfor v_emp in c_emp loopdbms_output.put_line(v_emp.first_name||'' ||v_emp.employee_id||' '||v_emp.department_id||' '||v_emp.salary);endloop; end;2.编写一个PL/SQL块,输出所有比本部门平均工资高的员工信息。
declarev_avg employees.salary%type;beginfor v_emp in (select * from employees) loopselectavg(salary) into v_avg from employees where department_id = v_emp.department_id;if v_emp.salary >= v_avg thendbms_output.put_line(v_emp.employee_id||''||v_emp.first_name||''|| v_emp.salary ||''|| v_emp.department_id); endif;endloop;end;3.写一个PL/SQL块,输出所有员工及其部门领导的姓名、员工号及部门号。
实验三PL/SQL编程基础开发语言及实现平台或实环境Oracle 11g实验目的(1) 掌握PL/SQL 块结构、PL/SQL 的基本语法、PL/SQL 的控制结构。
(2) 掌握PL/SQL 块中使用复合数据类型。
(3) 掌握PL/SQL 异常处理技术。
实验要求(1) 记录执行命令和操作过程中遇到的问题及解决方法,注意从原理上解释原因。
(2) 记录利用SQL*Plus或iSQL*Plus编写、执行PL/SQL 程序的命令。
实验内容运行1.2.3中的程序,查看运行结果,体会pl/sql语句的语法结构和运行结果。
完成4.5.6.及7.8中任选一个中的代码的编写。
1 利用LOOP 循环方式计算1+3+5+7+9。
代码如下:SET SERVEROUTPUT ONDECLAREi NUMBER;sum1 NUMBER;BEGINi:=1;sum1:=0;LOOPIF mod(i,2)!=0 THENsum1:=sum1+i;END IF;i:=i+1;IF(i>9) THENEXIT;END IF;END LOOP;DBMS_OUTPUT.PUT_LINE(sum1);END;2.利用记录类型将emp表的某条信息显示出来。
代码如下:SET SERVEROUTPUT ONDECLAREE_name emp.ename%type;E_no emp.empno%type;E_sal emp.sal%type;E_deptno emp.deptno%type;E_hiredate emp.hiredate%type;BEGINselect empno,ename,hiredate,sal,deptno INTO E_no,E_name,E_ hiredate,E_sal , E_deptno FROM emp WHERE empno='7788';DBMS_OUTPUT.PUT_LINE(E_no||E_name || E_hiredate || E_sal || E_deptno);end;/请利用%rowTYPE重做本例,注意三者的差别。
实验1SQL*Plus的使用和基本SELECT语句实验要求(1)掌握SQL*Plus的基本使用(2)掌握SELECT语句的简单用法。
实验条件自我实践实验时间大约60分钟1.练习1 FOLLOW ME●时间20分钟●实验步骤(1)观看第1章教学视频。
(2)实践视频中的实例。
2.练习2●时间40分钟●实验步骤(1)登录到SQL*Plus,初始用户名为:SCOTT,口令为TIGER。
(2)分别显示EMP、DETP、SALGRADE表结构,并察看表中的数据。
(3)创建一个查询显示每个雇员的姓名、工作、受雇日期及雇员编号,并且要将雇员编号作为第一列显示。
最后将该SQL语句保存成文件p1q1.sql,并执行该脚本文件。
(4)将脚本文件p1q1.sql调取到SQL缓冲区,并将列标题设置为Emp #,Employee,Job及Hire Date,将该SQL语句保存成文件p1q2.sql,最后返回查询结果。
思考练习题1.SQL*Plus命令是用于访问数据库的吗?2.下面的SELECT语句能成功执行吗?SQL>SELECT ename,job,sal Salary2FROM emp;3.下面的语句有3处错误,请纠正它们。
SQL>SELECT empno,ename2Salary x 12 ANNUAL SALARY3FROM emp;4.创建一个查询从EMP表中检索出不重复的工作名称。
5.用一个逗号和一个空格将姓名和工作连接后作为一个整体输出,显示的列标题为Employee and Title。
6.创建一个查询,用逗号将表中所有字段的信息连接作为一个整体输出,输出的列标题为THE_OUTPUT。
实验2使用WHERE和ORDER BY子句实验要求(1)掌握WHERE子句的用法。
(2)掌握ORDER BY子句的用法。
实验条件自我实践实验时间大约60分钟1.练习1FOLLOW ME●时间20分钟●实验步骤(1)观看第2章教学视频。
实验三PL/SQL 编程课前准备:导入hr。
一、实验目的1、了解 PL/SQL 块结构、程序结构2、掌握各种类型变量的使用3、掌握 For 游标的使用4、掌握异常的使用二、实验内容1、块结构练习,分析块结构及下列语句含义declaregrade varchar2(10);BEGINCASE gradeWHEN 'A' THEN DBMS_OUTPUT.PUT_LINE('ABC');WHEN 'B' THEN DBMS_OUTPUT.PUT_LINE ('优秀');WHEN 'C' THEN DBMS_OUTPUT.PUT_LINE ('良好');WHEN 'D' THEN DBMS_OUTPUT.PUT_LINE ('一般');WHEN 'F' THEN DBMS_OUTPUT.PUT_LINE ('较差');ELSE DBMS_OUTPUT.PUT_LINE ('没有此成绩');END CASE;END;注意:在PL SQLDeveloper或SQL*Plus中,希望结果输出到屏幕,在执行DBMS_OUTPUT.PUT 前需要事先执行:Set serveroutput on2、各种类型变量的使用(6.7 实验指导p140 的1.(1),1.(2),1.(4))(1)declarevar_sal number:=2200;BEGINupdate employees set salary=var_sal where employee_id=’203’;END;注意:变量类型;执行PLSQL块前后,查询203工号员工的工资(2)%type 类型变量declarevar_first_name employees.first_name%type;var_last_name st_name%type;BEGINselect first_name,last_name into var_first_name,var_last_name from employeeswhere employee_id=199;dbms_output.put_line(var_first_name || ' ' || 'var_last_name'); END;注意:变量类型;赋值语句的使用方式(3)%rowtype 类型变量declarevar_emp employees%rowtype; --rowtype变量BEGINselect * into var_empfrom employeeswhere employee_id=199;dbms_output.put_line(var_emp.employee_id);dbms_output.put_line(var_st_name);dbms_output.put_line(var_emp.first_name);dbms_output.put_line(var_emp.job_id);dbms_output.put_line(var_emp.salary);END;3、使用游标(1)、6.7 实验指导p142 的 2.(2),并改为用游标For 循环实现,分析如何使用游标For 循环如对游标进行处理declarecursor emp_cur isselect * from employees;emp_one employees%rowtype;beginfor r in emp_cur loopdbms_output.put_line(emp_one.employee_id || ‘‘); dbms_output.put_line(emp_st_name || ‘‘); dbms_output.put_line(emp_one.job_id || ‘‘); dbms_output.put_line(null);dbms_output.put_line(‘ **************’);end loop;end;(2)、关于隐式游标,分析以下语句,写出执行结果beginupdate employees set salary=1200 where employee_id=7369;if sql%notfound thendbms_output.put_line('未更新任何记录');elsedbms_output.put_line('更新' || sql%rowcount || '条记录');end if;end; /(3)运用隐式游标的属性,写出PL/SQL 块实现下列功能:维护表DEPT 的一条记录:如果表中有DeptNo=10 的记录,则将其LOC 更新为‘福州’,否则插入新记录DeptNo=10,参考:beginupdate DEPT set LOC=‘福州’where DeptNo=’10’;if sql%notfound thendbms_output.put_line('未更新任何记录');elsedbms_output.put_line('更新' || sql%rowcount || '条记录');end if;end;4、使用异常(1)、在SQL*Plus 中输入以下PL/SQL 块,分析结果,并说明预定义异常的使用方法begininsert into scott.emp(empno,empname,job,sal,deptno)values(7369,'Clare','CLERK',1500,20);exceptionwhen dup_val_on_index thendbms_output.put_line('捕获DUP_VAL_ON_INDEX异常');dbms_output.put_line('该主键已经存在');end;分析结果:如果用户试图使用完全相同的主键值向同一个表中插入两条记录,这会因为违反系统主键约束产生错误。
Oracle数据库基础实验4 PL/SQL块结构,条件、循环语句的使用【实验学时】2学时【实验目的】1.学习匿名PL/SQL块的基本结构。
2.了解PL/SQL的基本数据类型。
3.掌握PL/SQL中变量和常量的定义方法。
4.学会在PL/SQL程序中使用复合数据类型:记录和集合。
5.学会使用select…into…语句返回一行数据。
6.练习在PL/SQL中使用DML语句和动态SQL语句。
7.熟练掌握PL/SQL中的选择和循环语句的使用。
【实验内容】1.定义一个PL/SQL块,向屏幕输出hello world!。
SQL> ed已写入文件afiedt.buf1 declare2 begin3 dbms_output.put_line('hello,world');4 exception5 when others then6 dbms_output.put_line('error');7 raise;8* end;SQL> /hello,worldPL/SQL 过程已成功完成。
2.定义一个PL/SQL块,将输入的字符串中大小写相互转换后向屏幕输出。
例如,输入abDCe,输出ABdcESQL> ed已写入文件afiedt.buf1 declare2 str1 varchar2(20):='&str1';3 str2 varchar2(2);4 str3 varchar2(20);5 len number(10);6 leng number(10);7 begin8 len:=1;9 leng:=length(str1);10 while len<=leng loop11 str2:=substr(str1,len,1);12 if str2>='a' and str2<='z' then13 str3:=str3||upper(str2);14 elsif str2>='A' and str2<='Z' then15 str3:=str3||lower(str2);16 end if;17 len:=len+1;18 end loop;19 dbms_output.put_line(str3);20* end;SQL> /输入str1 的值: ehhrfEdsd原值2: str1 varchar2(20):='&str1';新值2: str1 varchar2(20):='ehhrfEdsd';EHHRFeDSDPL/SQL 过程已成功完成。
广东技术师范学院实验报告学院: 计算机科学学院 专业: 计算机科学与技术(师资)班级: 成绩:姓名: 孔哥哥 学号: 组别: 组员: 实验地点: Win10电脑 实验日期: 指导教师签名:实验名称: 实验三:PL/SQL 程序块简单应用一、 实验目的:a)通过独立完成实验报告,让学生掌握以下技能: b)掌握SQL 的基本操作c)掌握简单PL/SQL 程序块的编写二、实验内容:a)建立表、索引、视图、同义词 b)对数据进行插入操作 c)编写一个PL/SQL 块三、实验步骤:a)启动SQL*PLUS ,以SCOTT 模式连接到数据库;b) 创建社保信息表,包含员工号、员工姓名、部门,工资,雇佣日期,社保缴费基数,月社保费等字段。
c)编写PL/SQL程序块ShowInfo,给定一个员工号就可以显示其姓名、性别等信息,如果该员工不存在则显示‘对不起,没有此员工!’d)编写PL/SQL程序块processInfo,对员工岗位进行判断,决定缴费基数,计算社保费,写入数据库中。
注意:社保缴费工资与实际工资可以不相同,社保缴费工资和每月养老保险费可以放在工资表里。
declarev_shebaojishu number(6);v_yueshebaofei number(7,2);beginfor v_emp in(select *from emp) loopcasewhen v_emp.job='CLERK' then v_shebaojishu :=2000;v_yueshebaofei :=v_emp.sal*0.07;when v_emp.job='SALESMAN' then v_shebaojishu :=3000;v_yueshebaofei :=v_emp.sal*0.08;when v_emp.job='MANAGER' then v_shebaojishu :=5000;v_yueshebaofei :=v_emp.sal*0.09;when v_emp.job='PRESIDENT' then v_shebaojishu :=7000;v_yueshebaofei :=v_emp.sal*0.11;else v_yueshebaofei :=0;end case;insert intoshebao(emp_empno,emp_ename,emp_job,emp_sal,emp_hiredate,shebaojishu,yuesheb aofei)values(v_emp.empno,v_emp.ename,v_emp.job,v_emp.sal,v_emp.hiredate,v_shebaojishu,v _yueshebaofei);end loop;end;/插入成功后输入 select * from shebao;查询是否成功写入数据库中四、实验问题及原因1.c步骤的时候没有分清%type和%rowtype以下是区别和用法:%TYPE:定义一个变量,其数据类型与已经定义的某个数据变量的类型相同,或者与数据库表的某个列的数据类型相同,这时可以使用%TYPE。
湖南文理学院实验报告课程名称大型数据库技术实验名称PL/SQL存储过程、函数成绩学生姓名专业计科16 年级、学号同组者姓名无实验日期 2018.12.03 一、实验目的:1.了解存储过程的使用方法。
2.掌握存储过程的使用方法。
二、实验要求:1. 掌握SQL Developer编译功能,使用SQL Developer完成PL/SQL命令。
2.按照业务要求创建实现特定功能的存储过程。
3.按照业务内容创建实现具有特定功能的函数。
三、实验步骤:1.打开SQLDeveloper,建立system链接、bs+学号连接登录ORCL数据库。
2.在SQLDeveloper中,用密码tiger解锁scott账号。
3. 范例1)显示所指定雇员名所在的部门名和位置。
CREATE OR REPLACE PROCEDURE DeptMesg(pename emp.ename%TYPE,pdname OUT dept.dname%TYPE,ploc OUT dept.loc%TYPE) ASBEGINSELECT dname,loc INTO pdname,plocFROM emp,deptWHERE emp.deptno=dept.deptno AND emp.ename=pename;END;/VARIABLE vdname VARCHAR2(14);VARIABLE vloc VARCHAR2(13);EXECUTE DeptMesg('SMITH',:vdname,:vloc);PRINT vdname vloc;四、实验内容:1、写存储过程1)显示所指定雇员名所在的部门名和位置。
create or replace procedure DepMesg(pname emp.ename%type,pdname out dept.dname%type.ploc out dept.loc%type)asbeginselect dname,loc into pdname.plocfrom emp,deptWhere emp.deptno=dept.deptno and emp.ename=pename;end;varchar vdname varchar(10);varchar volc varchar(10);execte deptMesg(‘Stiv’,vdname,:volc);print vdname volc;2)定义一个为修改职工表(emp)中某职工工资的存储过程子程序,职工名作为形参,若该职工名在职工表中查找不到,就在屏幕上提示“查无此人”然后结束子程序的执行;否则若工种为MANAGER的,则工资加$1000;工种为SALESMAN,工资加$500;工种为ANALYST,工资加$200,否则工资加$100。
《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编程1.PL/SQL块处理定义一个包含声明、执行和异常处理的块查询EMP表中职工号7788的工资,输出工资的值并且如果工资小于3000那么把工资更改为3000,异常部分对NO_DATA_FOUND异常进行处理,输出没有该员工。
如果想运行缓冲区的内容,那么可以用RUN命令或者/命令;serveroutput需要设置为on 2.记录类型的使用创建一个记录类型v_record,类型包含name,salary,job,deptno等分量,要求记录类型的分量的数据类型和emp表中列的数据类型一致(%type实现)。
创建一个变量,变量类型为v_ record,读取EMP表中职工号为7788的ename,sal,job,deptno为该变量赋值,输出变量的分量。
3.条件语句的使用分别用IF语句和CASE语句实现以下要求:输入一个员工号,修改该员工的工资,如果该员工职位是CLERK,工资增加100;若为SALESMAN,工资增加160;若为ANALYST,工资增加200;否则增加300。
4. 循环和显示游标的使用分别用简单循环、WHILE循环、FOR循环以及显示游标统计并输出各个部门的人数以及平均工资5.用隐式游标实现以下要求:修改部门号为50的部门地址为‘BEIJING’。
如果该部门不存在,则向dept表中插入一个部门号为50,地址为‘BEIJING’的记录。
6.创建一个显示雇员总人数的存储过程emp_count,并执行该存储过程7. 编写显示雇员信息的存储过程EMP_LIST,并引用EMP_COUNT存储过程8. 创建函数,实现功能为:在scott.emp表和scott.dept表中查询出任意给定职工号的职工姓名及职工所在部门的名称。
9. 创建触发器,实现更新dept表中的deptno值,级联更新emp表中相应值。
10. 对存储过程、函数及触发器实现查看、修改、删除等基本操作。
主要算法和程序清单:1.DECLAREv_empno emp.empno%TYPE:=7788;v_sal emp.sal%TYPE;v_add emp.sal%TYPE;BEGINSELECT sal INTO v_sal FROM emp WHERE empno=v_empno;IF v_sal<3000THEN v_add:=3000;ELSEdbms_output.put_line('sal>3000');END IF;UPDATE emp SET sal=v_add WHERE empno=v_empno;END;/2.declaretype v_record is record (name emp.ename%type,salary emp.sal%type,job emp.job%type,deptno emp.deptno%type);empinfo v_record;--定义变量beginselect ename,sal,job,deptnointo empinfofrom empwhere empno = 7788;dbms_output.put_line('雇员'||||'的职务是:'||empinfo.job||'工资是:'||empinfo.salary||'部门号是:'||empinfo.deptno);end;/3.declarecursor c_emp is select * from scott.emp for update;v_increment number;beginfor v_emp in c_emp loopcase v_emp.deptnowhen 10 then v_increment:=100;when 20 then v_increment:=160;when 30 then v_increment:=200;else v_increment:=300;end case;update scott.emp set sal = sal+v_increment where current of c_emp;end loop;end;4.5.beginupdate scott.deptset loc = 'BEIJING' where deptno=50;if sql%notfound theninsert into scott.dept(deptno,loc) values(50,'BEIJING');dbms_output.put_line('插入成功!');ELSEdbms_output.put_line('更新成共');end if;end;6.create or replace procedure emp_countas v_total number;beginselect count(*) into v_total from scott.emp;dbms_output.put_line('雇员总数:'||v_total); end;/SQL> execute emp_count;雇员总数:15PL/SQL 过程已成功完成。
PL/SQL编程实验报告班级:10网工三班学生姓名:谢昊天学号:1215134046实验目的和要求:(1) 掌握PL/SQL块结构、PL/SQL的基本语法、PL/SQL的控制结构。
(2) 掌握PL/SQL块中使用复合数据类型和游标的方法。
(3) 掌握PL/SQL异常处理技术。
(4) 掌握存储过程、存储函数、触发器高级数据库对象的基本作用。
(5) 掌握存储过程、存储函数、触发器的建立、修改、查看、删除操作。
实验内容:(1) 记录执行命令和操作过程中遇到的问题及解决方法,注意从原理上解释原因。
(2) 记录利用SQL*Plus或iSQL*Plus编写、执行PL/SQL程序的命令。
(3) 记录执行命令和操作过程中遇到的问题及解决方法,注意从原理上解释原因。
(4) 记录利用企业管理器管理存储过程、存储函数、触发器的方法。
(5) 记录利用SQL*Plus和iSQL*Plus管理存储过程、存储函数、触发器的命令。
实验步骤与调试过程:1、打开DOS命令窗口,在其中输入sqlplus system/system命令进入oracle数据库系统。
2、在SQLPLUS下输入create table business(bno char(10) primary key,bname char(50) not null,btype char(4),baddress char(20),btel char(13));,创建一个business表,3、用同样的方法新建hospital、card、staff、consume、insurance等表,使用“desc 报表名”查看表结构。
4、新建表staff_sq1,包含两列sno、sname,5、在SQLPLUS下输入alter table staff_sq1 rename to staff_sq10;,修改以表名。
6、创建基于医院名的索引,输入create index hospital_name_index on HOSPITAL(HNAME DESC);。
实验三PL/SQL编程(2)
一.根据本章课件以及本章代码2.txt,学习掌握以下内容:
异常处理\包\触发器
二.完成以下作业。
1.创建一个emp1表,其结构和数据与emp表完全一致.用游标完成操作:
在sql*plus中显示工资低于1500的职员信息,并显示如果给他们涨30%工资后的工资.
用游标变量完成以上题目,并加异常处理。
2.创建一个包,求圆的面积. 在包中定义一个全局常数pi,以及计算圆面积的函数。
3. 创建触发器:
create table std(deptno number(2),sal number(5));
insert into std values(20,2000);
std表中的信息,是部门号以及企业规定的该部门的最低工资标准。
现在要创建触发器,当在emp插入信息时,把工资低于所属部门工资标准的职员信息插入到emp1表中。
(选做)若std中的信息是部门号以及该部门的平均工资,要创建触发器,当在emp插入信息时,把工资低于所属部门平均工资的职员信息插入到emp1表中,并修改平均工资。
实验三PL/SQL编程1.PL/SQL块处理定义一个包含声明、执行和异常处理的块查询EMP表中职工号7788的工资,输出工资的值并且如果工资小于3000那么把工资更改为3000,异常部分对NO_DATA_FOUND异常进行处理,输出没有该员工。
如果想运行缓冲区的内容,那么可以用RUN命令或者/命令;serveroutput需要设置为on 2.记录类型的使用创建一个记录类型v_record,类型包含name,salary,job,deptno等分量,要求记录类型的分量的数据类型和emp表中列的数据类型一致(%type实现)。
创建一个变量,变量类型为v_record,读取EMP表中职工号为7788的ename,sal,job,deptno为该变量赋值,输出变量的分量。
3.条件语句的使用分别用IF语句和CASE语句实现以下要求:输入一个员工号,修改该员工的工资,如果该员工职位是CLERK,工资增加100;若为SALESMAN,工资增加160;若为ANALYST,工资增加200;否则增加300。
4. 循环和显示游标的使用分别用简单循环、WHILE循环、FOR循环以及显示游标统计并输出各个部门的人数以及平均工资5.用隐式游标实现以下要求:修改部门号为50的部门地址为‘BEIJING’。
如果该部门不存在,则向dept表中插入一个部门号为50,地址为‘BEIJING’的记录。
6.创建一个显示雇员总人数的存储过程emp_count,并执行该存储过程7. 编写显示雇员信息的存储过程EMP_LIST,并引用EMP_COUNT存储过程8. 创建函数,实现功能为:在scott.emp表和scott.dept表中查询出任意给定职工号的职工姓名及职工所在部门的名称。
9. 创建触发器,实现更新dept表中的deptno值,级联更新emp表中相应值。
10. 对存储过程、函数及触发器实现查看、修改、删除等基本操作。
主要算法和程序清单:1.DECLAREv_empno emp.empno%TYPE:=7788;v_sal emp.sal%TYPE;v_add emp.sal%TYPE;BEGINSELECT sal INTO v_sal FROM emp WHERE empno=v_empno;IF v_sal<3000THEN v_add:=3000;ELSEdbms_output.put_line('sal>3000');END IF;UPDATE emp SET sal=v_add WHERE empno=v_empno;END;/2.declaretype v_record is record (name emp.ename%type,salary emp.sal%type,job emp.job%type,deptno emp.deptno%type);empinfo v_record;--定义变量beginselect ename,sal,job,deptnointo empinfofrom empwhere empno = 7788;dbms_output.put_line('雇员'||||'的职务是:'||empinfo.job||'工资是:'||empinfo.salary||'部门号是:'||empinfo.deptno);end;/3.declarecursor c_emp is select * from scott.emp for update;v_increment number;beginfor v_emp in c_emp loopcase v_emp.deptnowhen 10 then v_increment:=100;when 20 then v_increment:=160;when 30 then v_increment:=200;else v_increment:=300;end case;update scott.emp set sal = sal+v_increment where current of c_emp;end loop;end;4.5.beginupdate scott.deptset loc = 'BEIJING' where deptno=50;if sql%notfound theninsert into scott.dept(deptno,loc) values(50,'BEIJING');dbms_output.put_line('插入成功!');ELSEdbms_output.put_line('更新成共');end if;end;6.create or replace procedure emp_countas v_total number;beginselect count(*) into v_total from scott.emp;dbms_output.put_line('雇员总数:'||v_total); end;/SQL> execute emp_count;雇员总数:15PL/SQL 过程已成功完成。
SQL> begin2 emp_count;3 end;4 /雇员总数:15PL/SQL 过程已成功完成。
7.1 CREATE OR REPLACE PROCEDURE EMP_LIST2 AS3 CURSOR emp_cursor IS4 SELECT empno,ename FROM scott.emp;5 BEGIN6 FOR Emp_record IN emp_cursor LOOP7 DBMS_OUTPUT.PUT_LINE(Emp_record.empno||Emp_record.ename);8 END LOOP;9 EMP_COUNT;10* END;SQL> /过程已创建。
8.SQL> CREATE OR REPLACE PROCEDURE select_emp2 (v_emp_no IN emp.empno%type)3 IS4 v_emp_name emp.ename%type;5 v_dept_name dept.dname%type;6 BEGIN7 SELECT EMP.ENAME,DEPT.DNAME8 INTO v_emp_name, v_dept_name9 FROM EMP,DEPT10 WHERE EMP.DEPTNO=DEPT.DEPTNO AND EMPNO = v_emp_no;11 DBMS_OUTPUT.PUT_LINE(v_emp_name||' '||v_dept_name);12 END select_emp;13 /过程已创建。
SQL> EXECUTE select_emp(7844);TURNER SALESPL/SQL 过程已成功完成。
SQL> CREATE OR REPLACE TRIGGER update_dept_to_emp2 AFTER UPDATE ON DEPT FOR EACH ROW3 BEGIN4 IF UPDATING THEN5 UPDATE EMP SET DEPTNO = :new.DEPTNO6 WHERE DEPTNO=:old.DEPTNO;7 END IF;8 END update_dept_to_emp;9 /触发器已创建9.CREATE OR REPLACE TRIGGER tr_reg_depAFTER update OF deptnoON deptFOR EACH ROWBEGINDBMS_OUTPUT.PUT_LINE('旧的deptno值是'||:old.deptno||'、新的deptno值是'||:new.deptno); UPDATE emp SET deptno = :new.deptnoWHERE deptno = :old.deptno;END;10.select object_name,status from user_objects where object_type='FUNCTION'; select object_name,status from user_objects where object_type='PROCEDURE'; SELECT OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_TYPE='TRIGGER';drop procedure select_emp;DROP FUNCTION GET_AVG_PAY;DROP TRIGGER TR_REG_DEP;五、拓展题--创建一个包mypackage,声明该包有一个过程update_sal和一个函数get_YearSalcreate or replace package myPackage isprocedure update_sal(name varchar2,newsal number);function get_YearSal(name varchar2) return number;end;create or replace package body myPackage isprocedure update_sal(name varchar2,newsal number) isbeginupdate emp set sal=newSal where ename=name;end;function get_YearSal(name varchar2) return number isv_sal number(7,2);beginselect sal*12+nvl(comm,0) into v_sal from emp where ename=name;return v_sal;end;end;调用执行包中的存储过程或函数我们现在有这样一张用户表表结构如下,希望向表中增加数据时,表中id列的数字自动生成。
第一步创建序列,要求开始的数字为1,每次递增1,按顺序产生序列值;第二步创建一个触发器,向用户表中插入数据的时候触发触发器,在触发器内部调用序列并生成一个序列值赋值给表的id列。
表结构如下:UserInfo(id ,username,userPass)--用户表(用户编号number类型,用户名,用户密码)create sequence seq_user_idstart with 1 --从1开始increment by 1;--每次增量为1第二步创建一个触发器给id列赋值create trigger tr_user_idbefore insert on userfor each rowbeginselect seq_user_id.nextval into :new.id from dual; end;主要算法:1.DECLAREv_empno emp.empno%TYPE:=7788;v_sal emp.sal%TYPE;v_add emp.sal%TYPE;BEGINSELECT sal INTO v_sal FROM emp WHERE empno=v_empno;IF v_sal<3000THEN v_add:=3000;ELSEdbms_output.put_line('sal>3000');END IF;UPDATE emp SET sal=v_add WHERE empno=v_empno;END;/2.declaretype v_record is record (name emp.ename%type,salary emp.sal%type,job emp.job%type,deptno emp.deptno%type);empinfo v_record;--定义变量beginselect ename,sal,job,deptnointo empinfofrom empwhere empno = 7788;dbms_output.put_line('雇员'||||'的职务是:'||empinfo.job||'工资是:'||empinfo.salary||'部门号是:'||empinfo.deptno);end;/3.declarecursor c_emp is select * from scott.emp for update;v_increment number;beginfor v_emp in c_emp loopcase v_emp.deptnowhen 10 then v_increment:=100;when 20 then v_increment:=160;when 30 then v_increment:=200;else v_increment:=300;end case;update scott.emp set sal = sal+v_increment wherecurrent of c_emp;end loop;end;4.5.beginupdate scott.deptset loc = 'BEIJING' where deptno=50;if sql%notfound theninsert into scott.dept(deptno,loc) values(50,'BEIJING');dbms_output.put_line('插入成功!');ELSEdbms_output.put_line('更新成共');end if;end;6.create or replace procedure emp_countas v_total number;beginselect count(*) into v_total from scott.emp;dbms_output.put_line('雇员总数:'||v_total); end;/SQL> execute emp_count;雇员总数:15PL/SQL 过程已成功完成。