游标
Oracle游标是一种用于轻松的处理多行数据的机制。如果没有游标,Oracle开发人员必须单独地、显式地取回并管理游标查询选择的每一条记录。游标的另一项功能是,它包含一个跟踪当前访问的记录的指针,这使程序能够一次处理多条记录。
1.声明游标
声明游标的语句格式如下:
Oracle游标是一种用于轻松的处理多行数据的机制。如果没有游标,Oracle开发人员必须单独地、显式地取回并管理游标查询选择的每一条记录。游标的另一项功能是,它包含一个跟踪当前访问的记录的指针,这使程序能够一次处理多条记录。
1.声明游标
声明游标的语句格式如下:
DECLARE
Cursor_Name
IS
SELECT
Statement
声明游标完成了下面两个目的:
① 给游标命名.
② 将一个查询与游标关联起来。
2.打开游标
打开游标的语句格式如下:
OPEN
Cursor_Name;
打开游标将激活查询并识别活动集,可是在执行游标取回命令之前,并没有真正取回记录。OPEN命令还初始化了游标指针,使其指向活动集的第一条记录。游标被打开后,直到关闭之前,取回到活动集的所有数据都是静态的。换句话说,游标忽略所有在游标打开之后,对数据执行的SQL DML命令(INSERT、UPDATE、DELETE和SELECT),因此只有在需要时才打开它,要刷新活动集,只需关闭并重新打开游标即可。
3.从游标中取数据
FETCH命令以每次一条记录的方式取回活动集中的记录。通常将FETCH命令和某种迭代处理结合起来使用,在迭代处理中,FETCH命令每执行一次,游标前进到活动集的下一条记录。
FETCH命令的语句格式如下:
FETCH
Cursor_Name
INTO
Record_List;
执行FETCH命令后,活动集中的结果被取回到PL/SQL变量中,以便在PL/SQL块中使用。每取回一条记录,游标的指针就移向活动集的下一条记录。
4.关闭游标
CLOSE语句关闭以前打开的游标。
CLOSE语句的格式:
CLOSE
Cursor_Name;
5.隐式游标
隐式游标也可以叫做SQL游标。和显式的游标不同,不能对一个SQL游标显式的执行OPEN、CLOSE和FETCH语句。Oracle隐式的打开SQL游标、处理SQL游标、然后再关闭该游标。Oracle提供隐式游标的主要目的就是利用这些游标的属性来确定SQL语句运行的情况。
6.实例
一个游标应用的完整程序代码:
DECLARE
CURSOR C1 IS
SELECT VIEW_NAME FROM ALL_VIEWS WHERE ROWNUM <= 10 ORDER BY VIEW_NAME;
VNAME VARCHAR2 ( 40 );
BEGIN
OPEN C1;
FETCH C1 INTO VNAME;
WHILE C1 % FOUND LOOP
FETCH C1 INTO VNAME;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(C1 % ROWCOUNT ) || '' || VNAME);
END LOOP;
CLOSE C1;
END ;
CURSOR C1 IS
SELECT VIEW_NAME FROM ALL_VIEWS WHERE ROWNUM <= 10 ORDER BY VIEW_NAME;
VNAME VARCHAR2 ( 40 );
BEGIN
OPEN C1;
FETCH C1 INTO VNAME;
WHILE C1 % FOUND LOOP
FETCH C1 INTO VNAME;
DBMS_OUTPUT.PUT_LINE(TO_CHAR(C1 % ROWCOUNT ) || '' || VNAME);
END LOOP;
CLOSE C1;
END ;
DECLARE
TempSal EMPLOYEES.SAL % TYPE;
CURSOR MyCursor IS
SELECT * FROM EMPLOYEES WHERE SAL > TempSal;
CursorRecord MyCursor % ROWTYPE;
BEGIN
TempSal : = 800 ;
IF MyCursor % ISOPEN THEN
FETCH MyCursor INTO CursorRecord;
dbms_output.put_line(to_char(CursorRecord.EMP_NAME));
ELSE
dbms_output.put_line( ' 游标未打开! ' );
END IF ;
END ;
TempSal EMPLOYEES.SAL % TYPE;
CURSOR MyCursor IS
SELECT * FROM EMPLOYEES WHERE SAL > TempSal;
CursorRecord MyCursor % ROWTYPE;
BEGIN
TempSal : = 800 ;
IF MyCursor % ISOPEN THEN
FETCH MyCursor INTO CursorRecord;
dbms_output.put_line(to_char(CursorRecord.EMP_NAME));
ELSE
dbms_output.put_line( ' 游标未打开! ' );
END IF ;
END ;
输出结果为“游标未打开!”。
2)%FOUND属性
该属性功能是测试前一个fetch语句是否有值,有值将返回true,否则为false。
DECLARE
TempSal EMPLOYEES.SAL % TYPE;
CURSOR MyCursor IS
SELECT * FROM EMPLOYEES WHERE SAL > TempSal;
CursorRecord MyCursor % ROWTYPE;
BEGIN
TempSal : = 800 ;
OPEN MyCursor;
FETCH MyCursor INTO CursorRecord;
IF MyCursor % FOUND THEN
dbms_output.put_line(to_char(CursorRecord.EMP_NAME));
ELSE
dbms_output.put_line( ' 未发现数据! ' );
END IF ;
END ;
TempSal EMPLOYEES.SAL % TYPE;
CURSOR MyCursor IS
SELECT * FROM EMPLOYEES WHERE SAL > TempSal;
CursorRecord MyCursor % ROWTYPE;
BEGIN
TempSal : = 800 ;
OPEN MyCursor;
FETCH MyCursor INTO CursorRecord;
IF MyCursor % FOUND THEN
dbms_output.put_line(to_char(CursorRecord.EMP_NAME));
ELSE
dbms_output.put_line( ' 未发现数据! ' );
END IF ;
END ;
输出结果为“tom”。
3)%NOTFOUND属性
该属性是%found属性的反逻辑,常被用于退出循环。
DECLARE
TempSal EMPLOYEES.SAL % TYPE;
CURSOR MyCursor IS
SELECT * FROM EMPLOYEES WHERE SAL > TempSal;
CursorRecord MyCursor % ROWTYPE;
BEGIN
TempSal : = 800 ;
OPEN MyCursor;
FETCH MyCursor INTO CursorRecord;
IF MyCursor % NOTFOUND THEN
dbms_output.put_line(to_char(CursorRecord.EMP_NAME));
ELSE
dbms_output.put_line( ' 发现数据! ' );
END IF ;
END ;
TempSal EMPLOYEES.SAL % TYPE;
CURSOR MyCursor IS
SELECT * FROM EMPLOYEES WHERE SAL > TempSal;
CursorRecord MyCursor % ROWTYPE;
BEGIN
TempSal : = 800 ;
OPEN MyCursor;
FETCH MyCursor INTO CursorRecord;
IF MyCursor % NOTFOUND THEN
dbms_output.put_line(to_char(CursorRecord.EMP_NAME));
ELSE
dbms_output.put_line( ' 发现数据! ' );
END IF ;
END ;
输出结果为“发现数据!”
4)%ROWCOUNT属性
该属性用于返回游标的数据行数。
DECLARE
TempSal EMPLOYEES.SAL % TYPE;
CURSOR MyCursor IS
SELECT * FROM EMPLOYEES WHERE SAL > TempSal;
CursorRecord MyCursor % ROWTYPE;
BEGIN
TempSal : = 800 ;
OPEN MyCursor;
FETCH MyCursor INTO CursorRecord;
dbms_output.put_line(to_char(MyCursor % ROWCOUNT ));
END ;
TempSal EMPLOYEES.SAL % TYPE;
CURSOR MyCursor IS
SELECT * FROM EMPLOYEES WHERE SAL > TempSal;
CursorRecord MyCursor % ROWTYPE;
BEGIN
TempSal : = 800 ;
OPEN MyCursor;
FETCH MyCursor INTO CursorRecord;
dbms_output.put_line(to_char(MyCursor % ROWCOUNT ));
END ;
输出结果为“1” 。
7.游标的属性
1)%ISOPEN属性
该属性功能是测试游标是否打开,如果没有打开游标就使用fetch语句将提示错误。