PL/SQL 游标中的变量实际上与绑定参数相同吗?

Are PL/SQL variables in cursors effectively the same as bind parameters?

我听说使用绑定变量(可以)更有效,因为对于具有不同绑定值的后续调用,查询本身仍然相同,因此不再需要解析。

我明白为什么固定值会出现这种情况。在下面的游标中,该值固定为 1。如果我有一个相同的不同游标,除了 1 变成 2,这是一个不同的查询。到目前为止清除。

declare
  cursor C_CURSOR is 
    select * from TESTTABLE pt where pt.ID = 1;

但我想知道在游标内使用 PL/SQL 变量时是否也是这种情况。它们是像固定值一样扩展,还是被解释为绑定变量。

我到处搜索,但到处都能找到关于 文字 的例子,就像上面的例子一样,但没有关于 PL/SQL 的使用的明确解释变量。

换句话说,在下面的两个片段中,第二个可能更有效,还是它们本质上相同?

在游标中直接使用 PL/SQL 变量:

declare
  V_TEST integer := 1;

  cursor C_CURSOR is 
    select * 
    from 
      TESTTABLE pt
    where
      pt.ID = V_TEST;

begin
  for r in C_CURSOR loop
    null;
  end loop;
end;

绑定变量:

declare
  V_TEST int := 1;

  cursor C_CURSOR(B_TEST int) is 
    select * 
    from 
      TESTTABLE pt
    where
      pt.ID = B_TEST;

begin
  for r in C_CURSOR(V_TEST) loop
    null;
  end loop;
end;

首先,问得好。

我想做一个小报价:

Every reference to a PL/SQL variable is in fact a bind variable.

话虽如此,

PL/SQL 本身会处理与绑定变量有关的大部分问题,以至于您编写的大多数代码已经在您不知情的情况下使用了绑定变量.以 PL/SQL 的以下位为例:

create or replace procedure dsal(p_empno in number)
as
  begin
    update emp
    set sal=sal*2
    where empno = p_empno;
    commit;
  end;
/

现在您可能认为必须用绑定变量替换 p_empno。然而,好消息是每个对 PL/SQL 变量的引用实际上都是一个绑定变量。

Source

阅读精品手册:PL/SQL Static SQL

A PL/SQL static SQL statement can have a PL/SQL identifier wherever its SQL counterpart can have a placeholder for a bind variable. The PL/SQL identifier must identify either a variable or a formal parameter.

从 SQL 引擎的角度来看,您的两个示例片段是等效的,并且表现同样出色。

阅读更多同样精美的手册:

Generally, PL/SQL parses an explicit cursor only the first time the session opens it and parses a SQL statement (creating an implicit cursor) only the first time the statement runs.

All parsed SQL statements are cached. A SQL statement is reparsed only if it is aged out of the cache by a new SQL statement. Although you must close an explicit cursor before you can reopen it, PL/SQL need not reparse the associated query. If you close and immediately reopen an explicit cursor, PL/SQL does not reparse the associated query.

因此更改绑定变量不需要 SQL 语句解析。

从代码可读性(即维护)的角度来看,使用 parameters 的第二个代码段更好。这在小片段中并不明显,但在大型 PL/SQL 程序中,如果游标直接使用包或子例程变量,则令人头疼。阅读代码时,每次都需要检查光标所依赖的状态。使用游标参数可以立即看到。