oracle如何监控游标 oracle系统游标

如何使用Oracle的游标?

Oracle中的游标分为显示游标和隐式游标。

创新互联建站成立于2013年,是专业互联网技术服务公司,拥有项目成都网站制作、成都网站设计、外贸营销网站建设网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元汝南做网站,已为上家服务,为汝南各地企业和个人服务,联系电话:18980820575

显示游标:

显示游标是用cursor...is命令定义的游标,它可以对查询语句(select)返回的多条记录进行处理;显示游标的操作:打开游标、操作游标、关闭游标;

隐式游标:

隐式游标是在执行插入(insert)、删除(delete)、修改(update)和返回单条记录的查询(select)语句时由PL/SQL自动定义的。PL/SQL隐式地打开SQL游标,并在它内部处理SQL语句,然后关闭它。

Oracle游标使用总结

Oracle游标分为显示游标和隐式游标

显示游标(Explicit Cursor):在PL/SQL程序中定义的 用于查询的游标称作显示游标

隐式游标(Implicit Cursor):是指非PL/SQL程序中定义的 而且是在PL/SQL中使用UPDATE/DELETE语句时 Oracle系统自动分配的游标

一 显示游标

使用步骤

( )定义 ( )打开 ( )使用 ( )关闭

使用演示

首先创建测试用表STUDENT 脚本如下

( ) 使用WHILE循环处理游标

create or replace PROCEDURE PROC_STU AS

BEGIN

显示游标使用 使用while循环

declare

定义游标 名称为cur_stu

cursor cur_stu is

select stuno stuname from student order by stuno;

定义变量 存放游标取出的数据

v_stuno varchar( );

v_stuname varchar( );

begin

打开游标cur_stu

open cur_stu;

将游标的当前行取出存放到变量中

fetch cur_stu into v_stuno v_stuname;

while cur_stu%found 游标所指还有数据行 则继续循环

loop

打印结果

dbms_output PUT_LINE(v_stuno|| ||v_stuname);

继续将游标所指的当前行取出放到变量中

fetch cur_stu into v_stuno v_stuname;

end loop;

close cur_stu; 关闭游标

end;

END PROC_STU ;

( ) 使用IF ELSE代替WHILE循环处理游标

create or replace PROCEDURE PROC_STU AS

BEGIN

显示游标使用 使用if判断

declare

定义游标 名称为cur_stu

cursor cur_stu is

select stuno stuname from student order by stuno;

定义变量 存放游标取出的数据

v_stuno varchar( );

v_stuname varchar( );

begin

打开游标cur_stu

open cur_stu;

将游标的当前行取出存放到变量中

fetch cur_stu into v_stuno v_stuname;

loop

if cur_stu%found then 如果游标cur_stu所指还有数据行

打印结果

dbms_output PUT_LINE(v_stuno|| ||v_stuname);

继续将游标所指的当前行取出放到变量中

fetch cur_stu into v_stuno v_stuname;

else

exit;

end if;

end loop;

close cur_stu; 关闭游标

end;

END PROC_STU ;

( ) 使用FOR循环处理游标

create or replace PROCEDURE PROC_STU AS

BEGIN

显示游标使用 使用for循环

declare

定义游标 名称为cur_stu

cursor cur_stu is

select stuno stuname from student order by stuno;

begin

for stu in cur_stu

loop

dbms_output PUT_LINE(stu stuno|| ||stu stuname);

循环做隐含检查 %notfound

end loop;

自动关闭游标

end;

END PROC_STU ;

( ) 常用的使用EXIT WHEN处理游标

create or replace

PROCEDURE PROC_STU _ AS

BEGIN

显示游标使用 使用exit when循环

declare

定义游标 名称为cur_stu

cursor cur_stu is

select stuno stuname from student order by stuno;

定义变量 存放游标取出的数据

v_stuno varchar( );

v_stuname varchar( );

begin

打开游标cur_stu

open cur_stu;

loop

将游标的当前行取出存放到变量中

fetch cur_stu into v_stuno v_stuname;

exit when cur_stu%notfound; 游标所指还有数据行 则继续循环

打印结果

dbms_output PUT_LINE(v_stuno|| ||v_stuname);

end loop;

close cur_stu; 关闭游标

end;

END PROC_STU _ ;

二 隐式游标

使用演示

create or replace PROCEDURE PROC_STU AS

BEGIN

隐式游标使用

update student set stuname= 张燕广 where stuno= ;

如果更新没有匹配则插入一条新记录

if SQL%NOTFOUND then

insert into student(STUNO STUNAME AGE GENDER)

values( 张燕广 男 );

end if;

END PROC_STU ;

说明

所有的SQL语句在上下文区内部都是可执行的 因为都有一个游标指向上下文区 此游标就是

SQL游标 与现实游标不同的是 SQL游标在PL/SQL中不需要打开和关闭 而是在执行UPDATE

DELETE是自动打开和关闭

上面例子中就是通过SQL%NOTFOUND游标属性判断UPDATE语句的执行结果决定是否需要插入新记录 CREATE TABLE STUDENT (

STUNAME VARCHAR ( BYTE)

STUNO VARCHAR ( BYTE)

AGE NUMBER

GENDER VARCHAR ( CHAR)

lishixinzhi/Article/program/Oracle/201311/17531

Oracle 游标

游标能够根据查询条件从数据表中提取一组记录,将其作为一个临时表置于数据缓冲区中,利用指针逐行对记录数据进行操作。

Oracle中的游标分为显示游标和隐式游标 。

在执行SQL语句时,Oracle会自动创建隐式游标,该游标是内存中处理该语句的数据缓冲区,存储了执行SQL语句的结果。通过隐式游标属性可获知SQL语句的执行状态信息。

%found:布尔型属性,如果sql语句至少影响到一行数据,值为true,否则为false。

%notfound:布尔型属性,与%found相反。

%rowcount:数字型属性,返回受sql影响的行数。

%isopen:布尔型属性,当游标已经打开时返回true,游标关闭时则为false。

用户可以显式定义游标。使用显式游标处理数据要4个步骤:定义游标、打开游标、提取游标数据和关闭游标。

游标由游标名称和游标对应的select结果集组成。定义游标应该放在pl/sql程序块的声明部分。

语法格式:cursor 游标名称(参数) is 查询语句

打开游标时,游标会将符合条件的记录送入数据缓冲区,并将指针指向第一条记录。

语法格式:open 游标名称(参数);

将游标中的当前行数据赋给指定的变量或记录变量。

语法格式:fetch 游标名称 into 变量名;

游标一旦使用完毕,就应将其关闭,释放与游标相关联的资源。

语法格式:close 游标名称;

declare

cursor c1 is  select sno,cno,grade from sc;

v_sno sc.sno%type;

v_cno sc.cno%type;

v_grade sc.grade%type;

begin

open c1;

loop

  fetch c1 into v_sno,v_cno,v_grade;

  exit when c1%notfound;--紧跟fetch之后

if c1%found then

dbms_output.put_line(to_char(c1%rowcount)||v_cno);

end if;

end loop;

close c1; 

end;

declare

cursor c1 is select sno,cno,grade from sc;

v_sno sc.sno%type;

v_cno sc.cno%type;

v_grade sc.grade%type;

begin

open c1;

fetch c1 into v_sno,v_cno,v_grade;

while c1%found loop

  dbms_output.put_line(v_sno||v_cno||v_grade);

 fetch c1 into v_sno,v_cno,v_grade;

end loop;

close c1; 

end;

第三种:for

declare

cursor c1 is select sno,cno,grade from sc;

begin

for item in c1 loop

dbms_output.put_line(rpad(item.sno,'10',' ')||rpad(item.cno,'10',' ')||rpad(item.grade,'10',' '));

end loop;

end;

如何监控Oracle数据库中长时间运行的进程

监控Oracle 数据库中长时间运行进程的两种方式,通过这些方 法,我们可以监控单条语句的 长时间操作,监控存储过程的运行进度,甚至自己'生成'进度信息. 关键词:监控进度V$SESSION_LONGOPS 当Oracle 存储过程运行时间较长时,我们希望客 户端能了解到它在后台执行的状况或者进度信息(类 似WINDOWS 安装软件时的进度条信息),这样可以知 道运行在后台的应用进程是否终止或者休眠,更近一 步要求,最好能知道进行到哪一步骤,还有多少时间才 能完成. 简单到一条SQL 语句的情况,如果执行时间较长, 我们如何得到它的运行状况?是否后台还在运行?虽 然可以查看SQL 的执行计划了解它的执行步骤,但如 何知道它运行到哪一个步骤了呢?如何才能估计出它 的合理的较为精确的执行时间呢? Oracle 数据库前端发出执行命令后,进程在后台 执行,普通开发人员一般无法了解到后台在做什么,一 般采用的方法是用DBMSOUTPUT.PUT_LINE 来打印出 来,但DBMS—OUTPUT.PUT—LINE 打印的信息受缓冲区 大小限制,如果信息较多就容易溢出,而且如果存储过 程执行时间较长,只有在其执行完后,这些信息才会打 印出来,这就增加了调试周期,影响了调试效果.有的 开发人员在存储过程中通过写日志表的形式来记录进 度,但需要COMMIT 后其他进程才能看到这些日志信 息,而在某些控制结构中(如游标CURSOR 循环)COM— MIT,则很容易引起ORA 一01555 错误,造成程序出错. 下面介绍两种监控方法. 如何监控单条长语句从ORACLE8 开始,出现一个新的动态视图:V $SESSION_LONGOPS,从这个视图可以获知一些操作 (如全表扫描,并行查询,RMAN,排序等)的执行进度, 我们先来了解一下V$SESSION—LONGOPS 视图的一些 重要字段: 列说明 sID 会话标识 5ERIAL#会话序列号 OPfE 操作的简短描述 TARG 盯操作的对象,如xx TAR~_DESC目标描述 SOFAR 目前已执行单位数目 ToTAIWORK 总单位数目 UNlTS 单位 START_TIME 开始执行时间 LAST_ UPDATE_TIME 统计数据最后更新时间 TIME_ REMAINING 估计剩余时间c ELAPSED_SECONDS 已执行时间(秒) MEsSAGE 统计数据汇总信息 USERA^^E 用户名 ~L_ADDRES5 语句的地址,,用于和V$sql_text 等关联 语句的hash 地址,用于和V$sql_texlSQLHASH VALUE等关联 这个动态视图显示各个运行时间超过6 程.这些进程包含许多备份和恢复功能,统计数据收集,查询等. 执行以下语句就可以得到数据库中各个长时间操 作的进程信息: select'Icfromv$sesslon_ longopswheretime_ re- malnlng0 我们也可以用图形化工具查看,如TOAD,OEM中 均可查看长操作进程进度信息. Oracle 自带的管理工具OracleEnterpriseManager (OEM)提供了图形化查看长操作的功能,如: 计算机系统应用2007 Quest公司的数据库管理工具TOAD 也可以看到 长操作信息,如: 表的统计信息. 长时问运行的SQL 语句可以用V$SESSION—LON? 为了能监控到查询进程执行的进度,必需使用 CBO 优化器并且: 设置TlMED—STATISTICS或者SQL—TRACE 用ANALYZE语句或者DBMS—STAT 包收集相关 108 实践经验P 帕cficalExpen GOPS来监控.实际上,长时间运行的存储过程也可以 监控.那是否任何操作都可以通过这个视图来监控进 度呢?很遗憾,V$SESSION—LONGOPS 只会报告它认为 耗时长的操作.对于NEsTEDLOOP/UNIQUEINDEX READS/INDEXRANGEScANS 等执行速度很快的操作, 2007 期计算机系统应用由于它们执行一般不超过6 秒,因此将不会出现在V $SESSION—LONGOPS 如何监控自定义存储过程单条长语句可以用上面的方法监控,Oracle 动生成V$SE.SSION— LONGOPS 记录.那么存储过程中 有许多小操作,如何监控进度呢?其实,我们也可以手 工生成V$SESSION—LONGOPS 记录,方法是调用DBMS APPLICATION—INFO 包来生成自定义进度信息. 从Oracle7.2 开始,提供了DBMS—APPLICATION— INFo 包,通过调用这个包,应用可以将自己的名字和 动作填写到V$SESSION 和V$SQLAREA 的MODULE ACTION列中.V$SESSION 列出每个会话的用户名,操 作系统机器名,终端名,程序名等. 应用可以在执行模块时设置模块名和动作名,模 块名一般是甩户自定义的.而动作名一般描述模块中 的当前执行的事务的名字. DBMSAPPLICATION_INFO 包包含以下过程 SET_ MODULE 设置当前运行程序的模块名 SET__AEl'ION 设置当前模块的当前动作名 SESSION—LON-在V$SESSIONLONGOPS视图中 GoPS 插入一行进度信息 SETMODULE过程设置模块名和动作名: createorreplaceproceduredel—cust(v_cust—Id varchar2) begindbms—— application—— info.set— module(module—— name="delcust". actlon_name="deletetablecust)i deletefromcustwherecustld=v_ cusLId; dbms_appllcatlon— Info.seLmodule(,); end;以上设置的模块名和动作名可以通过查询V $sqlarea 获取. 如:selectsql—text,module,actionfromv $sqlareawheremodule="del_cust: sql_textmoduleadion Deletefr0mcustdel_ custdeletetableoust 1rowselected. SET_SESSION—LONGOPS 过程用于在V$session— longops 中插入一行,开发人员可以调用此过程设置长 时间操作的状态信息,这样,任何其他其他会话都可以 看到这个进度信息.如下例所示: declare nohlntnumberdefaultdbmsapplicatlon_info.set_ session— Iongops_ nohint; IdndexnumberdefaultInohlnt: slnonumber;begin forlIn1..8888888888 loop update....; dbms_ appllcaflon— Info.setsesslon_ longops (rlndex=l_rlndex, slno=I_slno. op_name="updateahugetable. target=126, target_desc='.msgdescription context=0.sOfar=j. totalwork=8888888888. units=loops endloop;end; 然后,从另一个会话来执行以下语句selectfromv$sesslon_ longopswheretlmere? malnlng0; 也可以用图形化工具TOAD 或OEM来查看. 因此,采用本文说明的方法,Oracle 开发人员可以 比较方便的监控长操作进程的进度信息,也可以自己 设置监控信息,来了解后台存储过程的运行效率.甚 至,可以在存储过程或SQL 语句提交执行后马上观察 其执行进度,如果比较缓慢,则可以中断其执行,进行 调优,从而缩短调试周期,提高开发效率.


网站标题:oracle如何监控游标 oracle系统游标
当前URL:http://ybzwz.com/article/hgeicj.html