2

我想知道 Oracle 关于子查询以及更新和删除子句的执行的行为是什么。

我想知道甲骨文是否:

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

编辑:

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

删除表 T1;
删除表 IT1;
删除表 OT1;

创建表 T1 (
  ID 整数,
   V 整数,
   枢轴整数
);

创建表 IT1 (
  ID 整数
);

创建表 OT1 (
  ID 整数,
  整数,
   NV 整数
);

插入 T1 (ID,V,PIVOT) 值 (1,1,1);
插入 T1 (ID,V,PIVOT) 值 (2,1,1);

插入 IT1 (ID) 值 (1);
插入 IT1 (ID) 值 (2);

插入 OT1 (ID,NV,FOO) 值 (1,2,0);
插入 OT1 (ID,NV,FOO) 值 (2,2,0);

犯罪;


合并到 T1 目标使用 (
  选择不同的 T1.ID、T1.V、OT1.NV
  从 T1
  T1.ID 上的内部连接 ​​IT1 = IT1.ID
  OT1.ID 上的左外连接 OT1 = IT1.ID
  其中 T1.PIVOT = 1 或 OT1.FOO=40) SRC
开(SRC.ID = 目标.ID)
当匹配然后
更新集 TARGET.V=SRC.NV
删除目标.V=SRC.V;

犯罪;

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

这个声明不像我预期的那样工作。它会删除所有链接。就像删除子句使用修改后的数据执行子查询一样。

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

谢谢,

尼古拉斯

4

3 回答 3

1

SQL 标准保证三个阶段:

  1. 计算所有正在更新的行的新值(只读阶段)
  2. 一次应用所有更改
  3. 约束已验证

这意味着所有“子查询”在第一次写入发生之前逻辑上执行。这可以使用不同的物理计划形状来实现,但这与您的应用程序逻辑无关。

于 2013-08-12T16:10:15.037 回答
0

忘记回答这个问题了。

该问题是已知的,应通过补丁 11.2.0.4(2013 年第四季度发布)修复。

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

alter session set "_complex_view_merging"=false;"  

或者提示NO_MERGE

于 2015-05-25T19:47:59.547 回答
-1

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

于 2013-08-12T15:56:18.057 回答