1.游标简述
在这个章节,我们将会讨论在PL/SQL中的游标。Oracle创建一块称之为上下文的内存区域用来处理SQL语句,这块内存区域包含了执行SQL语句需要的所有信息,例如:语句执行后返回的记录的数量等等
一个游标是一个指向上下文区域的指针。PL/SQL通过这个游标去控制上下文区域。一个游标保存有SQL语句执行后返回一个或多个记录。这些被游标保存的记录的集合被称之为活动集。
你可以给游标命名进而能够在编程中实现每次获取和处理一个SQL语句执行后返回的记录。游标分为两种类型:
- 隐式游标
- 显式游标
2.隐式游标
隐式游标是在oracle执行没有指定显式游标的SQL语句时创建的。程序不能控制隐式游标和在隐式游标内的信息。
当使用一个DML语句(insert,update,delete)时,一个隐式游标会自动与这个DML语句相关联。对于insert操作来说,这个隐式游标持有需要将要被插入进表中的数据。对于update和delete操作来说,这个隐式游标标识出将会被改变的记录。
在PL/SQL中,你可以将最近的隐式游标称之为SQL游标,其总是拥有下列属性: %FOUND
,%ISOPEN
,%NOTFOUND
,%ROWCOUNT
.除上之外,还有一些可选的属性,%BULK_ROWCOUNT
和%BULK_EXCEPTIONS
是和FORALL
语句一起使用的。下面的表提供了对最常用的属性的描述:
属性 | 描述 |
---|---|
%FOUND | 如果一个INSERT ,UPDATE 或者DELETE 语句影响了一条或多条记录,则返回TRUE ;如果一个 SELETE INTO 语句返回了一条或多条记录,则返回TRUE ;其他情况,返回 FALSE . |
%NOTFOUND | 在逻辑上来说与%FOUND 相反。如果一个 INSERT ,UPDATE 或者DELETE 语句没有影响到表中的记录,则返回TRUE ;如果一个 SELETE INTO 语句没有返回记录,则返回TRUE ;其他情况,返回 FALSE . |
%ISOPEN | 因为当执行完与隐式游标相关联的SQL语句Oracle总是自动的关闭SQL 游标,所以对于隐式游标来说,此属性总是返回FALSE 。 |
%ROWCOUNT | 返回被INSERT ,UPDATE 或者DELETE 语句影响的记录的条数;或者返回SELECT INTO 语句返回记录的条数。 |
任何SQL游标属性都可以通过sql%attribute_name
来访问。
3.显式游标
显式游标是通过编程定义的游标,是为了获得更多的对于上下文区域的控制.显式游标应该定义在PL/SQL块中声明区域。显式游标创建在返回大于一条记录的SELECT
语句上。
- 创建显式游标的语法:
CURSOR <cursor_name> IS <select_statement>;
使用显式游标包含以下步骤:
- 声明游标以初始化内存
- 打开游标以分配内存
- 获取游标以检索数据
- 关闭游标以释放已经分配的内存
3.1 声明游标
声明游标使用一个名字和与之关联的SELECT
语句来定义游标。例如:
CURSOR c_emp IS SELECT empno,ename,job FROM scott.emp;
3.2 打开游标
打开游标为这个显式游标分配内存,并为之后将SQL语句返回的记录存入游标做准备。例如,我们将打开上面定义好的游标:
OPEN c_emp;
3.3 获取游标
获取游标每次访问一个记录。例如,我们从上面已经打开的游标中获取记录 :
FETCH c_emp INTO c_empno,c_ename,c_job;
3.4 关闭游标
关闭游标 意味着释放已经分配的内存。例如,我们将关闭上面已经打开的游标:
CLOSE c_emp;
3.5 完整例子:
用一个完整的例子去演示,用例为Oracle创建时scott用户自带的表:
CREATE TABLE emp01
AS
SELECT * FROM scott.emp;
DECLARE
c_empno emp01.empno%TYPE;
c_ename emp01.ename%TYPE;
c_job emp01.job%TYPE;
CURSOR c_emp IS SELECT empno,ename,job FROM emp01;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO c_empno,c_ename,c_job;
dbms_output.put_line('编号:'||c_empno||'姓名'||c_ename||'职位'||c_job);
EXIT WHEN c_emp%NOTFOUND;
END LOOP;
CLOSE c_emp;
END;
结果:
编号:7369姓名SMITH职位CLERK
编号:7499姓名ALLEN职位SALESMAN
编号:7521姓名WARD职位SALESMAN
编号:7566姓名JONES职位MANAGER
编号:7654姓名MARTIN职位SALESMAN
编号:7698姓名BLAKE职位MANAGER
编号:7782姓名CLARK职位MANAGER
编号:7788姓名SCOTT职位ANALYST
编号:7839姓名KING职位PRESIDENT
编号:7844姓名TURNER职位SALESMAN
编号:7876姓名ADAMS职位CLERK
编号:7900姓名JAMES职位CLERK
编号:7902姓名FORD职位ANALYST
编号:7934姓名MILLER职位CLERK
参考资料:英语原文:https://www.tutorialspoint.com/plsql/plsql_cursors.htm
原文:blog.isdevil.com