Oracle 游标中的PL/SQL变量是否与绑定参数有效相同?
我听说使用绑定变量更有效,因为对于使用不同绑定值的后续调用,查询本身仍然是相同的,因此不再需要对其进行解析 我理解为什么固定值会出现这种情况。在下面的光标中,该值固定为1。如果我有一个相同的不同游标,除了1变为2,它是一个不同的查询。到目前为止还没有Oracle 游标中的PL/SQL变量是否与绑定参数有效相同?,oracle,plsql,cursor,bind-variables,parameterbinding,Oracle,Plsql,Cursor,Bind Variables,Parameterbinding,我听说使用绑定变量更有效,因为对于使用不同绑定值的后续调用,查询本身仍然是相同的,因此不再需要对其进行解析 我理解为什么固定值会出现这种情况。在下面的光标中,该值固定为1。如果我有一个相同的不同游标,除了1变为2,它是一个不同的查询。到目前为止还没有 declare cursor C_CURSOR is select * from TESTTABLE pt where pt.ID = 1; 但是我想知道在游标中使用PL/SQL变量时是否也是这样。它们是像固定值一样展开的,还是被解
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;
首先,好问题 我想引用一句话: 对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;
/
现在,您可能会认为必须用bind变量替换p_empno。然而,好消息是,对PL/SQL变量的每个引用实际上都是一个绑定变量
阅读精细手册:
PL/SQL静态SQL语句可以有PL/SQL标识符,只要它的SQL对应项可以有绑定变量的占位符。PL/SQL标识符必须标识变量或形式参数
从SQL引擎的角度来看,您的两个示例代码段都是等效的,并且性能相同
阅读更多相同的精细手册:
通常,PL/SQL仅在会话第一次打开显式游标时解析它,并且仅在语句第一次运行时解析SQL语句(创建隐式游标)
所有解析的SQL语句都被缓存。只有当SQL语句被新的SQL语句从缓存中过时时,才会重新解析SQL语句。尽管必须先关闭显式游标,然后才能重新打开它,但PL/SQL不需要重新分析关联的查询。如果关闭并立即重新打开显式游标,PL/SQL不会重新分析关联查询
因此,更改绑定变量不需要SQL语句解析
从代码可读性(即维护)的角度来看,使用的第二个代码段更优越。这在小代码段中并不明显,但在大型PL/SQL程序中,如果游标直接使用包或子例程变量,则会令人头痛。阅读代码时,每次都需要检查光标所依赖的状态。使用游标参数可以立即看到这一点。查找游标共享参数。是的,对PL/SQL变量的每个引用实际上都是一个绑定变量。@ruudvan我找到了。我在寻找答案时发现了这一点,但它只与我的问题有着千丝万缕的联系。游标共享与绑定窥视和性能问题更相关。不要忘记,它是针对11g及以上版本的,因为它是在11g中引入的。@LalitKumarB,你完全正确。我只是在我已经评论过之后才意识到。我不想删除它,以防有人通过sql而不是pl/sql来这里:)这正是我的想法和希望。我就是找不到证明它的文件。非常感谢你提供了这一点。