叫游标的使用,游标,以前没有听过这个名,什么是游标,他的作用是什么,如何来声明,怎么来使用,
主要是你要掌握他是干嘛的,怎么用,游标,在PL/SQL程序当中,对于处理多行记录的事务,经常使用游标来实现,
处理多行的
在PL/SQL程序当中,对于处理多行记录的事务,经常使用游标来实现,处理多行的,我们刚才写的程序,
你像这打印80号部门的,这里涉及到很多人了,我们考虑说使用游标,用于处理多行记录,你看我们上面用的
时候其实并没有用着这个概念,某个人的情况,如果变量多的话,我们用记录类型,来存储你这个变量,然后分别
再打印,相当于只是一条数据,如果你想处理多条数据的话,就要使用到游标这样一个概念,游标是一个指向上下文的
一个句柄或者指针,有点像我们的iterator这个
显示的游标,还有隐式的,显示的游标处理,需要四个PL/SQL的步骤,对应这个蓝色的,第一步叫定义一个游标,
叫cursor什么什么,肯定select一个什么东西,给他定义好了,定义好了以后,我就打开一个游标,打开这个游标就是open,
游标名,就完了,程序不能用open重复打开一个游标,就打开一次,然后提取游标的数据,JAVA里面用next返回一个游标的
数据,提取游标使用的的是fetch,游标的名,into放在一个变量里,或者放在一个记录类型里,一个变量,一个记录类型,
都可以,最后游标还需要关闭,对游标使用的四个步骤,然后不能有into了
12.1 使用游标
要求: 打印出 80 部门的所有的员工的工资:salary: xxx
declare
--1. 定义游标
cursor salary_cursor is select salary from employees where department_id = 80;
v_salary employees.salary%type;
begin
--2. 打开游标
open salary_cursor;
--3. 提取游标
fetch salary_cursor into v_salary;
--4. 对游标进行循环操作: 判断游标中是否有下一条记录
while salary_cursor%found loop
dbms_output.put_line('salary: ' || v_salary);
fetch salary_cursor into v_salary;
end loop;
--5. 关闭游标
close salary_cursor;
end;
如果打印一个人直接定义一个 变量就是,操作这个,declare,然后,begin,最后一个end,打印80号部门的员工的工资,
格式是这样子的,这个肯定是我定义一个变量,把这个工资给他放在变量里,那我们先定义一个,v_sal,employees这个表里的,
salary跟他是一样的,然后下边我们要使用游标了,因为有多个人,首先要定义一个游标,定义游标,cursor起个名,emp_sal_cursor,
is select salary from employees where department_id,id等于80,把80号部门员工的salary给他定义成一个游标,那这个
就写完了,定义游标,第二步,叫打开游标,打开就是open,把它打开,第三步叫提取游标,fetch叫获取这个游标,你看看这个格式,
fetch什么什么into,因为你这个游标只记录一条salary,把它into到一个变量里,fetch到这里面,因为这里面有多条记录的,
那你就肯定有多个值,怎么来表示这多个值,这里面我们要用到一个循环,while你游标的这个变量,他百分号found,一旦你这个游标,
看你这里面是否还有值,有点像我们的hasNext,判断下一个是否还有值,found本身这个时候是否还有值,如果有值的话,
执行这样一个循环,循环的结果是把他的工资给他输出出来,打印一下,打印这个,直到你没有,你得取完一次之后,
while你得有一个迭代条件,取完之后,你得再取一次,取下一次,再取一次,
然后再取再取直到没有了,end loop,结束,这个时候打印的效果就是把80号部门的所有的工资都打印了
declare
v_sal employees.salary%type;
cursor emp_sal_cursor is select salary from employees where department_id = 80;
begin
open emp_sal_cursor;
fetch emp_sal_cursor into v_sal;
while emp_sal_cursor%found loop
dbms_output.put_line('salary:'||v_sal);
fetch emp_sal_cursor into v_sal;
end loop;
end;
这个肯定是80号部门的,这个感觉不太理想,那你就再加上一个id呗,光有工资,不知道人是谁,忘了这个啥,
关,关闭游标,就是close,这个是一个完整的使用游标的代码,定义一个游标,然后打开,然后取,取到哪儿,
你要是只select一个东西,那相应的还得定义一个变量,把select这个东西放到变量里,然后这个变量我仅仅是
输出了一下,在提取游标的时候,因为它是多条记录,需要我们使用一个循环的结构,依次的给他取出来,直到他没有,
所以使用的是百分号found,他是否还有值,当然最后给他关闭游标
declare
v_sal employees.salary%type;
cursor emp_sal_cursor is select salary from employees where department_id = 80;
begin
open emp_sal_cursor;
fetch emp_sal_cursor into v_sal;
while emp_sal_cursor%found loop;
dbms_output.put_line('salary:'||v_sal);
fetch emp_sal_cursor into v_sal;
end loop;
close emp_sal_cursor;
end;
如果我想看谁的工资是多少,那你相应的还得定义一个变量,v_empid,然后select salary,employee_id,
from这个,然后into v_sal逗号v_empid,放到这两个变量里,然后打印一下,然后打印一下id,就这样呗,
然后fetch的时候他是取两个变量
declare
v_sal employees.salary%type;
v_empid employees.employee_id%type;
cursor emp_sal_cursor is select salary,employee_id from employees where department_id = 80;
begin
open emp_sal_cursor;
fetch emp_sal_cursor into v_sal,v_empid;
while emp_sal_cursor%found loop
dbms_output.put_line('empid:'||v_empid||'salary:'||v_sal);
fetch emp_sal_cursor into v_sal,v_empid;
end loop;
close emp_sal_cursor;
end;
这就是谁他的工资是多少,你要是用SQL语句的话,select employee_id,salary from,employss,
where department_id等于,80,
select employee_id,salary from employees where employee_id = 80;
你用PL/SQL写的话要使用游标,分别定义两个变量来存那两个值,里边还可以用到循环,
这就是这个例子,然后呢,如果我想再想除了打印employee_id和salary之外,还想打印hire_date,
email,什么department_id,变量是不是有很多了,多的时候用什么,得用记录类型,我们现在就使用一个记录类型,
我在这上面改,声明一个记录类型,type,emp_record is record,然后是一个小括号,括起来,分号结束,这里边把他两
扔进来,你也可以再加上一个变量,这个用逗号隔开,这声明一个记录类型,然后声明一个记录类型的变量,记录类型的变量,
v_emp_record,emp_record这个类型的,一个变量,然后定义游标,该有的还是有,打开游标,提取游标,提取的时候,不是into
到这里,而是into到记录类型的变量里,放到变量里,然后这个放的时候,因为你这里取,取的时候是先取的salary,再取的id,
放的时候是先放他再放他,你这个定义这个的时候,也是先定义salary,再定义id,它会依次的按照从前往后的顺序,格式对应,
打印就是打印他的,记录类型变量的,然后你再去取,再去into到记录类型的变量里,能理解不,然后最后关闭游标
declare
type emp_record is record(
v_sal employees.salary%type,
v_empid employees.employee_id%type
);
v_emp_record emp_record;
cursor emp_sal_curosr is select salary,employee_id from employees where department_id = 80;
begin
open emp_sal_cursor;
fetch emp_sal_cursor into v_emp_record;
while emp_sal_cursor%found loop
dbms_output.put_line('empid:'||v_emp_record.v_empid||'salary:'||v_sal);
fetch emp_sal_cursor into v_emp_record;
end loop;
close emp_sal_cursor;
end;
declare
type emp_record is record(
v_sal employees.salary%type,
v_empid employees.employee_id%type,
v_hiredate employees.hire_date%type
);
v_emp_record emp_record;
cursor emp_sal_cursor is select employee_id,salary from employees where department_id = 80;
begin
open emp_cursor_record;
fetch emp_sal_record into v_emp_record;
while emp_sal_cursor%found loop
dbms_output.put_line('empid:'||v_emp_record.v_empid||'salary:'||v_emp_record.v_sal||
'hire_date:'||v_emp_record.v_hiredate);
end loop;
close emp_sal_cursor;
end;
这就是三个变量,相当于把游标和记录类型给结合起来了,他两的作用不一样,一个是用于存储
多个变量的,叫记录类型,一个是用来输出多行记录的游标,就是这样一个概念,游标对应的有4步,就这四步,
布尔类型的,判断你是否还有记录,有found,也有not found,已经被打开了,使用这个比较多
游标的for循环要注意,我们刚才是使用while循环来实现的,while你这个游标的变量,然后他是否是found的,
for循环啊,他就能够把我们刚才的四步减省减省,我们这里说的是这样四步,while循环这样来用
使用for的时候可以简写,PL/SQL还提供了for循环语句,自动的执行open,fetch,close,和循环语句的功能,
当进入循环的时候,游标for循环会自动的打开游标,然后并提取第一行记录,当程序处理完当前锁提取的数据,
而进入下一次循环时,游标for循环也会自动的提取下一行数据供程序处理,当提取完结果集中所有数据的时候,
并自动的关闭,for什么什么in,相当于我这个程序里边,就正常还是有这样四步的,这四步还是有的,只不过使用for
循环的时候,这三步能自动的来做一些事了,现在给他改成for循环,使用for循环同样实现刚才的这个,这个怎么来做,
它能够自动的打开,我就直接for了,for指定一个局部变量,是吧,这个局部变量我就定义成一个,c,in,in就是in游标的
变量,然后loop,loop完了以后,这个想干什么,想打印这个东西,先打印这个,打印完了以后,也会自动去取,然后直到你
结束,end loop结束,结束完了,关也不用关了,然后在end,这个得改一改,我select这个,for他,他就相当于是一个局部变量,
c的salary
declare
type emp_record is record(
v_sal employees.salary%type,
v_empid employees.employee_id%type,
v_hiredate employees.hire_date%type
);
v_emp_record emp_record;
cursor emp_sal_cursor is select from salary,employee_id,hire_date from employees
where department_id = 80;
begin
for c in emp_sal_cursor loop
dbms_output.put_line('empid:'||c.employee_id||'salary:'||c.salary||
'hire_date:'||c.hire_date);
end loop;
end;
这个游标他本身是指向employees的三个字段,记录类型我们就不要了,我们就定义一个游标就可以了,
然后就直接打印,因为我们开始是把游标放到记录类型里,这个都已经给删了,所以当然这个就不合适了,
这是这种方式,就是理解上要难一点,本身他也是有这样四步的,只不过后三步给for循环给解决了,这就是使用
游标的概念,这个就大同小异了
13. 使用游标的练习:
打印出 manager_id 为 100 的员工的 last_name, email, salary 信息(使用游标, 记录类型)
declare
--声明游标
cursor emp_cursor is select last_name, email, salary from employees where manager_id = 100;
--声明记录类型
type emp_record is record(
name employees.last_name%type,
email employees.email%type,
salary employees.salary%type
);
-- 声明记录类型的变量
v_emp_record emp_record;
begin
--打开游标
open emp_cursor;
--提取游标
fetch emp_cursor into v_emp_record;
--对游标进行循环操作
while emp_cursor%found loop
dbms_output.put_line(v_emp_record.name || ', ' || v_emp_record.email || ', '
|| v_emp_record.salary );
fetch emp_cursor into v_emp_record;
end loop;
--关闭游标
close emp_cursor;
end;
(法二:使用for循环)
declare
cursor emp_cursor is
select last_name,email,salary
from employees
where manager_id = 100;
begin
for v_emp_record in emp_cursor loop
dbms_output.put_line(v_emp_record.last_name||','||v_emp_record.email||','
||v_emp_record.salary);
end loop;
end;
打印出manager_id为100的员工的信息,使用游标,记录类型,你就看一下这个题,使用一个游标和记录类型,因为这里面声明了
三个变量,有点不少,不少我就可以把他们放到一个记录类型里,这样来声明,就没问题,然后声明记录类型,就要定义一个记录类型
的变量,然后把游标的变量放到into的这个记录类型里,然后声明一个游标,他选择了employees表里的信息,id是他的条件的,
然后打开游标,提取游标,这个游标放到记录类型变量里面去,一旦你这个游标能够找到值的时候,把相应的记录类型的这几个属性
给他打出来,然后再取,这个一定不要忘了,再取end,关闭,如果使用for循环就简单了,for循环记录类型也没了,我就直接指向你那个
表就完了,声明一个cursor,就选择employees的那三列,直接一个for循环,in这个定义的cursor他,loop来执行,直接打印这个变量的,
对应employees表里的,没有再定义记录类型,跟我们刚才写的大同小异的