执行select union select和insert时的Oracle Race Conditions

时间:2013-11-06 18:29:27

标签: sql oracle select insert union

我有一个Oracle数据库,我正在尝试以编程方式确定视图是否与其绘制的表具有相同数量的记录。它可能不是因为视图可能是错误地查询另一个模式中的表。起初我尝试了

select count(*) from view  

然后做

select count(*) from 
(select * from table1
 union 
select * from table2)

并比较结果。

问题是我担心有人在我的第一个查询和第二个查询之间的时间插入表2。在这种情况下,我可能从视图中获得了5条记录,但在插入完成后,我可能会从第二个查询中获得6条记录。

我不想错误地报告问题,所以我考虑做两个查询的联合:​​

select count(*) from view
union 
select count(*) from 
(select * from table1
union select * from table2)

但是我不知道这是否会实际阻止在查询到视图和查询表的联合之间发生插入。

基本上我需要知道Oracle是否在数据快照上进行了两次选择,或者数据是否是动态的。

1 个答案:

答案 0 :(得分:2)

Oracle中的单个SQL语句始终会查看特定SCN(系统更改号)中存在的数据。假设读提交的默认事务隔离级别,那将是查询启动时的SCN。因此,假设纯SQL,UNION的两边都将在查询开始时确定SCN上的数据。

这里需要注意的是视图是否包含对PL / SQL的调用(即用于确定是否包含特定行的函数调用)。 PL / SQL块中的查询将查看数据的当前状态,而不一定是查询开始时的状态。

如果你真的只关心返回的行数而不是实际数据,那么做一些像

这样的事情似乎更合乎逻辑
SELECT (SELECT COUNT(*) cnt FROM view) -
       (SELECT COUNT(*) cnt FROM table) num_diffs
  FROM dual

如果你真的想比较数据

SELECT <<columns>>
  FROM table
MINUS
SELECT <<columns>>
  FROM view

将显示表中不存在的数据i