pl/sql过程化语言

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;

猜你喜欢

转载自blog.csdn.net/qq_40529747/article/details/79882199