plsql过程化语言
--控制输出-- declare begin dbms_output.put_line('hello/plsql'); end; --变量的声明和使用-- declare v_num number(8):=10; v_num1 number(8):=20; v_num2 number(8); begin v_num2:=v_num+v_num1; dbms_output.put_line('结果为:'||v_num2); end; --声明常量 在数据类型前面加constant-- declare π constant number(8,5):=3.1415; R number(9):=2; area number(10,8); begin area:=π*R*R; dbms_output.put_line(area); end; --关于赋值--把emp表的7369的工资sal 赋值给v_sal--into-- declare v_empno number(4):=7369; v_sal number(7,2); begin select sal into v_sal from emp where empno=v_empno; dbms_output.put_line(v_empno||'的工资为'||v_sal); end; ---使用表的列类型--v_empno的类型是emp表empno字段的类型-- declare v_empno emp.empno%type:=7499; v_sal emp.sal%type; begin select sal into v_sal from emp where empno=v_empno; dbms_output.put_line(v_empno||'的工资为'||v_sal); end; declare v_cname emp.ename%type; v_cjob emp.job%type; begin select emp.ename,emp.job into v_cname,v_cjob from emp where emp.empno=7369; dbms_output.put_line(v_cname||'的工作为:'||v_cjob); end; --使用表的行类型-- declare erow emp%rowtype; begin select * into erow from emp where emp.empno=7369; dbms_output.put_line('姓名:'||erow.ename); dbms_output.put_line('工作:'||erow.job); end; --使用分支语句 declare erow emp%rowtype; num1 number; begin select * into erow from emp where emp.empno=7369; select count(emp.empno) into num1 from emp where emp.empno=7369; if num1>0 then dbms_output.put_line('姓名:'||erow.ename); dbms_output.put_line('职位:'||erow.job); else dbms_output.put_line('没有此人'); end if; end; --弹出框 accept num prompt'请输入一个数字'; declare pnum number:=# begin if pnum=0 then dbms_output.put_line('你输入的是0'); elsif pnum=1 then dbms_output.put_line('你输入的是1'); else dbms_output.put_line('你输入了其他数字'); end if; end; --loop循环语句-- declare i number; begin i:=0; loop i:=i+1; dbms_output.put_line(i); exit when(i>100); end loop; end; --while循环-- declare i number :=1; begin while i<10 loop dbms_output.put_line(i); i:=i+1; end loop; end; --for循环-- declare i number:=1; begin for i in 1..100 loop dbms_output.put_line(i); end loop; end; --for循环反序-- declare i number:=1; begin for i in reverse 1..100 loop dbms_output.put_line(i); end loop; end;
游标游标相当于一个集合
--打印emp的员工的工资
declare
--定游光标--
cursor cemp is select ename,sal from emp;
--为游标定义对应的变量
pname emp.ename%type;
psal emp.sal%type;
begin
open cemp;
--循环取出游标里的元素
loop
--取一条记录赋值给pname 和 psal--
fetch cemp into pname,psal;
exit when cemp%notfound;
dbms_output.put_line(pname||'的工资为'||psal);
end loop;
close cemp;
end;
案例给emp表的老板的工资+1000 经理+800,员工+400
declare
--查询emp表的编号和工作放入游标中(相当集合)
cursor cemp is select empno,job from emp;
pempno emp.empno%type;
pjob emp.job%type;
begin
--打开游标--
open cemp;
loop
--遍历游标把empno赋值给pempno job赋值给pjob。
fetch cemp into pempno,pjob;
--循环的退出条件为cemp游标没有值时
exit when cemp%notfound;
--如果pjob为president说明就是老板
if pjob='PRESIDENT' then update emp set sal=sal+1000 where empno=pempno;
--如果pjob是manager说明是经理
elsif pjob='MANAGER' then update emp set sal=sal+800 where empno=pempno;
--否则就是员工
else update emp set sal=sal+400 where empno=pempno;
end if;
--结束循环--
end loop;
--关闭游标--
close cemp;
end;
通过system用户 在SQL plus上输入 show parameter cursor 可以查看cursor的最大连接数
修改光标的最大连接数 alter system set open_cursors=400 scope=both;
scope的取值有三个 both:两个同时更改
memory :只更改当前事例,不更改 参数文件
spfile:只更改参数文件,不更改当前事例(数据库重启服务)
set serveroutput on 打开oracle自带的输出方法dbms_output
游标的四个属性
%found如果游标里面还有就返回true 否则返回false
%notfound 如果游标没有了返回true 否则返回false
%isopen判断游标是否打开 打开true 没打开false
%rowcount 返回影响的行数,比如现在游标有100条数据,这个游标执行影响了10条,返回10
--带参数的游标,输出某个部门的所有员工的姓名
declare
cursor cemp (pno number) is select ename from emp where deptno=pno;
pname emp.ename%type;
begin
open cemp(10);
loop
fetch cemp into pname;
exit when cemp%notfound;
dbms_output.put_line(pname);
end loop;
close cemp;
end;
列外
定义:程序设计语言提供的一种功能,用来增强程序的健壮性和容错性。
系统例外:no_data_found(没有找到数据)
Too_many_rows(select...into...匹配多个行)
zero_divide(0不能做除数)
value_error(算数或转化错误)
timeout_on_resource(等待资源发生超时)
总结
案例:
--打印emp表每个年份的入职人数和总的入职人数--
declare
cursor cemp is select to_char(hiredate,'yyyy') from emp;
phiredate varchar2(4);
count80 number:=0;
count81 number:=0;
count82 number:=0;
count87 number:=0;
begin
open cemp;
loop
fetch cemp into phiredate;
exit when cemp%notfound;
if phiredate='1980'then count80:=count80+1;
elsif phiredate='1981'then count81:=count81+1;
elsif phiredate='1982'then count82:=count82+1;
else count87:=count87+1;
end if;
end loop;
close cemp;
dbms_output.put_line('total'||(count80+count81+count80+count87));
dbms_output.put_line('1980'||count80);
dbms_output.put_line('1981'||count81);
dbms_output.put_line('1982'||count82);
dbms_output.put_line('1987'||count87);
end;
案例2.--给emp表的员工涨工资幅度为10%由工资最低的员工开始,
--但是工资的总额不能超过7w打印出涨工资的人数和工资总额
--分析 sql select empno,sal from emp group by sal;--根据工资进行升序
--变量saltotal工资总额,countemp 涨工资人数
declare
cursor cemp is select empno,sal from emp order by sal;
pempno emp.empno%type;
psal emp.sal%type;
--工资总额
saltotal number;
--涨工资人数
countsal number:=0;
begin
--得到涨工资的初始值
select sum(sal) into saltotal from emp;
open cemp;
loop
--循环退出条件--
exit when saltotal>70000;
fetch cemp into pempno,psal;
exit when cemp%notfound;
--开始涨工资
if(saltotal+psal*0.1)<=70000 then
update emp set sal=psal*1.1 where empno=pempno;
countsal:=countsal+1;
saltotal:=saltotal+psal*0.1;
end if;
end loop;
close cemp;
commit;
dbms_output.put_line('涨工资的人数为:'||countsal||' 工资总额为:'||saltotal);
end;
案例3.
--通过plsql编写程序,按部门号统计7000以上,3000-7000,3000以下的人数,和部门工资总额
declare
--查询所有的部门编号;
cursor cdept is select deptno from dept;
cdeptno dept.deptno%type;
--查询某个部门中的员工的工资;
cursor cemp(pnum number) is select sal from emp where deptno=pnum;
csal emp.sal%type;
count3 number;
count3_7 number;
count7 number;
sumsal number;
begin
open cdept;
--拿到部门号--
loop
fetch cdept into cdeptno;
exit when cdept%notfound;
--初始化count3,count3_7,count1
count3:=0;
count3_7:=0;
count7:=0;
--得到工资总额sumsal
select sum(sal) into sumsal from emp where deptno=cdeptno;
--把部门号放入cemp游标查出所有员工的工资
open cemp(cdeptno);
loop
fetch cemp into csal;
exit when cemp%notfound;
if csal<3000 then count3:=count3+1;
elsif csal>=3000 and csal<=7000 then count3_7:=count3_7+1;
else count7:=count7+1;
end if;
end loop;
close cemp;
dbms_output.put_line('部门号'||cdeptno||' 3000以内的员工人数'||count3||' 3-7千的人数'||count3_7||' 7千以上的人数'||count7||' 总工资'||sumsal);
end loop;
close cdept;
end;
案例4.
--drop table sc; --drop table course; --drop table student; --drop table teacher; --drop table dep;-- CREATE TABLE DEP--系表 (DNO NUMBER(2), DNAME VARCHAR2(30), DIRECTOR NUMBER(4), TEL VARCHAR2(8)); CREATE TABLE TEACHER (TNO NUMBER(4), TNAME VARCHAR2(10), TITLE VARCHAR2(20), HIREDATE DATE, SAL NUMBER(7,2), BONUS NUMBER(7,2), MGR NUMBER(4), DEPTNO NUMBER(2)); CREATE TABLE student (sno NUMBER(6), sname VARCHAR2(8), sex VARCHAR2(2), birth DATE, passwd VARCHAR2(8), dno NUMBER(2));--学生系号对应系表 CREATE TABLE course--课程表 (cno VARCHAR2(8),--编号 cname VARCHAR2(20),--名称 credit NUMBER(1),--学分 ctime NUMBER(2),--时长 quota NUMBER(3));--容量这门课可以有多少人上 CREATE TABLE sc (sno NUMBER(6),--学生编号 cno VARCHAR2(8),--课程编号 grade NUMBER(3));--成绩多少 --创建一张表保存查询出来的数据 create table msg1( cursorname varchar2(20),--课程名 dname varchar2(20),--系名 count1 number(9),--小于60分的人数 count2 number(9),--60-85分的人数 count3 number(9),--85分以上的人数 avggrade number(9)--平均成绩 ); alter table dep add (constraint pk_deptno primary key(dno)); alter table dep add(constraint dno_number_check check(dno>=10 and dno<=50)); alter table dep modify(tel default 62795032); alter table student add (constraint pk_sno primary key(sno)); alter table student add(constraint sex_check check(sex='男' or sex='女')); alter table student modify(birth default sysdate); alter table course add (constraint pk_cno primary key(cno)); alter table sc add (constraint pk_key primary key(cno,sno)); alter table teacher add (constraint pk_tno primary key(tno)); alter table sc add (FOREIGN KEY(cno) REFERENCES course(cno)); alter table sc add (FOREIGN KEY(sno) REFERENCES student(sno)); alter table student add (FOREIGN KEY(dno) REFERENCES dep(dno)); alter table teacher add (FOREIGN KEY(deptno) REFERENCES dep(dno)); INSERT INTO DEP VALUES (10, '计算机系', 9469 , '62785234'); INSERT INTO DEP VALUES (20,'自动化系', 9581 , '62775234'); INSERT INTO DEP VALUES (30,'无线电系', 9791 , '62778932'); INSERT INTO DEP VALUES (40,'信息管理系', 9611, '62785520'); INSERT INTO DEP VALUES (50,'微纳电子系', 2031, '62797686'); INSERT INTO TEACHER VALUES(9468,'CHARLES','PROFESSOR','17-12月-2004',8000,1000,NULL,10); INSERT INTO TEACHER VALUES(9469,'SMITH','PROFESSOR','17-12月-2004',5000,1000 ,9468,10); INSERT INTO TEACHER VALUES(9470,'ALLEN','ASSOCIATE PROFESSOR', '20-2月-2003',4200,500,9469,10); INSERT INTO TEACHER VALUES(9471,'WARD','LECTURER', '22-2月-2004',3000,300,9469,10); INSERT INTO TEACHER VALUES(9581,'JONES','PROFESSOR ', '2-4月-2003',6500,1000,9468,20); INSERT INTO TEACHER VALUES(9582,'MARTIN','ASSOCIATE PROFESSOR ','28-9月-2005',4000,800,9581,20); INSERT INTO TEACHER VALUES(9583,'BLAKE','LECTURER ','1-5月-2006',3000,300,9581,20); INSERT INTO TEACHER VALUES(9791,'CLARK','PROFESSO', '9-6月-2003',5500,NULL,9468,30); INSERT INTO TEACHER VALUES(9792,'SCOTT','ASSOCIATE PROFESSOR ','09-12月-2004',4500,NULL,9791,30); INSERT INTO TEACHER VALUES(9793,'BAGGY','LECTURER','17-11月-2004',3000,NULL,9791,30); INSERT INTO TEACHER VALUES(9611,'TURNER','PROFESSOR ','8-9月-2005',6000,1000,9468,40); INSERT INTO TEACHER VALUES(9612,'ADAMS','ASSOCIATE PROFESSO','12-1月-2004',4800,800,9611,40); INSERT INTO TEACHER VALUES(9613,'JAMES','LECTURER','3-12月-2006',2800,200,9611,40); INSERT INTO TEACHER VALUES(2031,'FORD','PROFESSOR','3-12月-2005',5500,NULL,9468,50); INSERT INTO TEACHER VALUES(2032,'MILLER','ASSOCIATE PROFESSO','23-1月-2005',4300,NULL,2031,50); INSERT INTO TEACHER VALUES(2033,'MIGEAL','LECTURER','23-1月-2006',2900,NULL,2031,50); INSERT INTO TEACHER VALUES(2034,'PEGGY', 'LECTURER', '23-1月-2007',2500,NULL,2031,50); insert into student(birth,sno,sname,sex,passwd,dno) values('01-8月 -10',1,'John','男','123456',10); insert into student(birth,sno,sname,sex,passwd,dno) values('02-8月 -10',2,'Jacob','男','123456',10); insert into student(birth,sno,sname,sex,passwd,dno) values('03-8月 -10',3,'Michael','男','123456',10); insert into student(birth,sno,sname,sex,passwd,dno) values('04-8月 -10',4,'Joshua','男','123456',10); insert into student(birth,sno,sname,sex,passwd,dno) values('05-8月 -10',5,'Ethan','男','123456',10); insert into student(birth,sno,sname,sex,passwd,dno) values('06-8月 -10',6,'Matthew','男','123456',20); insert into student(birth,sno,sname,sex,passwd,dno) values('07-8月 -10',7,'Daniel','男','123456',20); insert into student(birth,sno,sname,sex,passwd,dno) values('08-8月 -10',8,'Chris','男','123456',20); insert into student(birth,sno,sname,sex,passwd,dno) values('09-8月 -10',9,'Andrew','男','123456',30); insert into student(birth,sno,sname,sex,passwd,dno) values('10-8月 -10',10,'Anthony','男','123456',30); insert into student(birth,sno,sname,sex,passwd,dno) values('11-8月 -10',11,'William','男','123456',30); insert into student(birth,sno,sname,sex,passwd,dno) values('12-8月 -10',12,'Joseph','男','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('13-8月 -10',13,'Alex','男','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('14-8月 -10',14,'David','男','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('15-8月 -10',15,'Ryan','男','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('16-8月 -10',16,'Noah','男','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('17-8月 -10',17,'James','男','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('18-8月 -10',18,'Nicholas','男','123456',50); insert into student(birth,sno,sname,sex,passwd,dno) values('19-8月 -10',19,'Tyler','男','123456',50); insert into student(birth,sno,sname,sex,passwd,dno) values('20-8月 -10',20,'Logan','男','123456',50); insert into student(birth,sno,sname,sex,passwd,dno) values('21-8月 -10',21,'Emily','女','123456',10); insert into student(birth,sno,sname,sex,passwd,dno) values('22-8月 -10',22,'Emma','女','123456',10); insert into student(birth,sno,sname,sex,passwd,dno) values('23-8月 -10',23,'Madis','女','123456',10); insert into student(birth,sno,sname,sex,passwd,dno) values('24-8月 -10',24,'Isabe','女','123456',10); insert into student(birth,sno,sname,sex,passwd,dno) values('25-8月 -10',25,'Ava','女','123456',10); insert into student(birth,sno,sname,sex,passwd,dno) values('26-8月 -10',26,'Abigail','女','123456',20); insert into student(birth,sno,sname,sex,passwd,dno) values('27-8月 -10',27,'Olivia','女','123456',20); insert into student(birth,sno,sname,sex,passwd,dno) values('28-8月 -10',28,'Hannah','女','123456',20); insert into student(birth,sno,sname,sex,passwd,dno) values('29-8月 -10',29,'Sophia','女','123456',30); insert into student(birth,sno,sname,sex,passwd,dno) values('30-8月 -10',30,'Samant','女','123456',30); insert into student(birth,sno,sname,sex,passwd,dno) values('31-8月 -10',31,'Elizab','女','123456',30); insert into student(birth,sno,sname,sex,passwd,dno) values('01-7月 -10',32,'Ashley','女','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('02-7月 -10',33,'Mia','女','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('11-8月 -10',34,'Alexis','女','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('12-8月 -10',35,'Sarah','女','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('13-8月 -10',36,'Natalie','女','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('14-8月 -10',37,'Grace','女','123456',40); insert into student(birth,sno,sname,sex,passwd,dno) values('15-8月 -10',38,'Chloe','女','123456',50); insert into student(birth,sno,sname,sex,passwd,dno) values('16-8月 -10',39,'Alyssa','女','123456',50); insert into student(birth,sno,sname,sex,passwd,dno) values('17-8月 -10',40,'Brianna','女','123456',50); insert into course values('c001','数据结构',3,10,100); insert into course values('c002','Java语言',2,20,100); insert into course values('c003','数字电路',3,30,100); insert into course values('c004','模拟电路',3,40,100); insert into course values('c005','信号与系统',4,50,100); insert into course values('c006','C语言',3,60,100); insert into course values('c007','高等数学',5,70,100); insert into course values('c008','自动原理',1,80,100); insert into course values('c009','数理方程',3,90,100); insert into course values('c010','大学语文',2,61,100); insert into course values('c011','机械制图',3,52,100); insert into course values('c012','微机原理',3,43,100); insert into course values('c013','通信基础',3,74,100); insert into course values('c014','计算机原理',5,35,100); insert into course values('c015','数据库',3,86,100); insert into course values('c016','编译原理',2,97,100); insert into course values('c017','大学物理',2,38,100); insert into course values('c018','统计基础',4,50,100); insert into course values('c019','线性代数',4,70,100); insert into course values('c020','Linux基础',3,60,100); insert into sc values(6,'c002',60); insert into sc values(6,'c015',60); insert into sc values(6,'c010',61); insert into sc values(27,'c010',65); insert into sc values(6,'c001',60); insert into sc values(6,'c011',61); insert into sc values(6,'c018',70); insert into sc values(8,'c007',65); insert into sc values(27,'c020',65); insert into sc values(27,'c015',65); insert into sc values(26,'c015',55); insert into sc values(25,'c015',59); insert into sc values(1,'c017',65); insert into sc values(2,'c017',66); insert into sc values(3,'c017',67); insert into sc values(4,'c017',68); insert into sc values(5,'c017',69); insert into sc values(6,'c017',70); insert into sc values(7,'c017',71); insert into sc values(8,'c017',72); insert into sc values(9,'c017',73); insert into sc values(10,'c017',74); insert into sc values(11,'c017',75); insert into sc values(12,'c017',76); insert into sc values(13,'c017',77); insert into sc values(14,'c017',78); insert into sc values(15,'c017',79); insert into sc values(16,'c017',80); insert into sc values(17,'c017',81); insert into sc values(18,'c017',82); insert into sc values(19,'c017',83); insert into sc values(20,'c017',84); insert into sc values(21,'c017',85); insert into sc values(22,'c017',86); insert into sc values(23,'c017',87); insert into sc values(24,'c017',88); insert into sc values(25,'c017',89); insert into sc values(26,'c017',90); insert into sc values(27,'c017',89); insert into sc values(28,'c017',88); insert into sc values(29,'c017',87); insert into sc values(30,'c017',86); insert into sc values(31,'c017',85); insert into sc values(32,'c017',84); insert into sc values(33,'c017',83); insert into sc values(34,'c017',82); insert into sc values(35,'c017',81); insert into sc values(36,'c017',80); insert into sc values(37,'c017',79); insert into sc values(38,'c017',78); insert into sc values(39,'c017',77); insert into sc values(40,'c017',76); commit; /*分析问题 1.得到有哪些系编号,系名。--select dno,dname from dep; 2.得到系中学生选修了“大学物理”这门课的成绩 --查询成绩 --查询课程表中课程名为‘??’的编号 select grade from sc where cno=(select cno from course where cname=?? ) and son in (select sno from student where dno=??)查询同一个系的所有学生 定义变量 每个分数段的人数 count1 number; count2 number; count3 number; 每个系选修‘大学物理’学生的平均成绩 avggrade number; 1.算数 2.select avg(grade) into avggrade from sc where cno=(select cno from course where cname=?? ) and son in (select sno from student where dno=??) */ declare --定义系的游标-- cursor cdept is select dno,dname from dep; --定义两个变量接收游标查找的dno,dname cdno dep.dno%type; cdname dep.dname%type; --定义成绩的游标-- cursor cgrade(coursename varchar2,depno number) is select grade from sc where cno=(select cno from course where cname=coursename) and sno in (select sno from student where dno=depno); --定义变量接收grade成绩 pgrade sc.grade%type; --每个分数段的人数 count1 number; count2 number; count3 number; --每个系选修‘大学物理’学生的平均成绩 avggrade number; --定义coursename 变量 pcoursename varchar2(40):='大学物理'; begin open cdept; loop --取出游标的值赋给cdno和cdname; fetch cdept into cdno,cdname; exit when cdept%notfound; --给count1.2.3初始化 count1:=0; count2:=0; count3:=0; --给平均成绩初始化 select avg(grade) into avggrade from sc where cno=(select cno from course where cname=pcoursename) and sno in (select sno from student where dno=cdno); --取系中,选修大学物理的学生信息 open cgrade(pcoursename,cdno); loop --赋给pgrade fetch cgrade into pgrade; --退出条件 exit when cgrade%notfound; --计数 if pgrade<60 then count1:=count1+1; elsif pgrade>=60 and pgrade<85 then count2:=count2+1; else count3:=count3+1; end if; end loop; close cgrade; --添加到表中 insert into msg1 values(pcoursename,cdname,count1,count2,count3,avggrade); end loop; close cdept; commit; end;