begin
语句块中,可以直接编写增删改操作的sql语句;
insert into stu values(1001,'zhangsan');
update stu set stuname='zs' where stuid=1001;
delete from stu where stuid=1001;
commit;
在语句块中,如果需要查询(select),不能直接编写查询语句
如果一定要写查询,必须接收查询结果;接收查询结果,主要依靠游标来接收
end;
显示游标和隐式游标
set serveroutput on;
隐式游标:
declare
v_no emp.empno%type;--后面用来指定v_no的类型,表示与emp表的empno字段的类型一致;
v_name emp.ename%type;
v_sal emp.sal%type;
begin
select empno,ename,sal into v_no,v_name,v_sal from emp;
dbms_output.put_line('v_no:'||v_no);
dbms_output.put_line('v_name:'||v_name);
dbms_output.put_line('v_sal:'||v_sal);
exception
when TOO_MANY_ROWS then dbms_output.put_line('返回了太多行了');
end;
上面,接收了一个或有限的几个字段值,如果一张表里有很多字段,而且都要查询的时候?
例子:查询整行:
declare
empinfo emp%rowtype;--使用变量empinfo来接收emp的一行数据
begin
select * into empinfo from emp where empno=7369;
dbms_output.put_line('empno:'||empinfo.empno);
dbms_output.put_line('ename:'||empinfo.ename);
dbms_output.put_line('sal:'||empinfo.sal);
end;
使用 rowtype指定类型,并接收数据的时候,必须接收一行完整的数据
上述所有例子中,都只能接收一行以内的数据,如果查询返回了多行呢?--》显式游标
*****************************************************************************************
显式游标
显式游标的使用,分四个步骤:
1.申明游标
2.打开游标
3.提取游标
4.关闭游标
例子1:根据员工编号,查询员工的工资
declare
v_no emp.empno%type:=7369;
cursor empinfo is select sal from emp where empno=v_no;--申明游标
v_sal emp.sal%type;
begin
open empinfo;--打开游标
fetch empinfo into v_sal;--提取游标
dbms_output.put_line('v_sal:'||v_sal);
close empinfo;--关闭游标
end;
例子2:查询指定员工的名字和工资,同时查询该员工所在部门的名字
declare
v_no emp.empno%type:=7369;
cursor empinfo is select e.ename,e.sal,d.dname from emp e,dept d where e.deptno=d.deptno and e.empno=v_no;--申明游标
v_sal emp.sal%type;
v_name emp.ename%type;
v_dept_name dept.dname%type;
begin
open empinfo;--打开游标
fetch empinfo into v_name,v_sal,v_dept_name;--提取游标
dbms_output.put_line('v_name:'||v_name);
dbms_output.put_line('v_sal:'||v_sal);
dbms_output.put_line('v_dept_name:'||v_dept_name);
close empinfo;--关闭游标
end;
例子3:根据员工编号,查询员工所有信息
declare
v_no emp.empno%type:=7369;
cursor v_e is select * from emp where empno=v_no;
v_emp emp%rowtype;
begin
open v_e;
fetch v_e into v_emp;
dbms_output.put_line('empno:'||v_emp.empno);
dbms_output.put_line('ename:'||v_emp.ename);
dbms_output.put_line('sal:'||v_emp.sal);
dbms_output.put_line('hiredate:'||v_emp.hiredate);
close v_e;
end;
例子4:查询所有员工信息(多行)
declare
cursor allemp is select * from emp;
empinfo emp%rowtype;
begin
open allemp;
loop
fetch allemp into empinfo;
if allemp%notfound then exit;end if;
dbms_output.put_line('empno:'||empinfo.empno||',行数:'||allemp%rowcount);
--dbms_output.put_line('ename:'||empinfo.ename);
--dbms_output.put_line('sal:'||empinfo.sal);
--dbms_output.put_line('hiredate:'||empinfo.hiredate);
end loop;
if allemp%isopen then close allemp; end if;
end;
for也可以循环游标
DECLARE
CURSOR allemp IS SELECT * FROM emp;
BEGIN
FOR I IN allemp LOOP
dbms_output.put_line('empno:'||I.empno||',ename:'||I.ename||',行数:'||allemp%rowcount);
END LOOP;
end;
--通过游标修改数据
declare
cursor userinfo is select * from sporter where sporterid=1001 for update;
v_name varchar2(50);
begin
for i in userinfo loop
v_name :=i.sportername;
update sporter set sportername='王五' where current of userinfo;
dbms_output.put_line('用户信息:'||i.sporterid||'-------'||i.sportername);
end loop;
commit;
end;
------------------------------------------------------------------------------------------------------------------------
隐式游标和显式游标区别:
隐式:into,接收的结果只能是一行以内的数据;
显式:可以接收一个数据,多个数据,一行数据,多行数据;显式游标不再使用into;
cursor,sys_refcursor
cursor只能在存储过程内部使用,超出存储过程范围外,cursor的存储空间会被释放;
sys_refcursor系统游标的存储空间,是独立于具体的某个存储过程以外的,所以某个存储过程的执行结束(存储过程执行的空间会被释放),不会影响系统游标的数据;
---------------------------------------------------------------
create procedure xxxx(
zz out cursor
)is
cursor zz is select * from biao;
begin
open zz;
loop
fetch zz into 变量1,变量2....
if zz%notfound then exit;end if;
使用变量中的数据;
end loop;
close zz;
end;
--------------------------------------------------------------
create procedure xxxx(
yy out sys_refcursor
)is
begin
open yy for select * from 表;
end;