【问题标题】:Oracle Race Conditions when doing select union select and insert执行选择联合选择和插入时的Oracle竞争条件
【发布时间】:2013-11-18 03:37:17
【问题描述】:

我有一个 Oracle 数据库,我正在尝试以编程方式确定视图是否具有与其从中提取的表相同的记录数。这可能不是因为视图可能错误地查询了另一个模式中的表。一开始我试着做

select count(*) from view  

然后做

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

并比较结果。

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

我不想虚报问题,所以想到了做两个查询的并集:

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

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

基本上我需要知道 Oracle 是在数据快照上进行这两个选择还是数据是动态的。

【问题讨论】:

    标签: sql oracle select insert union


    【解决方案1】:

    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
    

    会显示表中不存在的数据

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-11
      • 2022-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多