PL/SQL 是用游标来管理 SQL 的 SELECT 语句的。游标是数据库操作系统为了处理这些语句而分配的一块内存,它提供了对一个结果集进行逐行处理的能力,可看作是一种特殊的指针。它与某个查询结果集相关联,可以指向结果集的任意位置,以便对指定位置的数据进行处理,使用它可以在查询数据的同时对数据进行处理。
--隐式游标示例
begin
update employee set empName='张三三' where empId=1000;
if sql%found then
dbms_output.put_line('成功更新了一条数据');
else
dbms_output.put_line('没有找到相关的数据数据');
end if;
end;
--示例二,删除,notfound
begin
delete from employee where empId=2000;
if sql%notfound then
dbms_output.put_line('没有找到相关的数据');
end if;
end;
--示例三,rowcount
begin
delete from employee;
if sql%rowcount=0 then
dbms_output.put_line('没有找到相关的数据');
else
dbms_output.put_line('删除了'||sql%rowcount||'条数据');
end if;
end;
--显示游标
declare
cursor cur_emp(myAge int) is
select * from employee where age>myAge;
empRow employee%rowType;
begin
open cur_emp(20);
loop
fetch cur_emp into empRow;
exit when cur_emp%notfound;
dbms_output.put('员工编号'||empRow.empId);
dbms_output.put(' 员工名称'||empRow.empName);
dbms_output.put_line(' 员工年龄'||empRow.age);
end loop;
close cur_emp;
end;
--游标for循环
declarecursor cur_emp(theJob varchar2)
is
select * from employee where job=theJob;
begin
for theRow in cur_emp('CLERK')
loop
dbms_output.put('员工编号:'||theRow.empNo);
dbms_output.put(' 员工名称:'||theRow.empName);
dbms_output.put_line(' 员工工资:'||theRow.sal);
end loop;
end;
--进一步简化
begin
for theRow in (select * from employee where job='CLERK')
loop
dbms_output.put('员工编号:'||theRow.empNo);
dbms_output.put(' 员工名称:'||theRow.empName);
dbms_output.put_line(' 员工工资:'||theRow.sal);
end loop;
end;
--游标变量,针对于多个sql,或者是运行的时候才确定sql到底该如何写
--需求,如果输入的标志量为1,要求输出工资大于等于2000的员工相关信息
--如果标志量为2,要求输出工资大于等1000小于2000的员工相关信息
--标志量为3,要求输出工资小于1000的员工相关信息
--利用系统自带的scott,
--解锁一下alter user scott identified by tiger account unlock;
--先演示一个游标代表一个sql查询的情况
declare
cursor cur_emp1 is select * from employee where job='CLERK';
cursor cur_emp2 is select * from employee where sal>5000;
cursor cur_emp3 is select * from employee where gender='男';
theRow employee%rowtype; --代表一行的变量
flag int:=0;
begin
flag:=&qq;
if flag=0 then
begin
--操作第一个游标
open cur_emp1;
loop
fetch cur_emp1 into theRow;
exit when cur_emp1%notfound;
dbms_output.put('员工编号:'||theRow.empNo);
dbms_output.put(' 员工名称:'||theRow.empName);
dbms_output.put_line(' 员工工资:'||theRow.sal);
end loop;
close cur_emp1;
dbms_output.put_line('-------这是分割线---------------');
end;
elsif flag=1 then
begin
--操作第二个游标
open cur_emp2;
loop
fetch cur_emp2 into theRow;
exit when cur_emp2%notfound;
dbms_output.put('员工编号:'||theRow.empNo);
dbms_output.put(' 员工名称:'||theRow.empName);
dbms_output.put_line(' 员工工资:'||theRow.sal);
end loop;
close cur_emp2;
dbms_output.put_line('-------这是分割线---------------');
end;
else
begin
--操作第三个游标
open cur_emp3;
loop
fetch cur_emp3 into theRow;
exit when cur_emp3%notfound;
dbms_output.put('员工编号:'||theRow.empNo);
dbms_output.put(' 员工名称:'||theRow.empName);
dbms_output.put_line(' 员工工资:'||theRow.sal);
end loop;
close cur_emp3;
end;
end if;
end;
--然后演示游标变量(用一个游标代表多个sql查询)
declare
--定义游标变量的类型
type RefEmpCur is ref cursor return employee%rowtype;
--通过游标变量可以定义游标
empCur RefEmpCur;
theRow employee%rowtype; --代表一行的变量
flag int:=0;
begin
flag:=&tt;
if flag=0 then
open empCur for select * from employee where job='CLERK';
elsif flag=1 then
open empCur for select * from employee where sal>5000;
else
open empCur for select * from employee where gender='男';
end if;
loop
fetch empCur into theRow;
exit when empCur%notfound;
dbms_output.put('员工编号:'||theRow.empNo);
dbms_output.put(' 员工名称:'||theRow.empName);
dbms_output.put_line(' 员工工资:'||theRow.sal);
end loop;
close empCur;
end;
注意:游标变量案例里面不要使用游标for循环
小技巧:在PLSQL Developer中,执行for update 命令能直接从excel复制大量数据到表中
--for update操作
--select * from employee for update;
--可以从excel复制的方式直接导入大量数据(注意excel最前面要复制一个空的列)