Oracle SQL : delete from (query), delete which table's row?

今天群里面一位朋友问了一个问题如下 :

                                 DELETE FROM
                                (SELECT * FROM EPAD_MENU EM, MSG_DESC MD
                                WHERE MD.MD_TABLE = 'epad_menu' AND MD.MD_FIELD = 'em_id'
                                AND MD.MD_VALUE = EM.EM_ID AND EM.EM_BOOK_CODE = 'aa')

为什么删除的是 MSG_DESC的数据?

于是找了个测试库测试一下 :

SQL> create table t1(id int primary key,info varchar2(10));

Table created.

SQL> create table t2(id int primary key,info varchar2(10));

Table created.
SQL> insert into t1 values (1,'digoal');

1 row created.

SQL> insert into t1 values (2,'digoal');

1 row created.

SQL> insert into t2 values (1,'digoal');

1 row created.

SQL> insert into t2 values (2,'digoal');

1 row created.
SQL> commit;

Commit complete.

下面来写个类似的delete语句 :

SQL> delete from (select * from t1,t2 where t1.id=1 and t2.id=t1.id and t2.info='digoal');

1 row deleted.

SQL> select * from t2;

        ID INFO
---------- ----------
         1 digoal
         2 digoal

SQL> select * from t1;

        ID INFO
---------- ----------
         2 digoal

把t1.数据删了, t2的没有动.

下面把t1和t2的顺序换一下 :

SQL> rollback;

Rollback complete.

SQL> delete from (select * from t2,t1 where t1.id=1 and t2.id=t1.id and t2.info='digoal');

1 row deleted.

SQL> select * from t1;

        ID INFO
---------- ----------
         2 digoal
         1 digoal

SQL> select * from t2;

        ID INFO
---------- ----------
         2 digoal

SQL> rollback;

结果把t2的数据删了, t1没动.

来从执行计划看看是啥原因 :

SQL> explain plan for delete from (select * from t2,t1 where t1.id=1 and t2.id=t1.id and t2.info='digoal');

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 1934688782

----------------------------------------------------------------------------------------------
| Id  | Operation                     | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | DELETE STATEMENT              |              |     1 |    33 |     1   (0)| 00:00:01 |
|   1 |  DELETE                       | T2           |       |       |            |          |
|   2 |   NESTED LOOPS                |              |     1 |    33 |     1   (0)| 00:00:01 |
|*  3 |    TABLE ACCESS BY INDEX ROWID| T2           |     1 |    20 |     1   (0)| 00:00:01 |
|*  4 |     INDEX UNIQUE SCAN         | SYS_C0065664 |     1 |       |     1   (0)| 00:00:01 |
|*  5 |    INDEX UNIQUE SCAN          | SYS_C0065663 |     1 |    13 |     0   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter("T2"."INFO"='digoal')
   4 - access("T2"."ID"=1)
   5 - access("T1"."ID"=1)

19 rows selected.

SQL> explain plan for delete from (select * from t1,t2 where t1.id=1 and t2.id=t1.id and t2.info='digoal');

Explained.

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2064908203

----------------------------------------------------------------------------------------------
| Id  | Operation                     | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | DELETE STATEMENT              |              |     1 |    33 |     2   (0)| 00:00:01 |
|   1 |  DELETE                       | T1           |       |       |            |          |
|   2 |   NESTED LOOPS                |              |     1 |    33 |     2   (0)| 00:00:01 |
|*  3 |    INDEX UNIQUE SCAN          | SYS_C0065663 |     1 |    13 |     1   (0)| 00:00:01 |
|*  4 |    TABLE ACCESS BY INDEX ROWID| T2           |     1 |    20 |     1   (0)| 00:00:01 |
|*  5 |     INDEX UNIQUE SCAN         | SYS_C0065664 |     1 |       |     0   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - access("T1"."ID"=1)
   4 - filter("T2"."INFO"='digoal')
   5 - access("T2"."ID"=1)

19 rows selected.
时间: 2024-09-25 10:52:35

Oracle SQL : delete from (query), delete which table's row?的相关文章

oracle语句-oracle sql语句建表约束问题

问题描述 oracle sql语句建表约束问题 create table workers ( wID char(5) check ( wID like'[a-z][0-9][0-9][0-9][0-9]'), wName char(10) NOT NULL, wSex char() check ( wSex IN ('女','男')), wTel char(11) check ( wTel like'[0-9][0-9][0-9][0-9][0-9][0-9] [0-9][0-9][0-9][0

Oracle 闪回特性(Flashback Query、Flashback Table)

--================================================== -- Oracle 闪回特性(Flashback Query.Flashback Table) --==================================================       Oracle 闪回查询是指针对特定的表来查询特定的时间段内的数据变化情况来确定是否将表闪回到某一个特定的时刻以保证数据无讹误存在. 这个特性大大的减少了采用时点恢复所需的工作量以及

实例理解SQL中truncate和delete的区别_MsSql

本文以一个简单实例为大家介绍了SQL中truncate和delete的区别,帮助大家理解,具体内容如下 ---创建表Table1 IF OBJECT_ID('Table1','U') IS NOT NULL DROP TABLE Table1 GO CREATE TABLE Table1 (ID INT NOT NULL, FOID INT NOT NULL) GO --插入测试数据 INSERT INTO Table1 VALUES(1,101),(2,102),(3,103),(4,104)

实例理解SQL中truncate和delete的区别

本文以一个简单实例为大家介绍了SQL中truncate和delete的区别,帮助大家理解,具体内容如下 ---创建表Table1 IF OBJECT_ID('Table1','U') IS NOT NULL DROP TABLE Table1 GO CREATE TABLE Table1 (ID INT NOT NULL, FOID INT NOT NULL) GO --插入测试数据 INSERT INTO Table1 VALUES(1,101),(2,102),(3,103),(4,104)

SQL中truncate、delete与drop区别

一.相同点 1 truncate.不带where子句的delete.drop都会删除表内的数据 2 drop.truncate都是DDL语句(数据定义语言),执行后会自动提交 二.不同点 1 truncate 和 delete 只删除数据不删除表的结构(定义) drop语句将删除表的结构被依赖的约束(constrain).触发器(trigger).索引(index):依赖于该表的存储过程/函数将保留,但是变为 invalid 状态. 2 delete语句是数据库操作语言(dml),这个操作会放到

oracle-PLSQL SQL WINDOW不执行DELETE语句问题!!!

问题描述 PLSQL SQL WINDOW不执行DELETE语句问题!!! 系统win7 oracle10G plsql Version 8.0.2.1505 在plsql SQL WINDOW执行DELETE FROM AAA; 执行后没反应, 换了句DELETE FROM; 执行不报错,像是DELETE 被屏蔽了一样. 但是在plsql COMMAND WINDOW是可以正常执行. 卸载重装还是这样.郁闷. 求大神解救. 解决方案 不用郁闷了,应该是你的安装程序有问题,建议你用PLSQL D

详解SQL中drop、delete和truncate的异同_MsSql

第一:相同点:  truncate和不带where子句的delete,以及drop 都会删除表内的数据 第二:不同点: 1. truncate和delete只删除数据不删除表的结构(定义)     drop 语句将删除表的结构被依赖的约束(constrain).触发器(trigger).索引(index);依赖于该表的存储过程/函数将保留,但是变为 invalid 状态. 2. delete 语句是数据库操作语言(dml),这个操作会放到 rollback segement 中,事务提交之后才生

详解SQL中drop、delete和truncate的异同

第一:相同点: truncate和不带where子句的delete,以及drop 都会删除表内的数据 第二:不同点: 1. truncate和delete只删除数据不删除表的结构(定义)     drop 语句将删除表的结构被依赖的约束(constrain).触发器(trigger).索引(index);依赖于该表的存储过程/函数将保留,但是变为 invalid 状态. 2. delete 语句是数据库操作语言(dml),这个操作会放到 rollback segement 中,事务提交之后才生效

oracle sql语句性能优化

oracle|性能|优化|语句 1.选用适合的ORACLE优化器ORACLE的优化器共有3种 A.RULE (基于规则) b.COST (基于成本) c.CHOOSE (选择性) 设置缺省的优化器,可以通过对init.ora文件中OPTIMIZER_MODE参数的各种声明,如RULE,COST,CHOOSE,ALL_ROWS,FIRST_ROWS . 你当然也在SQL句级或是会话(session)级对其进行覆盖. 为了使用基于成本的优化器(CBO, Cost-Based Optimizer) ,