如何解决foreach游标显式和foreach游标隐式有什么区别
set serveroutput on
DECLARE
CURSOR c_1
IS
SELECT
LNR,LFNDNR,DATUM,STUECK,ANR
FROM
lagerbuchung;
CURSOR c_2(p_LNR INT)
IS
SELECT
ORT
FROM
LAGER
WHERE
lager.LNR = p_LNR;
v_ort varchar(45);
BEGIN
FOR v_rec IN c_1
LOOP
open c_2(v_rec.LNR);
fetch c_2into v_ort;
DBMS_OUTPUT.PUT_LINE(': ' || v_rec.LNR || ' : ' || v_rec.LFNDNR ||' : ' || v_rec.DATUM ||' : ' || v_rec.STUECK || ' : ' || v_rec.ANR || ' : ' || v_ort );
close c_2;
END LOOP;
END;
所以我的问题是,显式 foreach 游标和隐式 foreach 游标有什么区别?
代码相似吗?哪个更好用?我试图重现代码但使用隐式 foreach 游标,但没有管理并放弃。
解决方法
显式游标应该明确定义并声明为指向私有 SQL 区域,而隐式游标只是一条 SQL 语句,不需要任何人打开,因为它已经被数据库打开和关闭了自己的。
对于你的情况,使用这样的代码
SQL> SET SERVEROUTPUT ON
SQL> DECLARE
v_ort varchar(45);
BEGIN
FOR v_rec IN
(
SELECT l.ort,lb.lnr,lb.lfndnr,lb.datum,lb.stueck,lb.anr
FROM lager l
JOIN lagerbuchung lb
WHERE lb.lnr = l.lnr
)
LOOP
DBMS_OUTPUT.PUT_LINE(': ' || v_rec.lnr || ' : ' || v_rec.lfndnr ||
' : ' || v_rec.datum || ' : ' || v_rec.stueck ||
' : ' || v_rec.anr || ' : ' || v_rec.ort);
END LOOP;
END;
足以将当前光标转换为隐式光标
,如果你明确为游标声明一个变量,那么这个cursor is explicit,例如:
declare
cursor c1 is
select 1 as n from dual;
begin
for r in c1 loop
dbms_output.put_line(r.n);
end loop;
end;
如果您在代码中内联 sql 查询(在 FOR LOOP
或 SELECT INTO
中),PLSQL 会生成隐式(内部/未声明)游标,例如:
begin
for r in (select 1 as n from dual) loop
dbms_output.put_line(r.n);
end loop;
end;
显式 foreach 游标和隐式 foreach 游标有什么区别?代码类似吗?哪个更好用?
区别在于您需要为显式游标声明一个变量。您还需要打开、关闭和获取显式游标。出于这个原因,隐式游标通常会产生更整洁的代码。
仍然有显式游标的用例(参见 Practical life examples of oracle explicit cursor use):
- 您需要在同一个 PLSQL 程序中多次重用同一个游标。使用显式游标,您可以重用变量而无需重复查询。
- 您想通过 LIMIT 子句使用批量收集。使用显式游标,您可以直接设置限制。
我试图重现代码,但使用隐式 foreach 游标,但没有管理并放弃。
您可以使用隐式游标直接翻译您的代码:
declare
v_ort varchar(45);
begin
for v_rec in (SELECT LNR,LFNDNR,DATUM,STUECK,ANR FROM lagerbuchung) loop
SELECT ORT into v_ort FROM LAGER WHERE lager.LNR = v_rec.LNR;
DBMS_OUTPUT.PUT_LINE(': ' || v_rec.LNR || ' : ' || v_rec.LFNDNR ||
' : ' || v_rec.DATUM || ' : ' || v_rec.STUECK ||
' : ' || v_rec.ANR || ' : ' || v_ort);
end loop;
end;
但是 @Barbaros Özhan 已经发布了一个使用单个查询的更高效的版本。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。