4

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

我理解为什么这是固定值的情况。在下面的游标中,值固定为 1。如果我有一个相同的不同游标,除了 1 变为 2,这是一个不同的查询。到目前为止清楚。

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

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

我进行了广泛的搜索,但在任何地方我都可以找到关于literals的示例,就像上面的例子一样,但是没有关于 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;
4

2 回答 2

5

首先,好问题。

我想做一个小引述:

每个对 PL/SQL 变量的引用实际上都是一个绑定变量。

话说回来,

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 变量的引用实际上都是一个绑定变量。

资源

于 2015-04-21T14:21:51.090 回答
1

阅读精品手册:PL/SQL 静态 SQL

一个 PL/SQL 静态 SQL 语句可以有一个 PL/SQL 标识符,只要它的 SQL 对应项可以有一个绑定变量的占位符。PL/SQL 标识符必须标识变量或形式参数。

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

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

通常,PL/SQL 仅在会话第一次打开显式游标时解析它,并且仅在语句第一次运行时解析 SQL 语句(创建隐式游标)。

所有解析的 SQL 语句都被缓存。只有当一条 SQL 语句被新的 SQL 语句从缓存中老化时,它才会重新解析它。尽管必须先关闭显式游标才能重新打开它,但 PL/SQL 不需要重新解析相关联的查询。如果您关闭并立即重新打开显式游标,PL/SQL 不会重新分析关联的查询。

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

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

于 2015-08-20T04:30:06.157 回答