【问题标题】:Write consistency with nested subquery in Oracle编写与 Oracle 中嵌套子查询的一致性
【发布时间】:2011-10-24 14:01:43
【问题描述】:

我已经阅读了许多关于写入一致性的gory 详细信息,并且我了解它在简单情况下的工作原理。我不清楚的是这对嵌套子查询意味着什么。

这是一个具体的例子:

带有 PK id 和其他列 state、temp 和 date 的表。

UPDATE table SET state = DECODE(state, 'rainy', 'snowy', 'sunny', 'frosty') WHERE id IN (
  SELECT id FROM (
    SELECT id,state,temp from table WHERE date > 50      
  ) WHERE (state='rainy' OR state='sunny') AND temp < 0
)

真实的事情更复杂(在最里面的查询中),但这抓住了本质。

如果我们假设 state 列不可为空,此更新是否会由于并发修改而失败(即,DECODE 函数找不到匹配的值,'rainy' 或 'sunny' 的值,因此尝试将 null 插入不可为空的列中)?

【问题讨论】:

    标签: sql oracle oracle10g


    【解决方案1】:

    Oracle 支持“语句级读写一致性”(与所有其他严肃的 DBMS 一样)

    这意味着整个语句将不会看到语句启动后对数据库发生的任何更改。

    由于您的 UPDATE 是单个语句,因此不应出现解码返回 null 的情况。

    顺便说一句:语句可以简化,子查询不需要外层的SELECT:

    UPDATE table SET state = DECODE(state, 'rainy', 'snowy', 'sunny', 'frosty') 
    WHERE id IN (
        SELECT id
        FROM table 
        WHERE date > 50      
        AND (state='rainy' OR state='sunny') 
        AND temp < 0
    )
    

    【讨论】:

    • 是的,在我的简化示例中可以进行简化,但在原始查询中不行,因为内部谓词更复杂,涉及对不满足外部谓词的行进行聚合。
    【解决方案2】:

    我认为没有任何理由担心。子查询仅显式检索具有 state 'rainy' 或 'sunny' 的行的 ID,这就是外部 DECODE 将得到的。整个事情就是一个语句,并且将在事务边界内执行。

    【讨论】:

    • 看起来您对设计行为的看法是正确的,但事实证明它在实践中可能会有所不同(请参阅下面的答案)。
    【解决方案3】:

    回答我自己的问题:原来 Oracle 中有一个错误可能导致此查询失败。 Tom Kyte 已在here 开始的讨论中确认了详细信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 2013-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      相关资源
      最近更新 更多