Oracle MERGE INTO子句与子查询的执行顺序是什么

时间:2013-08-12 15:51:25

标签: sql oracle

我想知道Oracle在子查询以及update和delete子句的执行方面的行为是什么。

我想知道Oracle:

  1. 执行子查询,并为每行执行更新和删除子句
  2. 执行子查询以进行更新,然后执行要删除的子查询
  3. 1)和2),优化器选择最佳策略
  4. 其他?
  5. 修改

    使用的数据库:Oracle 11.2.0.3.0 我有这个漂亮的查询

    DROP TABLE T1;
    DROP TABLE IT1;
    DROP TABLE OT1;
    
    CREATE TABLE T1  (
      ID INTEGER,
       V INTEGER,
       PIVOT INTEGER
    );
    
    CREATE TABLE IT1  (
      ID INTEGER
    );
    
    CREATE TABLE OT1  (
      ID INTEGER,
      FOO INTEGER,
       NV INTEGER
    );
    
    INSERT INTO T1 (ID,V,PIVOT) VALUES (1,1,1);
    INSERT INTO T1 (ID,V,PIVOT) VALUES (2,1,1);
    
    INSERT INTO IT1 (ID) VALUES (1);
    INSERT INTO IT1 (ID) VALUES (2);
    
    INSERT INTO OT1 (ID,NV,FOO) VALUES (1,2,0);
    INSERT INTO OT1 (ID,NV,FOO) VALUES (2,2,0);
    
    commit;
    
    
    MERGE INTO T1 TARGET USING ( 
      SELECT DISTINCT T1.ID,T1.V, OT1.NV 
      FROM T1
      INNER JOIN IT1 ON T1.ID = IT1.ID
      LEFT OUTER JOIN OT1 ON OT1.ID = IT1.ID
      WHERE T1.PIVOT = 1 or OT1.FOO=40) SRC
    ON (SRC.ID = TARGET.ID)
    WHEN MATCHED THEN
    UPDATE SET TARGET.V=SRC.NV
    DELETE WHERE TARGET.V=SRC.V;
    
    commit;
    

    如果某个项目有新版本,则该项目将使用新版本(UPDATE子句)进行更新。如果不是,则销毁该项(DELETE子句)。删除不应该发生

    此声明不符合我的预期。它删除所有链接。就像delete子句用修改后的数据执行子查询一样。

    注意OT1.FOO = 40这里没用,但似乎造成了问题。如果我向子查询添加order by(无论顺序标准如何),语句都能正常工作。

    谢谢,

    尼古拉斯

3 个答案:

答案 0 :(得分:1)

SQL标准保证了三个阶段:

  1. 计算所有正在更新的行的新值(只读阶段)
  2. 一次性应用所有更改
  3. 约束已经过验证
  4. 这意味着所有“子查询”在第一次写入发生之前逻辑执行。这可以使用不同的物理计划形状来实现,但这与您的应用程序逻辑无关。

答案 1 :(得分:0)

忘了回答这个问题。

该问题已知,应通过补丁11。2。4。4(2013年第4季度发布)修复。

Oracle建议采用以下临时解决方法:

alter session set "_complex_view_merging"=false;"  

或提示NO_MERGE

答案 2 :(得分:-1)

我不相信Oracle会保证像这样的复合语句的操作顺序。我希望生成的解释计划将显示操作的确切顺序。我过去曾使用TOAD解析/调整这样的查询。

相关问题