update关联更新,主查询切记写上条件!!!!!!!!!!!

SQL> select empno,ename,deptno,dname from emp;

     EMPNO ENAME	  DEPTNO DNAME
---------- ---------- ---------- --------------------------------------------------
      7369 SMITH	      20 noname
      7499 ALLEN	      30 noname
      7521 WARD 	      30 noname
      7566 JONES	      20 noname
      7654 MARTIN	      30 noname
      7698 BLAKE	      30 noname
      7782 CLARK	      10 noname
      7788 SCOTT	      20 noname
      7839 KING 	      10 noname
      7844 TURNER	      30 noname
      7876 ADAMS	      20 noname

     EMPNO ENAME	  DEPTNO DNAME
---------- ---------- ---------- --------------------------------------------------
      7900 JAMES	      30 noname
      7902 FORD 	      20 noname
      7934 MILLER	      10 noname
      1111 YODA 		 noname

已选择15行。


 需求:
-----------只更新部门10、20的dname

一般人都会这么写:
UPDATE emp
   SET emp.dname =
       (SELECT dept.dname
          FROM dept
         WHERE dept.deptno = emp.deptno
           AND dept.deptno IN (10, 20));

SQL>  select empno,ename,deptno,dname from emp;

     EMPNO ENAME	  DEPTNO DNAME
---------- ---------- ---------- --------------------------------------------------
      7369 SMITH	      20 RESEARCH
      7499 ALLEN	      30
      7521 WARD 	      30
      7566 JONES	      20 RESEARCH
      7654 MARTIN	      30
      7698 BLAKE	      30
      7782 CLARK	      10 ACCOUNTING
      7788 SCOTT	      20 RESEARCH
      7839 KING 	      10 ACCOUNTING
      7844 TURNER	      30
      7876 ADAMS	      20 RESEARCH

     EMPNO ENAME	  DEPTNO DNAME
---------- ---------- ---------- --------------------------------------------------
      7900 JAMES	      30
      7902 FORD 	      20 RESEARCH
      7934 MILLER	      10 ACCOUNTING
      1111 YODA

已选择15行。

我只更新10和20为扫描30被更新成空值了呢?

Plan hash value: 2456638059
 
-----------------------------------------------------------------------------------------
| Id  | Operation                     | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT              |         |    15 |   450 |     2   (0)| 00:00:01 |
|   1 |  UPDATE                       | EMP     |       |       |            |          |
|   2 |   TABLE ACCESS FULL           | EMP     |    15 |   450 |     2   (0)| 00:00:01 |
|*  3 |   FILTER                      |         |       |       |            |          |
|   4 |    TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    13 |     1   (0)| 00:00:01 |
|*  5 |     INDEX UNIQUE SCAN         | PK_DEPT |     1 |       |     0   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   3 - filter(:B1=10 OR :B2=20)
   5 - access("DEPT"."DEPTNO"=:B1)
       filter("DEPT"."DEPTNO"=10 OR "DEPT"."DEPTNO"=20)


当主查询给子查询传值的时候:B1


相当于子查询为:

SELECT dept.dname
          FROM dept
         WHERE dept.deptno = :B1;
           AND dept.deptno IN (10, 20)

当传入30部门时,返回为空,所以30部分的数据都被跟新为空了


正确写法:
UPDATE emp
   SET emp.dname =
       (SELECT dept.dname
          FROM dept
         WHERE dept.deptno = emp.deptno
           AND dept.deptno IN (10, 20))
           where emp.deptno in (10, 20)

原文地址:https://www.cnblogs.com/hzcya1995/p/13352160.html