【问题标题】:oracle cursor concurrency with insert stmtoracle游标并发插入stmt
【发布时间】:2020-12-12 19:20:05
【问题描述】:

光标的结果是在打开时确定的?但下面的演示揭示了一个区别:

drop table Highschooler;
drop table w;
create table Highschooler( grade int );
create table w( grade int );

insert into Highschooler(grade) values (13);
insert into Highschooler(grade) values(14);
insert into Highschooler(grade) values (15);
insert into w values (16);

select * from Highschooler;
select * from w;

create or replace create function ff(a int) return int is 
   total int := 0;
begin
  select  count(grade) into total from w where grade > a ;
  return total;
end;

DECLARE
   my_var int :=0;
   my_var2 int := 0;
   my_var3 int := 0;
   CURSOR CC IS select ff(grade) from Highschooler for update;
BEGIN
   open CC;
   fetch CC into my_var;
   insert into w values (16);
   fetch CC into my_var2;
   fetch CC into my_var3;
   dbms_output.put_line(my_var || '  - '  || my_var2 || ' - ' || my_var3);
   close CC;
end;

输出:

GRADE
13
14
15
Download CSV
3 rows selected.

Result Set 4
GRADE
16
Statement processed. ------- the insert stmt in 'insert into w values (16);' affect the cursor's output here
1  - 2 - 2

【问题讨论】:

  • 您不介意将您的示例仅归结为相关部分,即一个带有一个插入和游标提取的表,并更详细地描述您观察到的差异吗?

标签: oracle database-cursor


【解决方案1】:

您的函数包含另一个光标,该光标仅在执行时打开。这就是为什么您通常不应该只使用函数来执行 SQL - 您最终会得到逻辑上损坏的数据,因为每次执行都将使用不同的 SCN 点。

【讨论】:

  • 打开游标返回时游标执行完成?如果是这样,光标中的函数也运行完成。如果没有,光标将在打开后继续执行,直到它被关闭?还是仅在游标的每个结果中调用的函数被提取?如果这是原因,为什么游标的结果不是选择 stmt 的结果集,而是调用函数之前的值?谢谢你的回复:)
【解决方案2】:

定义光标不使用函数,如

CURSOR CC IS 
select  (select  count(grade) from w where grade > h.grade) as ff 
from Highschooler h;

这将导致预期的结果

1  - 1 - 1

另请注意,避免使用函数将导致更好的性能,因为您省略了上下文切换

【讨论】:

  • 是的,让我困惑的是,当光标移动时,函数的使用会影响结果
猜你喜欢
  • 1970-01-01
  • 2017-08-03
  • 1970-01-01
  • 2014-02-16
  • 1970-01-01
  • 2011-06-10
  • 1970-01-01
相关资源
最近更新 更多