foreach游标显式和foreach游标隐式有什么区别
What is the difference between foreach cursor explicit and foreach cursor implicit
这里有一个示例,其中我使用显式游标来解决任务。
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
or SELECT INTO
中),PLSQL 会生成隐式 (internal/undeclared) 游标,例如:
begin
for r in (select 1 as n from dual) loop
dbms_output.put_line(r.n);
end loop;
end;
what is the difference between foreach cursor explicit and foreach cursor implicit? Is the code similar ? Which one is better to use?
区别在于显式游标需要声明一个变量。您还需要打开、关闭和获取显式游标。因此,隐式游标通常会产生更简洁的代码。
仍然有显式游标的用例(参见 Practical life examples of oracle explicit cursor use):
- 您需要在同一个 PLSQL 程序中多次重复使用同一个游标。使用显式游标,您可以重用变量而无需重复查询。
- 您想通过 LIMIT 子句使用批量收集。使用显式游标,可以直接设置限制。
I've tried to reproduce the code but with using foreach cursor implicit, but didn't manage and gave up.
您可以使用隐式游标直接翻译您的代码:
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 已经发布了使用单个查询的更高效的版本。
这里有一个示例,其中我使用显式游标来解决任务。
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
or SELECT INTO
中),PLSQL 会生成隐式 (internal/undeclared) 游标,例如:
begin
for r in (select 1 as n from dual) loop
dbms_output.put_line(r.n);
end loop;
end;
what is the difference between foreach cursor explicit and foreach cursor implicit? Is the code similar ? Which one is better to use?
区别在于显式游标需要声明一个变量。您还需要打开、关闭和获取显式游标。因此,隐式游标通常会产生更简洁的代码。
仍然有显式游标的用例(参见 Practical life examples of oracle explicit cursor use):
- 您需要在同一个 PLSQL 程序中多次重复使用同一个游标。使用显式游标,您可以重用变量而无需重复查询。
- 您想通过 LIMIT 子句使用批量收集。使用显式游标,可以直接设置限制。
I've tried to reproduce the code but with using foreach cursor implicit, but didn't manage and gave up.
您可以使用隐式游标直接翻译您的代码:
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 已经发布了使用单个查询的更高效的版本。