如何使用内部联接更新表

时间:2012-02-07 10:46:43

标签: sql oracle

我有两张桌子Emp&部门

SQL> select * from emp where rownum<4;

     EMPNO ENAME      JOB              MGR        SAL     DEPTNO
---------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902        800
      7499 ALLEN      SALESMAN        7698       1600
      7521 WARD       SALESMAN        7698       1250

SQL> select * from dept;

    DEPTNO DNAME           LOC                  EMPNO
---------- --------------- --------------- ----------
        10 ACCOUNTING      NEW YORK              7369
        20 RESEARCH        DALLAS                7499
        30 SALES           CHICAGO               7521
        40 OPERATIONS      BOSTON

我想更新emp的deptno,它应该与dept table&amp;的deptno相同。 dept的empno应该等于emp的empno;总之,我想使用emp;

使用内连接操作更新dept

2 个答案:

答案 0 :(得分:3)

在Oracle中,执行此操作的规范方法是MERGE语句:

MERGE INTO emp e
USING dept d
   ON (d.empno = e.empno)
 WHEN MATCHED THEN UPDATE SET e.deptno = d.deptno

但是,如果您使用的是Oracle 9(见下文),或者您的表上有域索引(例如Oracle Text),则上述操作无效

asked a question previously关于MERGE语句的作用。

e的每一行都必须通过连接条件(ON部分)连接到无{1}}或者只有d的一行,否则你将获得ORA-30926 “无法在源表中获得一组稳定的行。”

未连接到任何部门的e行未更改,d未连接到任何员工的行可用于INSERTS(并且在Oracle 9中必须用于WHEN NOT MATCHED THEN INSERT(cols) VALUES(...)子句;如果您使用的是Oracle 9,则此答案不适合您。)

另一种选择,但受到相同的基本限制:

UPDATE (SELECT e.deptno edeptno, d.deptno ddeptno
          FROM emp e, dept d
         WHERE e.empno = d.empno)
   SET edeptno = ddeptno

或者

UPDATE emp
   SET deptno = ( SELECT deptno FROM dept WHERE empno = emp.empno )
 WHERE empno IN ( SELECT empno FROM dept )

正如您所看到的,解决方案众多,但受到限制。

答案 1 :(得分:2)

Update emp e 
set deptno = ( select DEPTNO from dept d where d.empno = e.empno )

只要DEPT中的EMPNO是唯一的,它就会起作用。

编辑 - 正如所指出的,如果没有EMPNO,这将失败。

非常HACKY修复此问题,

  

更新版权

     

设置deptno =(

         SELECT RESULT FROM (
          select DEPTNO RESULT from dept d where d.empno = e.empno
           UNION ALL 
           select NULL from DUAL 
           ORDER BY 1
           ) WHERE ROWNUM < 2
         )