Как обновить таблицу с помощью внутреннего соединения - PullRequest
2 голосов
/ 07 февраля 2012

У меня есть две таблицы Emp & Dept.

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

Я хочу обновить deptno для emp, который должен быть таким же, как deptno для таблицы dept, и где empno of dept должен быть равен empno of emp; Короче говоря, я хочу обновить отдел, используя операцию внутреннего соединения с emp;

Ответы [ 2 ]

3 голосов
/ 07 февраля 2012

В 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)

Я задал вопрос ранее о том, что делают операторы 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 )

Как видите, решений много, но они могут бытьraints.

2 голосов
/ 07 февраля 2012
Update emp e 
set deptno = ( select DEPTNO from dept d where d.empno = e.empno )

Будет работать до тех пор, пока EMPNO в DEPT уникален.

Редактировать - Как указано, это не удастся, если EMPNO не существует.

Очень HACKY исправить это,

Обновление emp e

set 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
         )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...