plsql(轻量版)_流程控制

记录类型百分号type,使用它的优点,所引用的数据库列的数据类型不必知道,要不你就得知道它的

类型和他的一样的,这里你可以实时改变,列的数据类型改变,我这里也跟着改,动态的来获取你的类型

plsql(轻量版)_流程控制_第1张图片

这里还有个百分号rowtype,返回一个记录类型,其数据类型和数据库表的类型一样,一个列一样

plsql(轻量版)_流程控制_第2张图片

你这里有多少列我这里也有,列名叫什么我也跟你一样,然后你的列的类型,也一样,这就过了,他表示的是等于符号

plsql(轻量版)_流程控制_第3张图片

这个叫一般运算符

plsql(轻量版)_流程控制_第4张图片

加减乘除,这个叫赋值了,这个我们后边讲游标的时候,游标有可能有参数,参数的赋值用这个

plsql(轻量版)_流程控制_第5张图片

逻辑运算符,这个我们讲SQL里面都说过,你需要用到的你就来用

plsql(轻量版)_流程控制_第6张图片

变量的赋值,用到连接的用到双竖线

plsql(轻量版)_流程控制_第7张图片

通过select语句来完成对数据库的赋值,然后每次执行select语句就赋值一次,一般要求被赋值的变量,

与select的列名要一一对应,select一个什么salary,工资,into于一个变量,然后赋给一个人,你要再赋予一个人,

就要循环了,再赋予一个人就再赋予一次,一条一条的出来

plsql(轻量版)_流程控制_第8张图片

不能讲select语句赋给布尔类型的变量,这就是一个要求

plsql(轻量版)_流程控制_第9张图片

然后可转换的数据类型,在讲SQL中也提过,to_number,to_char,to_date

plsql(轻量版)_流程控制_第10张图片

注释,两个这个,表示的是单行的

plsql(轻量版)_流程控制_第11张图片

然后这样是表示多行的,这种每种语言都有,文档注释是JAVA特有的

plsql(轻量版)_流程控制_第12张图片

第三章,PL/SQL的流程控制语句,第一个叫条件语句,我们说条件语句有两种格式的,

一种叫if then,一个叫case when then when then,先看这个,if就跟讲JAVA里面一样,

JAVA里面if也说了三种结构,最简单的是一种情况,if一个东西,他返回的也是一个布尔类型的,

如果满足真的话,就执行后面的then,分号结束,endif,因为你讲PL/SQL他没有大括号的概念,JAVA

里面有大括号的概念,我一包就知道哪里是语句块,大括号结束,大括号结束就相当于endif,他这里没有

大括号呢,只有通过单词,叫关键字,关键字来标识,你这个语句块结束了

plsql(轻量版)_流程控制_第13张图片

两个的话加一个else,多个的话就没有e了,els,没有e,然后if,这是一个词,中间也不能加空格,

这个是跟JAVA不一样的

plsql(轻量版)_流程控制_第14张图片

那我们写一个例子,写这个吧,查询150号员工的工资,如果工资大于1万,打印这个,若这个之间就打印这个,

否则打印这个,declare,他的工资大于这么多,可以把工资放在这个变量里,看看这个变量是不是大于1万,

是这个意思吧,所以v_sal,employees表的salary的类型,一样的,这样写,然后,begin,我就select,salary,

into v_sal,from employees表,where employee_id等于150,把这个人的工资放到这儿,if,没有写小括号,

直接写if,如果你这个v_sal它是大于等于1万的,then dbms_output.put_line打印这个叫salary>=10000,

分号结束,这里写了三种情况,elsif,同样满足我们JAVA里面讲的,把更严格的放上边,只需要写上一个5000

就行了,就不用and salary小于1万了,then,再else,else就直接打印了,else这样,最后记得写一个endif,

表明这个条件判断语句结束了,紧接着我这个程序就结束了

declare

	v_sal employees.salary%type;
	
begin

	select salary into v_sal from employees where employee_id = 50;
	
	if v_sal >= 10000 then dbms_output.put_line('salary>=10000');
	
	elsif v_sal > 5000 then dbms_output.put_line('5000<=salary<=10000');
	
	else dbms_output.put_line('salary<5000');
	
	endif;
	
end;

plsql(轻量版)_流程控制_第15张图片

plsql(轻量版)_流程控制_第16张图片

这个人的工资大于等于1万的,这个程序就写完了,还有一种思路就是,什么思路,我用一个变量,

来记录你这个人妖输出的语句,这个写法没问题,写出来了,然后我再记录一下你这个类型,v_temp,

这个变量是varchar类型的,10个吧,当你工资大于等于1万的时候,我给这个变量赋个值,冒号等于,

当这个的时候,else,这个能看懂,然后结束,结束完了以后,你可以在这儿,dbms_output.put_line,

v_temp,跟着你可以把他的工资给他打印一下,v_sal双竖线,然后这样

declare

	v_sal employees.salary%type;
	
	v_temp varchar2(30);
	
begin

	select salary into v_sal from employees where employee_id = 150;
	
	if v_sal >= 10000 then v_temp := 'salary >= 10000';
	
	elsif v_sal >= 5000 then v_temp := '5000<=salary<10000';
	
	else v_temp := 'salary < 5000';
	
	dbms_output.put_line(v_sal || ',' || v_temp);
	
end;

plsql(轻量版)_流程控制_第17张图片

plsql(轻量版)_流程控制_第18张图片

然后大于等于1万,这种想法要注意,我们在JAVA当中也涉及到过,我可以把你要输出的这个东西,

那我就赋给一个变量,对这个变量进行一个操作,就这样,我们体会了if else,方法二,case when then,

这个例子你可以看看,这是另一种条件表达式,叫case一个东西,当这样的时候执行这个,when then then,

最后加一个else,end,然后结束

plsql(轻量版)_流程控制_第19张图片

我们把刚才这个练习,给他改成case when then,我们JAVA里面讲一个条件判断的时候,一个叫if else if,

还有一个叫switch case,这两个哪个好啊,显然if else更方便一些,没有共鸣啊,是吧,switch case的时候,

一个他就那么几种数据类型的可以用,再一个switch一个变量,case的是你离散时的值,然后相比,如果你要比较这个

数的范围,如果很大,或者是连续的,比较这个温度,温度在0到15度之间,说这个温度,那你用switch就费劲了,你这个中间的

温度那是连续的,你不可能把每一个温度都给他写出来,这个时候你只能用if else,有些时候一些值,如果就那么几个,你用

if else不如用switch效率高,这儿呢是同理的,这个if,else if,if then, elsif then,这个也是更具有通用性的,然后用case

when then,那就相当于JAVA中的switch case一样,那我们用它来写操作一下来看看,操作的话这块不要了,把这个工资放到这里面,

下一步就是case吧,我case一下你这个工资,v_sal,当你这个工资大于等于1万的时候,then,then这个吧,加个else,记得要加一个end,

表示结束,知道为什么报错,我们讲switch的时候,switch case,case里面,不能够放范围的,是不是只能放变量,你不能case salary,

when,salary大于1万,case只能填变量,这个也是一样,这里只能写值,那你这个怎么处理,那我只能在这里处理了,这个肯定是已经

获取到他的工资了,工资除以5000,加上一个trunc,这样不就可以得到离散的值了吗,如果你工资小于5000的,这一串值是0,如果要5000到

1万之间的,是1,大于1万的就是2,所以说你这个改的话,把2大的写到else里边,所以我们这里从小的写,先0,再1,不是0不是1,

这样你看行不行

declare

	v_sal employees.salary%type;
	
	v_temp varchar2(30);
	
begin

	select salary into v_sal from employees where employee_id = 150;
	
	v_temp := 
	
	case trunc(v_sal/5000) when 0 then 'salary < 5000'
	
						   when 1 then '5000<=salary<10000'
						   
						   else 'salary>10000'
						   
	end;
	
	dbms_output.put_line(v_sal||','||v_temp);
	
end;

plsql(轻量版)_流程控制_第20张图片

plsql(轻量版)_流程控制_第21张图片

我是让你看到调的过程当中,哪种格式是对的,我们刚才是不是这样写的,不能够写范围,我们没有写范围,

这样处理的时候,当然这个是写错了,不能写分号,然后你变量赋值不能写这儿,每次不能写这儿,你得给他拿出来,

拿到这儿来,你就写成这样,变量赋值,然后当是这样的时候,给他赋一个他,要么他要么他,打印,打印试试,因为这个

人工资是大于1万的,dbms_output.put_line,我这里简写,打个1,他这个也不行,他这个也特别呕心

declare

	v_sal employees.salary%type;
	
	v_temp varchar2(30);
	
begin

	select salary into v_sal from employees where employee_id = 150;
	
	case trunc(v_sal/5000) when 0 then dbms_output.put_line('1')
	
						   when 1 then dbms_output.put_line('1')
						   
						   else dbms_output.put_line('1')
						  
    end;
	
	dbms_output.put_line(v_sal || ',' || v_temp);
	
end;

plsql(轻量版)_流程控制_第22张图片

他这个特别的呕心,而且还有哪里呕心,他这里还特别有局限性,我们刚才用的trunc,如果我把这个等号删了,

实际上你这里是错的,我把等号写在这儿,意味着如果要等于5000的话,现在我不放在那个语句,现在我放到这种

情况,那你这个时候一trunc的话,坏事了,因为如果这个工资是5000,你得的结果是1,如果是1的话输出这个,使用

case when then的时候,这个限制条件很多,一个呢他只能写具体的值,他不能写取值范围,这点不如if else好,

再一点,既然你这写具体的值,既然你写具体的值的话你就要考虑到,你这个值的范围,因为人家这儿的话,正常的时候

是比5000多,含5000的时候,都是1,当然小于1万了,如果5000就给你放到另一个范围里面,这样就写不了了,就只能够

用if else了,这就是使用它的局限性,但是他至少也算是一种表达方式吧,你就把的if else顺序当成JAVA里的if else,

case when then相当于JAVA里的switch case,我们再练一下他

8. 使用 CASE ... WHEN ... THEN ... ELSE ... END;

要求: 查询出 122 号员工的 JOB_ID, 若其值为 'IT_PROG', 则打印 'GRADE: A'; 
					    'AC_MGT', 打印 'GRADE B', 
					    'AC_ACCOUNT', 打印 'GRADE C'; 
					    否则打印 'GRADE D'

declare
       --声明变量
       v_grade char(1);
       v_job_id employees.job_id%type;
begin
       select job_id into v_job_id
       from employees
       where employee_id = 122;
       
       dbms_output.put_line('job_id: ' || v_job_id);
       
       --根据 v_job_id 的取值, 利用 case 字句为 v_grade 赋值
       v_grade :=  
               case v_job_id when 'IT_PROG' then 'A'
                             when 'AC_MGT' then 'B'
                             when 'AC_ACCOUNT' then 'C'
                             else 'D'
                end;
                
       dbms_output.put_line('GRADE: ' || v_grade);
end; 

查询出122号员工的JOB_ID,如果他的值是这个,打印这个,这个打印这个,这个打印这个,declare,declare里面写啥,声明job_id,

v_job_id,varchar型的,先这样,然后打印一个东西,这个打印的东西给他当成一个变量,varchar2,这个差不多,begin,select

job_id,into job_id,from employees where,employee_id等于122,把这个人的job_id给拿出来,v_temp等于,回来case,case

v_job_id,when 'IT_PROG',then,我简写了,打印A,when 'AC_MGT',then,这个没有分号,还是挺别扭的,else,然后就没有了,

打印v_job_id,然后执行,加个end,这个部门的,它是D

declare

	v_job_id varchar2(10);
	
	v_temp varchar2(10);
	
begin

	select job_id into v_job_id from employees where employee_id = 122;
	
	v_temp := 
	
			case v_job_id when 'IT_PROG' then 'A'
			
						  when 'AC_MGT' then 'B'
						  
						  when 'AC_ACCOUNT' then 'C'
						  
						  else 'D'
			
			end;
			
end;

plsql(轻量版)_流程控制_第23张图片

plsql(轻量版)_流程控制_第24张图片

下面就循环了,循环三种结构,loop,表示循环体,分号结束

plsql(轻量版)_流程控制_第25张图片

exit when,循环条件,然后end loop,表示结束,这两个之间是可以加东西

有一个输出1到100,用三种方式写,先说刚才的第一种

9. 使用循环语句打印 1 - 100.(三种方式)

1).  LOOP ... EXIT WHEN ... END LOOP
declare
       --初始化条件
       v_i number(3) := 1;
begin
       loop
       --循环体
        dbms_output.put_line(v_i);
	--循环条件
        exit when v_i = 100;
	--迭代条件
        v_i := v_i + 1;
       end loop;
end;

2). WHILE ... LOOP ... END LOOP
declare
       --初始化条件
       v_i number(3) := 1;
begin
       --循环条件
       while v_i <= 100 loop
	     --循环体
             dbms_output.put_line(v_i);
	     --迭代条件
             v_i := v_i + 1;
       end loop;
end; 

3).
begin
       for i in 1 .. 100 loop
             dbms_output.put_line(i);
       end loop;
end;

先不能loop,先declare,begin,end,我们还没有讲异常呢,我们讲循环的时候,我们讲JAVA的时候包括三部分,

第一部分,叫初始化条件,第二部分,叫循环体也行,三循环条件,四迭代条件,这样三部分,然后放到这儿,任何循环

都是这样一个结构,都少不了,declare的算初始化条件,声明一个什么样的变量,然后然他执行loop,然后就是循环体,

case when算循环条件,跟endloop算迭代条件,先写第一部分,声明一个变量,v_i这是一个变量,这是number类型的,

写大一点也无所谓,冒号等于从1开始,这就是初始化条件,begin,loop什么执行,这个是2,dbms输出,输出一下v_i,

输出他以后,exit when,结束就是v_i,大于等于100的时候,exit when当结束的时候,如果没有到这个的时候,

v_i = v_i +1,然后,然后end loop,这儿是3,这儿是第四步,冒号等于

declare

	v_i number(5) := 1;
	
begin

	loop
	
		dbms_output.put_line(v_i);
		
	exit when v_i >= 100;
	
		v_i := v_i + 1;
		
	end loop;
	
end;

plsql(轻量版)_流程控制_第26张图片

plsql(轻量版)_流程控制_第27张图片

从1开始,然后到100结束,先打印一下,把这个循环体放到这,这个就到99了

declare

	v_i number(5) := 1;
	
begin

	loop
	
		dbms_output.put_line(v_i);
		
		v_i := v_i + 1;
		
	exit when v_i >= 100;
	
	end loop;
	
end;

plsql(轻量版)_流程控制_第28张图片

plsql(轻量版)_流程控制_第29张图片

因为你打印99,等于99加1了,把等于去了,这就到100了

declare

	v_i number(5) := 1;
	
begin

	loop
	
		dbms_output.put_line(v_i);
		
		v_i := v_i + 1;
		
	exit when v_i > 100;
	
	end loop;
	
end;

plsql(轻量版)_流程控制_第30张图片

 

plsql(轻量版)_流程控制_第31张图片

你这个你可以省了,让他在循环体里面执行也行,这是说的第一种方式,loop,exit when,end loop,

这都是他的关键字,第二种,就是while,while loop,然后执行,end loop

plsql(轻量版)_流程控制_第32张图片

用这种格式操作一下他,初始化条件,都这样写,where v_i小于等于100,loop执行,dbms_output.put_line,

执行完了以后,v_i要让他执行一个值,然后还有别的操作不,还有end loop,还有什么,这个跟我们讲的while

有点类似

declare

	v_i number(5) := 1;
	
begin

	while v_i<=100 loop
	
		  dbms_output.put_line(v_i);
		  
		  v_i := v_i + 1;
		  
	end loop;
	
end;

plsql(轻量版)_流程控制_第33张图片

plsql(轻量版)_流程控制_第34张图片

这里是循环条件,这里是循环体,然后你得加上一个迭代部分,这个不加的话就成了死循环了,

这是第二种方式,再往后,for,for循环,for循环的时候,JAVA里面的for循环重新定义了一个变量,

int i = 0,这个也是一样,循环计数器就是你定义的一个变量,只不过他的类型需要你指定了

plsql(轻量版)_流程控制_第35张图片

你看看这个格式,叫in,这个你先忽略,下限,两个点,上限,loop,要执行的语句,再end loop,所以就来,

这里不要了,你可以不用,begin,for循环,定义一个变量,比如c,in,从1开始,点点到一百,loop,开始执行,

打印c,打印c完了以后,我要到后面end loop

begin

	for c in 1..100 loop
	
		dbms_output.put_line(c);
		
	end loop;
	
end;

plsql(轻量版)_流程控制_第36张图片

plsql(轻量版)_流程控制_第37张图片

 

有啥疑问吗,这不就相当于JAVA里面的for,int i,i等于几啊,i等于1,第二部分,分号后边i小于等于100,

这不就是到100吗,加加,我自动的给你加加,这是循环体,就这样,这个后边可以加上一个reverse,从100到

1,就是可以反着来

begin

	for c in 1..100 loop
	
		dbms_output.put_line(c);
		
	end loop;
	
end;

 

plsql(轻量版)_流程控制_第38张图片

 

plsql(轻量版)_流程控制_第39张图片

这个完了以后,我们写一个稍微麻烦一点的,我们在JAVA中讲过,准确来说从2开始,到100之间的质数,

不只是结构,还有小算法,加不加break,效率是不一样的,循环结构,条件判断结构,顺便考一下你的算法,

题目也不大,所以是一个挺好的题目,从JAVA当中去想,你当时声明过哪些变量,然后begin,end,我们外层

for循环定义一个i,是想从2到100,在内层又定义一个for循环,然后定义一个flag,修改flag为true,这里我们也得定义

一个变量,v_i,number类型的,冒号等于,从2开始,number类型的,冒号等于,也是从2开始,我再定义一个flag,早知道我们

不定义布尔类型了,我还定义一个number类型的,1位就够,这个用for循环实现和while循环实现是一样的,我们先用while循环

实现吧,while,while后边写的是一个条件,v_i他的小于等于100,然后loop开始执行这个循环,这个循环里边,如果v_j

plsql(轻量版)_流程控制_第40张图片

plsql(轻量版)_流程控制_第41张图片

这个就是那之前的一行代码,你要是不初始化的话,每次就进不去了,每次进不去他就认为你是质数了,

这个其实和我们JAVA里面,除了各式之外,就是你这个外层循环,当这个被除数,内层当除数,范围取个根号就完了,

一旦发现做除等于0的时候,你给他改个值,然后判断这个值是否被改过,说明他就不是质数,没改过,就是,记得每次

给他改成1,这个重新给他置成一个2,然后这个加加就完了,这个是我们使用while循环来实现的,实现了质数的一个输出,

现在我们给他改成使用for,使用for循环,使用for循环的话,这两你不用了,for v_i,in,从2开始到100,loop,for v_j,

in 从2开始,sqrt(v_i),然后loop,然后还是这个判断,如果mod(v_i,v_j),等于0,then,then v_flag置成0,end if,if完了

就不用再加加了,这个完了以后,判断一下,判断一下v_flag,如果他是等于1的话,then,打印一下v_i,end if,注意这个,

那两行我们就不用了,v_flag等于1,end一下

declare

	v_flag number(1) := 1;
	
begin

	for v_i in 2..100 loop
	
		for v_j in 2 .. sqrt(v_i) loop
		
			if mod(v_i,v_j)=0 then v_flag := 0;
			
			end if;
			
		end if;
		
		if v_flag = 1 then dbms_output.put_line(v_i);
		
		end if;
		
		v_flag := 1;
		
	end loop;
	
end;

plsql(轻量版)_流程控制_第42张图片

plsql(轻量版)_流程控制_第43张图片

这个我们使用for循环,显然比刚才的while要简洁,而for循环会自动的给你迭代,就是这两个好处,

我们讲JAVA的时候,说过一个观点,有些算法是可以改进的,在哪,比如8这个数,8这个数已经明显等于

0了,但是他没有终止,他又继续的比了一下4,实际上到2的时候,已经该结束了,我们开始用了一个叫continue

标签的形式,直接跳到外层,叫goto,无条件的跳到指定的标号去

plsql(轻量版)_流程控制_第44张图片


跳转我在哪跳,如果一旦你发现有一个值,我就让你goto一个地,goto哪个地,goto到一个带标签的一个位置,

假设这个标签我就叫label,那你这个label是什么啊,实际上就是跳到这,一旦你这边出现等于0的时候执行过了,

进入这个语句里边,我就来判断一下,或者每执行一次我就给判断一下,如果不是1了,就已经被改了,直接就跑到

这里来了

declare

	v_flag number(1) := 1;
	
begin

	for v_i in 2..100 loop
	
		for v_j in 2 .. sqrt(v_i) loop
		
			if mod(v_i,v_j)=0 then v_flag := 0;
			
			goto label;
			
			end if;
			
	   end loop;
	   
	   <

plsql(轻量版)_流程控制_第45张图片

plsql(轻量版)_流程控制_第46张图片

10. 综合使用 if, while 语句, 打印 1 - 100 之间的所有素数
(素数: 有且仅用两个正约数的整数, 2, 3, 5, 7, 11, 13, ...).
declare
  v_flag number(1):=1;
  v_i number(3):=2;
  v_j number(2):=2;
begin

  while (v_i<=100) loop
        while v_j <= sqrt(v_i) loop
              if (mod(v_i,v_j)=0) then v_flag:= 0;
	      end if;
             
	      v_j :=v_j +1;
        end loop;
        
	if(v_flag=1) then dbms_output.put_line(v_i);
	end if;

        v_flag :=1;
        v_j := 2;
        v_i :=v_i +1;
   end loop;

end;


(法二)使用for循环实现1-100之间的素数的输出
declare
  --标记值, 若为 1 则是素数, 否则不是
  v_flag number(1) := 0;
begin
   for i in 2 .. 100 loop

       v_flag := 1;     
         
       for j in 2 .. sqrt(i) loop
           if i mod j = 0 then
              v_flag := 0;	
           end if;        
       end loop;
       
       if v_flag = 1 then
           dbms_output.put_line(i);
       end if;
       
   end loop;
end;

11. 使用 goto
declare
  --标记值, 若为 1 则是素数, 否则不是
  v_flag number(1) := 0;
begin
   for i in 2 .. 100 loop
       v_flag := 1;     
         
       for j in 2 .. sqrt(i) loop
           if i mod j = 0 then
              v_flag := 0;
              goto label; 
           end if;        
       end loop;
       
       <
这个有分号,这个不用加尖括号,比刚刚那个效率高,就相当于我们JAVA里面讲的continue,这个题就是

这样写的,这是用两种方式,相当于三种方式,while循环,for循环,还有使用goto这种格式的,goto就是这个意思,

后边这还有一个练习,就是这个
	   
11+.打印1——100的自然数,当打印到50时,跳出循环,输出“打印结束”
(方法一)
begin
  for i in 1..100 loop
      dbms_output.put_line(i);
      if(i = 50) then 
      goto label;
      end if;
  end loop;
      
      <

plsql(轻量版)_流程控制_第47张图片

plsql(轻量版)_流程控制_第48张图片

从1打到99,使用goto标签的形式,或者呢有没有别的方式,这个我们就说完了,如果等于50,

让他exit,这个不要了,这个没法打印结束了,那就加上一个dbms_output.put_line('打印结束'),

begin

	for i in 1..100 loop
	
		if i = 50 then dbms_output.put_line('打印结束');
		
		exit;
		
		end if;
		
		dbms_output.put_line(i);
		
	end loop;
	
end;

plsql(轻量版)_流程控制_第49张图片

plsql(轻量版)_流程控制_第50张图片

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(ORACLE)