当前位置: 代码迷 >> SQL >> PL/SQL的游标部类
  详细解决方案

PL/SQL的游标部类

热度:45   发布时间:2016-05-05 11:06:57.0
PL/SQL的游标类型

游标是oracle中的一个结果集,用于存放查询的结果;

?

PL/SQL中游标的声明;

1,声明游标2,打开游标(默认是关闭的);3,提取数据4,关闭游标

?

?

注意的要点:游标必须声明在declare中,使用open打开游标,fetch取游标中的数据,close关闭游标

?

隐式游标:主要是对DML数据的操作隐式游标的属性有:隐式游标不能使用select into

%FOUND – SQL 语句影响了一行或多行时为 TRUE%NOTFOUND – SQL 语句没有影响任何行时为TRUE%ROWCOUNT – SQL 语句影响的行数%ISOPEN  - 游标是否打开,始终为FALSE

?

?

显示游标

PL/SQL包含隐含游标和显示游标两种游标类型,其中隐含游标用于处理SELECT INTO和DML语句。而显示游标则专门用于SELECT语句返回的多行数据。

?

-----------------------------隐式游标类型

--隐式游标 使用DML语句时自动创建隐式游标
--DML 添加 删除,修改数据的时候(会涉及到数据的变化)

%found 发现数据,%notfound没有发现数据,%isopen游标是否打开,%rowCount受影响的行数

例子;在更新数据中使用游标测试隐式游标

在操作DML数据的时候默认有一个隐式游标sql

declare--声明pl/sql块begin update emp set sal=3000 where ename='SMITH';--更新语句 if sql%found then --如果发现语句   dbms_output.put_line('有'||sql%rowcount||'行受到影响');else --否则   dbms_output.put_line('没有数据更新');end if; if sql%isopen then  --如果游标打开,游标默认是关闭的    dbms_output.put_line('游标被打开');else --游标没有打开dbms_output.put_line('游标没有被打开');end if;end;/

?结果;

有1行受到影响
游标没有被打开

?

-----------------------------显示游标

?

显示游标用来存放数据的,这也是游标主要功能

%rowtype和%type相似,%rowtype存放的是全部字段,%type只能匹配一个字段,--使用%rowtype 存放查询语句返回的一条数据,

?

%typehe %rowtype的区别;

声明emp表的全部字段

--%type声明emp表中的全部字段declaretype emp_type_record is record(  v_ename    emp.ename%type;  v_sal    emp.sal%type;   v_empno emp.empno%type; ..........);beginend

?%rowtype声明emp表的全部字段

  declarev_rowtype emp%rowtype;  beginend;

?

使用%rowtype来打印emp表部门10的数据

declaremyrow emp%rowtype;begin      select ename,job,sal into myrow.ename,myrow.job,myrow.sal from emp where empno=10;       dbms_output.put_line('ename:'||myrow.ename);end; ORA-01403: 未找到任何数据ORA-06512: 在 line 5

?

-------------------显示静态游标

?

要接受多行数据必须使用游标来接受;

declaremyrow emp%rowtype;  cursor rowcursor is select * from emp where deptno=&a;--声明游标begin --使用循环来取数据      for myrow in rowcursor loop  dbms_output.put_line(myrow.ename||'+++++++++++'||myrow.sal);  end loop;end;CLARK+++++++++++2450KING+++++++++++5000MILLER+++++++++++1300

?

游标带参数的类型

declaremyrow emp%rowtype;  cursor rowcursor(v_deptno number) is select * from emp where deptno=v_deptno;--声明游标begin --使用循环来取数据      for myrow in rowcursor(10) loop  dbms_output.put_line(myrow.ename||'+++++++++++'||myrow.sal);  end loop;end;CLARK+++++++++++2450KING+++++++++++5000MILLER+++++++++++1300

?

fetch来取游标的数据? for循环和fetch来取游标需要特别的注意;

declare myrow emp%rowtype; cursor rowcorsor is select * from emp where deptno=&a;begin    --打开游标    open rowcorsor;loop    fetch rowcorsor into myrow;   exit when rowcorsor%notfound;dbms_output.put_line(myrow.ename||'+++++++'||myrow.sal);   end loop;end;/CLARK+++++++2450KING+++++++5000MILLER+++++++1300

?

?

?

--------------------------游标的更新

查询部门20的姓名等字段,更新SMITH的工资

declaremyrow emp%rowtype;  cursor rowcursor(v_deptno number) is select * from emp where deptno=v_deptno;--声明游标begin --使用循环来取数据      for myrow in rowcursor(20) loop  dbms_output.put_line('更新前:'||myrow.ename||'+++++++++++'||myrow.sal);  end loop; update emp set sal=3000 where ename='SMITH'; for myrow in rowcursor(20) loopdbms_output.put_line('更新后:'||myrow.ename||'+++++++++++'||myrow.sal);end loop; end;更新前:SMITH+++++++++++1000更新前:JONES+++++++++++2975更新前:SCOTT+++++++++++3000更新前:ADAMS+++++++++++1100更新前:FORD+++++++++++3000更新后:SMITH+++++++++++3000更新后:JONES+++++++++++2975更新后:SCOTT+++++++++++3000更新后:ADAMS+++++++++++1100更新后:FORD+++++++++++3000

?

?

?

----------------------------游标的删除

删除游标中部门20 的SMITH;为了测试,设置一个保存点a ?savepoint a; 方便回复 rollback to a;

?

declaremyrow emp%rowtype;  cursor rowcursor(v_deptno number) is select * from emp where deptno=v_deptno;--声明游标begin --使用循环来取数据      for myrow in rowcursor(20) loop  dbms_output.put_line('更新前:'||myrow.ename||'+++++++++++'||myrow.sal);  end loop; delete emp where ename='SMITH'; for myrow in rowcursor(20) loopdbms_output.put_line('更新后:'||myrow.ename||'+++++++++++'||myrow.sal);end loop; end; 更新前:JONES+++++++++++2975更新前:SCOTT+++++++++++3000更新前:ADAMS+++++++++++1100更新前:FORD+++++++++++3000更新后:JONES+++++++++++2975更新后:SCOTT+++++++++++3000更新后:ADAMS+++++++++++1100更新后:FORD+++++++++++3000

?

?

---------------------------显示动态游标 ref? cursor

declare  type emp_type_cursor is ref cursor;  mycursor emp_type_cursor; v_row emp%rowtype;begin   open mycursor for select * from emp where deptno=&a;  loop  fetch mycursor into v_row;  exit when mycursor%notfound;  dbms_output.put_line(v_row.ename);end loop;end; SMITHJONESSCOTTADAMSFORD

?

?

?

?

?

?

?

?

  相关解决方案