PL/SQL这一块,整个这一块需要大家掌握什么,就是他基本的格式,PL/SQL,基本的语法格式,
如何声明一个变量,然后程序从哪里执行,执行的格式是什么,出现异常怎么处理,基本的语法格式,
就这样写吧,第二个就是定义一个变量,变量赋个值,给他打印一下,这是最基本的了,然后定义多个变量,
然后分别把多个变量都打印,然后你变量很多的话,把这个变量放到一个叫记录类型里,记录类型,就好像JAVA里面的类
一样,我把这几个变量放在一个类中,我们讲JAVA的时候讲了一个类,里面有成员变量,然后创建这个类的对象,对象去调用
这几个成员变量,可以赋值,可以打印,这里面有点类似,我声明一个记录类型,这个类型这样写的,type谁谁谁,is,然后就可以
写is record,这个就是记录类型,这个类型可以看成类似于一个函数的概念,可以给他分成多个变量,然后就分号结束,这就是
一个记录类型,逗号之间,变量声明,JAVA里面的成员变量,记录类型你可以看成是一个类,然后有记录类型的一个变量,相当于
他的对象,用对象去调里面的变量,你可以赋值,这叫记录类型,记录类型完了以后,这个相当于我们给他输出了一个,输出了
一条语句,你只能输出一条,一个对象对应一个这个,你要输出多个的话,又涉及到循环结构了,在PL/SQL里边,流程控制,流程控制
就分成两个,叫条件判断,基本上每个语言,都有基本的流程控制,条件判断和循环,这样两块,那么条件判断这一块,它使用的有
两种,一种叫if,then,然后,elseif then,else,就这结束了,else是最后一种情况,记得最后加上endif,表明你这个if是结束的,
因为它里边没有像JAVA里面讲的大括号,我们大括号可以明确的指出来,他这里没有,没有的话就用关键字去结束了,最后叫end if,
这是一个,方式一,还有一种方式,case,这个我们接触过,SQL里面接触过,when这种情况,再when再then,最后就直接加上这种情况,
有一个end,end结束,这是条件判断的两种方式,我们给大家讲到时候,还有一个循环结构,这个呢有三种,方式三,三种,一个叫
loop,循环,省略号就相当于写循环体了,循环什么东西,然后你得指明结束的条件,exit when,当循环这个条件的时候,就结束,
然后end loop,表示结束,我们讲循环的时候,JAVA里面说了,有定义了四部分,条件,循环体,循环的迭代部分,还有循环的条件,
循环的条件就是你终止的条件,那显然你的循环体是放在这儿的,然后exit when,相当于循环条件,就是什么时候终止,然后你要
有迭代的话,这里面也行,放到这一块也行,最后还是结束,第二种方式叫while,当你怎么着的时候,我就开始执行这个循环体,
执行完了以后,就end loop,这是第二种方式,最后一种,for呗,for他定义一个变量,写上一个i,定义一个变量,让这个变量从哪哪开始,
并且到哪哪结束,这跟我们JAVA里面很像,JAVA里面也是定义一个局部变量i,然后让i从1开始,i小于等于100,他也是这种类似的格式,
指明它是loop循环,最后给他end一下,三种格式讲完了以后呢,基本的流程控制就说完了,然后这里还涉及到两个关键字,比如他
讲的goto,他就是像我们JAVA里面讲的break,后面可以加一个参,表示跳出他指定那一层的循环,然后这goto也是这个效果,
它相当于我们刚才说的break,就叫goto,还有一个叫exit,表示退出,是两个关键字,然后流程控制,流程控制完了以后,
我们声明一个记录类型,我把100号员工的,工资,hire_date,employee_id,给他输出出来,你可以把他整个看成是一个标签,
一个对象,你要想输出多个record对象的话,比如80号部门的,所有员工的他的信息,那就得走一个循环,再输出一条,再输出循环,
要用到流程控制的部分,还需要用到一个概念,叫游标,游标的使用,这是讲这个,多条语句的话,他呢可以这样理解,类似于JAVA中的,
Iterator,迭代器,迭代器的作用是什么,作用于集合,用于集合的遍历,是吧,集合遍历的时候使用的是游标,他两的作用是类似的,
游标,一个箭头,输出这一条以后,再往下,再往下,整个效果不是遍历吗,就是这个意思,游标的使用,其实我们想,上面的四点都是为了
后面做铺垫,还有一个,第五个,异常的处理,每一个语言,稍微成熟一点的话,一定会考虑到异常如何来处理,比如人生病一样,
语言多强大,这个人多壮,你再壮也可能生病,一旦出现异常的时候,你就告诉我生病了怎么办,那你就要考虑到异常的处理,PL/SQL
同样如此,他异常的处理和JAVA有点不一样,JAVA里的try catch,throws两种方式,他这里有三种方式,这就不具体写了,到时再说,
讲这前五个,都是为了第六个和第七个做铺垫的,讲前面这些,希望我们学PL/SQL,目标就是为了大家掌握第六点和第七点,会写一个,
存储函数,还有叫存储过程,就是前面这些东西,就跟你做select语句一样,select完了以后,保存不下来,你留不住,就是你这次用了
就完了,下次还得重写,那么写一个存储函数,或者存储过程,这个是可以保存到硬盘中的,这次你写完了,下次你想调,就直接来调,
你想左边这,第三项就叫函数
存储函数,还有叫存储过程,就是前面这些东西,就和你说select语句一样,select完了以后他保存不下来,你留不住,
就是你这次用了就完了,然后下次还得重写,那么写一个存储函数,或者存储过程,这个是可以保存在硬盘中的,这次你
写完了,下次你想调,直接来调,你像左边这,第三项叫函数,Functions,这个就是存储函数,当你写的存储函数就放到这,
就类似于你写一个表一样,表的话我们关机开机表都有,这个存储函数也有,你这个函数这个东西可以多次调用,这个是需要
我们大家可以写的,特别复杂的,可以写好多行的,不用,毕竟我们不是做PL/SQL程序员,你会写一个基本的存储函数,存储过程,
他两有啥区别,你把他两看成是函数,这里有返回值,这里没有返回值,就这个区别,当你写存储函数和存储过程的时候,我会用到
上面讲的这些,如果有多条语句,游标了,用到循环,然后如果变量很多的话,我们可以 把变量放到记录类型里面,这个都涉及到了,
假设我要查询一个employee_id,作为一个自变量,我存到这个函数里边,返回这个人的工资,这个人没有的话,你告诉我怎么办,
就有异常处理,所以写这两个呢,会用到上面的一些东西,第七个,会写一个触发器,触发器是另一个东西,trigger,你看这,这里有一个
叫Triggers,这个就是触发器,触发器跟这个名字很像,你操作一个什么东西,他就自动的触发了他,然后他就开始执行,相当于后台的
一个进程一样,这样来理解,他也是可以让我们去编写一个的,有点类似于函数,但是比这两个感觉上要简单一些,这是我们讲整个SQL的
整个格式,内容,上节课稍微提了一下记录类型,再回忆一下
包括前面说的如何来定义一个变量,我们习惯用v下划线表示变量,起个名,常量C开头,异常E开头,
然后游标,游标的英文就是cursor,表明这个是一个游标,记录类型,加一个record,表明是记录类型
然后复合类型,我们再回一下一下把之前的说一说
变量,记录类型等声明,比较像类里的成员变量,都放这,整个程序在运行的过程中,需要用到哪些变量,
你需要定义的,都放在declare里,一个定义,一个赋值,当然你要放在begin里也行,就是变量的声明放到这,
赋值的时候放在begin里也可以,因为begin是我们程序真正的执行部门,这个程序执行过程当中,如果出现异常的话,
我们要考虑异常的处理,所以加了一个exception,就是异常的处理,这里完了以后,我这个程序就结束了,end加上分号
结束,那比如我们写一个,我现在想查询一下,这个employees表当中的,employee_id员工的,工资是多少,他的工资是
多少,相当于我只要在这里查询这个人的工资,给他放在一个变量里,把这个变量打印出来,那我就在这里定义一个变量,
v_sal,这个变量,这个变量的类型,number类型的,工资给他定义成8位的,两位小数,你要给他指定一个值也行,这里面需要注意,
在PL/SQL当中,赋值的话,是冒号等于,JAVA中是啥,是等于,JAVA中要想判断谁跟谁等不等,是等等,我们PL/SQL中就是等了,SQL里
也是等,所以如果等号表示真正的相等了,定义一个变量,我就放在这里执行,执行的时候,一个PL/SQL语句块,一个增删改查,他都
可以用,只不过查的时候,不是select了,是select into,因为用到变量了,select salary,into这个v_sal,放到这个变量里,
然后哪个表里的,from employees,where employee_id,等于123,这个人的工资,给他放在这个变量里,写PL/SQL语句的时候,
标点是很呕心的,你要是习惯于把它打成多行,打成多行就这样,在这是没有标点的,在最后是有的,放到这个变量里了,
变量里你想打印,你得再输出一下dbms_output.put_line,然后把v_sal给他打印出来,你也可以在这里标注一下,是工资,
salary,是多少,这儿呢不涉及到异常处理,所以我们先给他干掉,end结束,我这一执行的话,有可能出来,但是没东西
declare
v_sal number(8,2) := 0;
begin
select salary into v_sal
from employees
where employee_id = 123;
dbms_output.put_line('salary: '||v_sal);
end;
set serveroutput on,这个每次都要记得,没分号
必须把这个开启了,表明可以打印东西
6500光出工资,是谁我不知道,想看看是谁,加一个employee_id,id的话,你不能在这写employee_id了,
因为它识别不了,还得放在一个变量里,number类型的,这里你给他指定值也行,不指定也没事,不指定的话
你在这给他写上,select salary,employee_id,into他,逗号v_emp_id,放在这两个变量里,记住要对应,
salary定义在这里的是第一个的,这是第二个,类型得相互匹配的,然后你再打印就可以了,就这样
declare
v_sal number(8,2) := 0;
v_emp_id number(10);
begin
select salary,employee_id into v_sal,v_emp_id
from employees
where employee_id = 123;
dbms_output.put_line('employeeid:'||v_emp_id||'salary:'||v_sal);
end;
employeeid 123,工资6500,加一个hire_date,加一个email,那你就在这加呗,v_email,email类型是
varchar类型的,20,没有赋值,v_hire_date,date类型的,分号,每一个声明都分号结束,然后依次的把这几个
给你放进去,email,hire_date,这四个依次放入你刚才声明的变量里,然后打印就可以了,然后我们把这四个
变量打印
declare
v_sal number(8,2) := 0;
v_emp_id number(10);
v_email varchar2(20);
v_hiredate date;
begin
select salary,employee_id,email,hire_date into v_sal,v,emp_id,v_email,v_hire_date
from employees
where employee_id = 123;
dbms_output.put_line('employeeid: '||v_emp_id||'salary: '||v_sal||'email: '||v_email
||'hire_date'||v_hiredate);
end;
这就是定义的信息,就这样操作,这里是定义了几个成员变量,这里是给成员变量赋值,这就是打印,
就这个意思,有了这个以后,我们说这几个成员变量,叫成员变量还有点牵强,成员变量有类,有类才会
有成员变量,这里连类也没有,这个变量,我给他放到一个记录类型里,记录类型你可以假设,当然没有这么说的,
你可以看成是JAVA中的一个类,既然是个类,JAVA类里面就可以有这么几个变量,然后我再造一个类的对象,一个对象
就可以有这几个变量的,我们再有一个记录类型,记录类型的话是这样,格式type,取个名,emp_record,is record,
这个名字就是一种习惯,你不这样写没事,type记录类型的名字,它是一个record指明,然后括号里面指明这个变量,
就是我们刚才声明的这一个,最后加上一个括号,给他括起来,分号结束,然后改,这个就不要了,这就声明了一个记录类型,
声明了一个记录类型,相当于是一个类,通过类的对象去调用成员变量的,声明一个记录类型,然后这儿呢你要提供一个记录
类型的变量,声明一个记录类型的变量,变量v开头的,v_emp_record,他这个变量是这个类型的,分号结束,就这样写,既然是一个
变量,我们在JAVA里面有点类似于一个对象,这个变量拥有这几个变量,然后我在下面写的时候就不用这么写了,我select依次放入
这几个变量,不用写这几个变量了,直接放在这里,放到他里边,然后打印的时候,打印的是这个变量的,相当于是这个对象的成员
变量,这个对象的他
declare
type emp_record is record(
v_sal number(8,2) := 0,
v_emp_id number(10),
v_email varchar2(20),
v_hiredate date
);
v_emp_record emp_record;
begin
select salary,employee_id,email,hire_date into v_emp_record
from employees
where employee_id = 123;
dbms_output.put_line('employeeid: '||v_emp_record.v_emp_id||','||'salary: '||v_emp_record.v_sal
||','||'email: '||v_emp_record.v_email||','||'hire_date: '||v_emp_record.v_hiredate)
end;
当然理解上不一样了,你原来的要好一点了,他这里是一个整体来出现的,record这个对象,你要写一个简单的也行,
比如最简单的就是declare,我声明一个type,salary_record is record,有一个括号,分号结束,要是变量不多的话,
多的话你就写成多行,定义两个变量,定义v_name,v_name是varchar2,v_salary是number类型的,定义了一个记录类型,
然后给一个记录类型的变量,它是他这个类型的,结束,这个就是declare就写完了,再写上begin,这是程序执行的部分,
他的这个变量,v_name,赋值冒号等于,刘德华,v_salary记录类型的,冒号等于这个值,然后打印,打印的话,你直接打印他不行,
看不着,打印他,然后结束有分号
declare
type salary_record is record(
v_name varchar2(20),
v_salary number(10,2)
);
v_sal_record salary_record;
begin
v_sal_record.v_name := '刘德华';
v_sal_record.v_salary := 120000;
dbms_output.put_line('name:'||v_sal_record.v_name||'salary:'||v_sal_record.v_salary);
end;
比刚才那个要简单,这一个基本的,这也是一个记录类型,是我们自己定义了一个,他你看成是一个类,
类里面两个变量,声明一个类的对象,对象调的属性,给属性赋值,然后打印对应的属性,所以你要是会一个编程语言的时候,
当然有其你还会一些复杂的,然后再学这些简单的时候,你会触类旁通,这就是说人的大脑的这个,很牛的一个功能,就是一种
联系你想到了,所以人不可以失去联想,这个叫记录类型的概念,记录类型是干什么的,如果你想打印或者操作这几个变量,
这几个变量有点多,我可以把它放在一个记录类型里,变量有点多,我把一个变量放到记录类型里,操作这个记录类型的对象,
到这里不叫变量,叫对象,操作记录类型的变量,通过记录类型的变量来操作变量,就是记录类型的一个作用,我们再回到刚才
这个例子,刚才写的这个例子,打印employees表里信息的,这个我们刚才说,记录类型里面这几个变量,实际上我们操作的是
employees表里面的变量依次的赋给记录类型里的变量,当然我们这里面,有可能像我们的id,什么salary,工资,你不能整太小了,
整太小了以后,当你把salary往里放的时候,可能放不进去了,给我整这个,工资用一个4位数来表示,用了两位数小数
declare
type emp_record is record(
v_sal number(4,2) := 0,
v_emp_id number(10),
v_email varchar2(20),
v_hiredate date
);
v_emp_record emp_record;
begin
select salary,employee_id,email,hire_date into v_emp_record
from employees
where employee_id = 123;
dbms_output.put_line('employeeid: '||v_emp_record.v_emp_id||'salary:'||v_emp_record.v_sal||
'email:'||v_emp_record.v_email||'hire_date:'||v_emp_record.v_hiredate);
end;
为了防止我出错,我们有一个百分号type的一个词,他表示什么意思,我这儿就不写他了,我们这里可以不要了,
反正下面已经重新指定了,我让他和employees表里的,salary工资的声明的类型和精度是一样的,用百分号type,
表明这个类型是一样的,同样的这里这样来修改,date你改也行,不改也行,他这个大小是不变的,就这样,声明了
几个类型,动态的来获取,相对应employees表里的,叫字段也好,或者叫列也好
declare
type emp_record is record(
v_sal employees.salary%type,
v_emp_id employees.employee_id%type,
v_email employees.email%type,
v_hiredate employees.hire_date%type
);
v_emp_record emp_record;
begin
select salary,employee_id,email,hire_date into v_emp_record
from employees
where employee_id = 123;
dbms_output.put_line('salary:'||v_emp_record.v_sal||'employeeid:'||v_emp_record.v_emp_id||
'email:'||v_emp_record.v_email||'hire_date:'||v_emp_record.v_hiredate);
我们还是可以再升级一下,这个需要大家会,我们这里面也有,然后你现在只是获取了employees表里的个别几个列,
我现在想获取所有的列,所有的列也都放在一个记录类型里面,那我们就依次在这里给他多写几列,把每一个列都写
出来,然后select的时候每一个列都分别赋给record这个变量里,然后打印的时候,把他里面的这么多都打了,这是一种
方式,再一种方式呢,说一个他这里面的注释,就是杠杠,单行注释,多行注释和JAVA里面一样,我把刚才的声明都给注了,
v_emp_record,这个叫记录类型,employees%rowtype,这个employees表里的对象,然后每一列什么类型的,我完全跟你一样,
我们在这里处理的时候,将employees表里的信息全放到record里面,然后呢我再打印一个信息,你想打谁就打谁,你这个就不能
这样写了,因为你上面没有声明,相当于也可以给他声明,跟你这里面的名一样,所以这里是employee_id,举几个例子,我就从
这里面输出几项,salary,email,hire_date,当然还有其他的,比如department_id,我输出一下你这个变量里面的,几个你想输的字段
declare
v_emp_record employees%rowtype;
begin
select * into v_emp_record
from employees
where employee_id = 123;
dbms_output.put_line('employeeid:'||v_emp_record.salary||'salary:'||v_emp_record.salary
||'email:'
||v_emp_record.email||'hire_date:'||v_emp_record||'department_id:'||v_emp_record.hire_date);
end;
这儿呢更简洁,这儿你不能看成是一行,这其实也是一个记录类型,只不过这个记录类型,
跟你employees这个表的结构,一样的,所以我就一行给你代替了,rowtype它是使用在表的,
你这里只是使用在某一列的,某一列的加上百分号type,跟你一列的类型一样,这个是跟表的类型一样,
然后select *往里面放就完了,就是这个,那这个升级的话,你要再升还可以升级,升级什么,这个写死的,
这个定一个,123,声明一个,v_emp_id,类型,10,然后呢,就这样写吧,在这赋值,冒号等于,我们不写123了,
v_emp_id,动态的来获取这个值,有一个变量
declare
v_emp_record employees%rowtype;
v_emp_id number(10);
begin
v_emp_id := 133;
select * into v_emp_record
from employees
where employee_id = v_emp_id;
dbms_output.put_line('employeeid:'||v_emp_record.employee_id||'email:'||v_emp_record.email||
'salary:'||v_emp_record.salary||'hire_date:'||v_emp_record.hire_date);
end;
这又换人了,就是这个人,讲记录类型,我们刚才讲的都是select,当然除了select以外,还有增删改,
写一个,decalre,改吧,改一个,把某个人的工资给他加上100,某个人的工资给他加上100,把谁的工资
给他加上100,就定义一个变量,id number类型的,10,执行,执行update这样一个概念,update employees,
set,set salary,salary加上100,where employee_id等于v_emp_id,v_emp_id赋个值,dbms_output.put_line,
打印salary打印不了,改了要放到一个变量里面才行,我这里就不打了,输出一个说执行成功,end
declare
v_emp_id number(10);
begin
v_emp_id := 133;
update employees
set salary = salary + 100
where employee_id = v_emp_id;
dbms_output.put_line('执行成功');
end;
我开始写了一个触发器,一执行表的update操作就执行了,这里你就能够看到触发器的作用,
这里我给他rollback,记录类型,你把这个概念搞清楚,我们下一个要讲的就是流程控制了