我已经写了一年的基本 Web 应用程序(用于 Oracle 数据库),并且由于函数非常简单,我们大多数人都坚持使用常规 FOR 循环来获取我们的数据:
for i in (select * from STUDENTS) loop
htp.prn(i.student_last_name || ', ' || i.student_first_name || ' ' || i.student_dob);
end loop;
Run Code Online (Sandbox Code Playgroud)
但是,游标似乎是做事的“正确”方式。我可以找到很多关于游标是什么以及遍历它们的不同方法的信息,但是我找不到在常规 FOR 循环上使用它们的可靠理由。它是否取决于程序的需要?是否有我应该注意的固有优势?
Jus*_*ave 16
您发布的代码正在使用游标。它使用隐式游标循环。
在某些情况下,使用显式游标循环(即在声明部分声明 CURSOR 变量)会产生更清晰的代码或更好的性能
student_cursor而不是包括嵌入一堆逻辑的 30 行 SQL 语句。例如,如果您要打印所有已获准毕业的学生,并且需要加入包含其学术记录、学位课程要求的表格、包含学术保留信息的表格、包含过期图书馆书籍信息的表格、包含有关未付费用、管理覆盖等信息的表。重构代码可能是有意义的,这样该查询就不会卡在与向用户呈现列表有关的代码中间。这可能涉及创建一个视图来封装所有这些逻辑。或者它可能涉及创建一个显式游标,该游标被声明为当前 PL/SQL 块的一部分或一些更高级别的 PL/SQL 块(即 在包中声明的游标),以便它可以重用。或者它可能涉及为封装和可重用性做一些其他事情(例如,创建一个流水线表函数)。htp.prn,那么执行 aBULK COLLECT可能不会给您带来任何好处。但是,在其他情况下,它可以导致显着的性能改进。游标可以是显式的或隐式的,并且可以在 FOR 循环中使用任一类型。你的问题实际上有两个方面。
为什么在隐式游标 FOR 循环上使用显式游标 FOR 循环?
为什么使用带有 FETCH 的循环而不是没有显式 FETCH 的 FOR 循环?
以下是文档中的一些有用信息。
FOR LOOP 隐式游标示例
BEGIN
FOR vItems IN (
SELECT last_name
FROM employees
WHERE manager_id > 120
ORDER BY last_name
)
LOOP
DBMS_OUTPUT.PUT_LINE ('Name = ' || vItems.last_name);
END LOOP;
END;
/
Run Code Online (Sandbox Code Playgroud)
显式游标 FOR LOOP 示例
DECLARE
CURSOR c1 IS
SELECT last_name
FROM employees
WHERE manager_id > 120
ORDER BY last_name;
BEGIN
FOR vItems IN c1 LOOP
DBMS_OUTPUT.PUT_LINE ('Name = ' || vItems.last_name);
END LOOP;
END;
/
Run Code Online (Sandbox Code Playgroud)
隐式游标是由 PL/SQL 构造和管理的会话游标。每次运行 SELECT 或 DML 语句时,PL/SQL 都会打开一个隐式游标。您无法控制隐式游标,但可以从其属性中获取信息。
隐式游标在其关联语句运行后关闭;但是,它的属性值在另一个 SELECT 或 DML 语句运行之前一直可用。
隐式游标属性为:SQL%ISOPEN、SQL%FOUND、SQL%NOTFOUND、SQL%ROWCOUNT、SQL%BULK_ROWCOUNT、SQL%BULK_EXCEPTIONS
显式游标是您构造和管理的会话游标。您必须声明并定义一个显式游标,为其指定名称并将其与查询相关联(通常,查询返回多行)。然后您可以通过以下任一方式处理查询结果集:
打开显式游标(使用 OPEN 语句),从结果集中提取行(使用 FETCH 语句),然后关闭显式游标(使用 CLOSE 语句)。
在游标 FOR LOOP 语句中使用显式游标(请参阅“使用游标 FOR LOOP 语句处理查询结果集”)。
您不能为显式游标赋值,不能在表达式中使用它,也不能将其用作正式的子程序参数或主变量。您可以使用游标变量来完成这些操作(请参阅“游标变量”)。
与隐式游标不同,您可以通过名称引用显式游标或游标变量。因此,显式游标或游标变量称为命名游标。
游标 FOR LOOP 语句允许您运行 SELECT 语句,然后立即循环遍历结果集的行。此语句可以使用隐式或显式游标。
| 归档时间: |
|
| 查看次数: |
43962 次 |
| 最近记录: |