学习大数据DAY14 PLSQL基础语法3

目录

二重循环 三种循环随便嵌套

exit continue return

作业

数据提取

游标

隐式游标

显示游标

动态游标

游标使用流程

游标属性

游标配合循环使用示例

作业2

参数游标

current of 语句

作业3


PLSQL基础语法(三)

二重循环 三种循环随便嵌套

begin

for n in 1..10

loop

dbms_output.put_line(n);

for j in 1..5

loop

dbms_output.put('*');

end loop;

dbms_output.put_line(null);

end loop;

end ; 

exit continue return

1.EXIT:只能用于循环中,并且只是退出本次循环,继续执行下一条外层循环数据

2.RETURN:可以用于循环和非循环中:退出整个BEGIN...END,且不往下执行

3.CONTINUE:退出本次循环,直接进入下一次循环

--一重循环

begin

for i in 1 .. 10

loop

if i=1 then

continue;

end if;

if i=8 then

dbms_output.put('发财咯');

exit;

end if;

dbms_output.put_line(i);

end loop;

dbms_output.put_line('');

end;

--二重循环

begin

for i in 1 .. 5

loop

if i=3 then continue;

end if;

if i=4 then exit;

end if;

dbms_output.put_line(i);

for j in 1..5

loop

if j=3 then

continue;

end if;

if j=4 then

--exit;

return;

end if;

dbms_output.put_line(j);

end loop;

end loop;

end;

作业

--1、99乘法表

declare

a number(10);

b number(10);

begin

  for a in 1 .. 9

    loop

      for b in 1 .. a

        loop

          dbms_output.put(b||'*'||a||'='||(a*b)||' '); 

          end loop;

          dbms_output.put_line(null); 

      end loop;

  end;

--2、拼接一个直角三角形

begin

  for i in 1 .. 9

    loop

      for j in 1 .. 2*i-1

        loop

          dbms_output.put('*'); 

          end loop;

          dbms_output.put_line(null); 

      end loop;

  end;

--3、上个练习基础上拼接一个等腰三角形

begin

  for i in 1 .. 9

    loop

      for j in 1 .. (8+i)

        loop

          if j between 9-i+1 and 9+i-1

            then

            dbms_output.put('*');

            else

            dbms_output.put(' ');  

            end if;

          end loop;

          dbms_output.put_line(null); 

      end loop;

  end;

--4、上个练习基础上拼接一个菱形

begin

  for i in 1 .. 9

    loop

      for j in 1 .. (8+i)

        loop

          if j between 9-i+1 and 9+i-1

            then

            dbms_output.put('*');

            else

            dbms_output.put(' ');  

            end if;

          end loop;

          dbms_output.put_line(null); 

      end loop;

    for k in 1 .. 8

      loop

        for m in 1 .. 17-k

          loop

            if m between 1+k and 17-k

              then

                dbms_output.put('*');

                else

                  dbms_output.put(' ');  

                  end if;

            end loop;

            dbms_output.put_line(null); 

        end loop;

  end;

  

/*5、打印输出100至200之间的全部素数,输出素数并统计共有多少个素数。

注:质数(prime number)又称素数,有无限个。一个大于1的自然数,除了1和它本身

外,不能被其他自然数整除,换句话说就是该数除了1和它本身以外不再有其他的因数;

否则称为合数。*/

declare

PrimeCount number(10):=0;

begin

  for i in 100 .. 200

    loop

      for j in 2 .. floor(i/2)

        loop

        if mod(i,j)=0

          then exit;

          end if;

        if j=floor(i/2)

          then

            dbms_output.put_line(i); 

            PrimeCount:=PrimeCount+1;

            end if;

            end loop;

      end loop;

      dbms_output.put_line('共有'||PrimeCount||'个素数'); 

  end;

数据提取

游标

游标是一种从表中检索数据并进行操作的灵活手段,游标主要用在服务器上,处理由客户端发送给服务端的sql语句,或是批处理、存储过程、触发器中的数据处理请求。游标的优点在于它可以定位到结果集中的某一行,并可以对该行数据执行特定操作。作为一个备用方式,当我们穷尽了while循环,子查询,临时表,表变量,自建函数或其他方式仍然无法实现某些查询的时候用游标来实现。

隐式游标

通过一个简单直接的select...into 语句提取一行数据,并放在一个局部变量中。

显示游标

在声明单元declare中明确的声明一个查询。这样我们就可以在一个或者多个程序中打开游标并从中提取数据,可以得到隐式游标所没有的空值颗粒。

动态游标

使用游标变量(用ref cursor 类型声明),我们可以把指向一个查询结果集的指针从一个程序传递到另一个程序,从而提供了另一层灵活性。任何程序只需要访问这个变量,就可以打开游标提取数据.

游标使用流程

声明游标

cursor 游标名称 is sql语句;

打开游标

open 游标名称;

提取数据

fetch 游标名称 into 记录名;

关闭游标

close 游标名称;

--提取dept部门编号和部门名称

declare

cursor cur_dept is select * from dept;

v_dept cur_dept%rowtype;

begin

open cur_dept;

fetch cur_dept into v_dept;

dbms_output.put_line(v_dept.deptno||v_dept.dname);

fetch cur_dept into v_dept;

dbms_output.put_line(v_dept.deptno||v_dept.dname);

fetch cur_dept into v_dept;

dbms_output.put_line(v_dept.deptno||v_dept.dname);

fetch cur_dept into v_dept;

dbms_output.put_line(v_dept.deptno||v_dept.dname);

close cur_dept;

end; 


游标属性

游标配合循环使用示例

declare

cursor cur_dept is select * from dept; --声明游标

v_dept cur_dept%rowtype; --声明游标变量

begin

open cur_dept; --打开游标

if cur_dept%isopen then

loop --开始循环

fetch cur_dept into v_dept; --抓取

exit when cur_dept%notfound; --循环边界

dbms_output.put_line(cur_dept%rowcount||'--'||v_dept.deptno||v_dept.dname); --打印

end loop;

close cur_dept; --关闭游标

end if;

end;

--while循环

declare

cursor cur_dept is select * from dept; --声明游标

v_dept cur_dept%rowtype; --声明游标变量

begin

open cur_dept; --打开游标

fetch cur_dept into v_dept; --抓取

while cur_dept%found

loop --开始循环

dbms_output.put_line(v_dept.deptno||v_dept.dname); --打印

fetch cur_dept into v_dept;

end loop;

close cur_dept; --关闭游标

end; 

--for 会自动打开关闭游标

declare

cursor cur_dept is select * from dept ; --声明游标

begin

for v_dept in cur_dept

loop --开始循环

dbms_output.put_line(cur_dept%rowcount||'--'||v_dept.deptno||v_dept.dname); --打印

end loop;

end;

作业2

-1、提取emp表的姓名和工资,显示游标序号,使用两种循环完成游标遍历输出 while for

--方法一

declare

cursor enamesal is select * from emp;

v_emp emp%rowtype;

begin

  open enamesal;

  fetch enamesal into v_emp;

  while enamesal%found

    loop

      dbms_output.put_line(v_emp.ename||' '||v_emp.sal||' '||enamesal%rowcount);

      fetch enamesal into v_emp;

      end loop;

   close enamesal; 

  end;

--方法二(超好用)

declare

cursor enamesal is select * from emp;

begin

  for i in enamesal

    loop

      dbms_output.put_line(i.ename||' '||i.sal||' '||enamesal%rowcount); 

      end loop;

  end;

--2、上题基础上对员工表2-4条数据输出,for循环实现

declare

cursor enamesal is select * from emp; 

begin

  for i in enamesal

    loop

      if enamesal%rowcount between 2 and 4

        then

        dbms_output.put_line(i.ename||' '||i.sal||' '||enamesal%rowcount); 

        end if;

      end loop;

  end;

参数游标

cursor 游标名称(参数名称 in 参数数据类型 :=默认值 ) is sql语句

open 游标名称(参数)

只有open需要加参数,其他直接使用游标名称

--简单输入

declare

cursor cur_emp is select * from emp where deptno=&部门编号;

begin

for v_emp in cur_emp

loop

dbms_output.put_line(v_emp.ename);

end loop;

end; 

--传入参数for循环

declare

cursor cur_emp(deptin number :=20) is select * from emp where deptno=deptin;

dno number(4);

begin

select max(deptno) into dno from emp;

for v_emp in cur_emp(dno)

loop

dbms_output.put_line(v_emp.ename||v_emp.deptno);

end loop;

end;

--传入参数while循环

declare

cursor cur_emp(deptin number :=20) is select * from emp where deptno=deptin;

v_emp cur_emp%rowtype;

dno number(4);

begin

select max(deptno) into dno from emp;

open cur_emp(dno);

fetch cur_emp into v_emp;

while cur_emp%found

loop

dbms_output.put_line(v_emp.ename||v_emp.deptno);

fetch cur_emp into v_emp;

end loop;

close cur_emp;

end; 

--二重循环传入参数for循环

declare

cursor cur_dept is select * from dept ;

cursor cur_emp(deptin number) is select * from emp where deptno=deptin;

begin

for v_dept in cur_dept

loop

dbms_output.put_line(v_dept.deptno||'---'||v_dept.dname);

for v_emp in cur_emp(v_dept.deptno)

loop

dbms_output.put_line(' '||v_emp.ename||'-'||v_emp.job||'-'||v_emp.sal);

end loop;

end loop;

end;

--二重循环传入参数while循环

declare

cursor cur_dept is select * from dept ;

cursor cur_emp(deptin number) is select * from emp where deptno=deptin;

v_emp cur_emp%rowtype;

begin

for v_dept in cur_dept

loop

dbms_output.put_line(v_dept.deptno||'---'||v_dept.dname);

open cur_emp(v_dept.deptno);

fetch cur_emp into v_emp;

while cur_emp%found

loop

dbms_output.put_line(' '||v_emp.ename||'-'||v_emp.job||'-'||v_emp.sal);

fetch cur_emp into v_emp;

end loop;

close cur_emp;

end loop;

end; 

current of 语句

通过where current of 语句进行数据更新或删除就可以直接修改最后取出的数据行,而不用再写判断条件了。该语法无法和returning 语句一起使用。

update 表名 set 列名= where current of 游标名;

示例

declare

cursor cur_emp is select * from emp where deptno='20' and sal<5000 for update;

begin

for  v_emp in cur_emp

loop

--update emp set sal=8000 where deptno='20' and sal<5000;

update emp set sal=8000 where current of cur_emp;

end loop;

end;

作业3

--1、寻找每个sc表中分数大于平均分数的考试的信息,显示学生编号,课程编号,分数

select sno,cno,score

from sc

where score>(

select avg(score) from sc

);

--2、使用游标获取每个老师所教授课程的课程名称以及平均成绩,二重循环实现

declare

cursor v_teacher is select tno,tname

from teacher;

cursor v_course(tt teacher.tno%type) is select cname,nvl2(avg(score),to_char(avg(score)),'没有成绩')  avgsc

from course left join sc on course.cno=sc.cno where tno=tt

group by cname;

begin

  for i in v_teacher

    loop

      dbms_output.put_line(i.tno||'--'||i.tname);

      for j in v_course(i.tno)

        loop

            dbms_output.put_line('     '||j.cname||'---'||j.avgsc); 

          end loop;

      end loop;

end;

上一篇:Centos9安装部署及静态ip配置方案