【问题标题】:What is the difference between foreach cursor explicit and foreach cursor implicitforeach 游标显式和 foreach 游标隐式有什么区别
【发布时间】:2021-01-22 10:47:34
【问题描述】:

这里有一个示例,我使用显式游标来解决任务。

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 oracle plsql database-cursor


【解决方案1】:

显式游标应显式定义并声明指向私有 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;

足以将当前光标转换为隐式光标

【讨论】:

  • 是否可以不用join或者join是必需的
  • 取决于您需要返回的内容,如果只需要在您的情况下重新使用ort 列,则只需使用SELECT ort FROM lager WHERE lnr IN (SELECT lnr FROM lagerbuchung) 作为选择语句。
  • 我试图重现它,但我收到以下错误,说必须声明 LNR。
【解决方案2】:

如果你明确为游标声明一个变量,那么这个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 LOOPSELECT 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 已经发布了一个使用单个查询的更高效的版本。

【讨论】:

    猜你喜欢
    • 2010-09-09
    • 1970-01-01
    • 2016-07-08
    • 2014-05-01
    • 1970-01-01
    • 2015-05-19
    • 2018-08-26
    • 2012-06-11
    相关资源
    最近更新 更多