예를 들어, 특정 사원의 새로운 급여가 저장된 'NEW_SAL'이라는 테이블이 있다.
'NEW_SAL'의 내용은 다음과 같다.
/* Oracle */
create table new_sal(
deptno number not null,
sal number,
constraint fk_new_sal_deptno foreign key (deptno) references dept (deptno)
);
/* MAIRA */
create table new_sal(
deptno int not null,
sal int,
constraint fk_new_sal_deptno foreign key (deptno) references dept (deptno)
);
/* COMMON */
insert into new_sal (deptno, sal) values
(
10, 4000
);
>>
DEPTNO SAL
10 4000
'DEPTNO' 열을 'NEW_SAL' 테이블의 기본 키(PRIMARY KEY)로 잡아주라고 한다.
/* Oracle */
alter table new_sal
add constraint pk_new_sal_deptno primary key (deptno);
>>Table altered.
/* MARIA */
alter table new_sal
add constraint pk_new_sal_deptno primary key (deptno);
>>
Query OK, 0 rows affected, 1 warning (0.246 sec)
Records: 0 Duplicates: 0 Warnings: 1
show warnings;
>>
+---------+------+---------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------+
| Warning | 1280 | Name 'pk_new_sal_deptno' ignored for PRIMARY key. |
+---------+------+---------------------------------------------------+
MARIA에서 PK 제약조건에 이름을 붙일 수 없다.
그래서 '제약조건명을 붙이는 건 무시하였다'('그런 거 우린 안 해요')라 한다.
PK 설정은 정상적으로 이루어진다.
이와 같은 업데이트는 일반적으로 상관 서브쿼리 또는 CTE를 사용하여 수행된다.
또 다른 기법은 뷰 또는 인라인 뷰를 생성한 다음, 해당 뷰를 업데이트하는 것이다.
/* MARIA */
update emp e, new_sal ns
set e.sal = ns.sal,
e.comm = ns.sal/2
where e.deptno = ns.deptno;
>>
Query OK, 4 rows affected (0.003 sec)
Rows matched: 4 Changed: 4 Warnings: 0
MARIA에서의 UPDATE
문은 굉장히 간결하고 알기 쉽다.
UPDATE
문에 직접적으로 JOIN
을 사용할 수 있다.
그러나 이 쿼리는 Oracle에서는 작동하지 않는다.
Oracle에서는 다음과 같은 쿼리를 사용한다.
/* Oracle */
update(
select e.sal as emp_sal, e.comm as emp_comm,
ns.sal as ns_sal, ns.sal/2 as ns_comm
from emp e, new_sal ns
where e.deptno = ns.deptno
)
set emp_sal = ns_sal, emp_comm = ns_comm
>>
Statement processed.
인라인 뷰를 생성하고 이 뷰에 대한 업데이트를 실행하는 쿼리를 사용한다.
이러한 형태의 업데이트에 있어 '키 보존'을 알아야 한다.
/* 위의 인라인 뷰와 동일한 유형의 쿼리임 */
select e.empno, e.deptno e_deptno, ns.sal, ns.deptno ns_deptno
from emp e, new_sal ns
where e.deptno = ns.deptno;
>>
EMPNO E_DEPTNO SAL NS_DEPTNO
7782 10 4000 10
7934 10 4000 10
7839 10 4000 10
3 rows selected.
결과셋에서는 NS_DEPTNO('NEW_SAL'테이블의 'DEPTNO')가 고유하지 않음을 알 수 있다.
인라인 뷰를 생성하고, 이에 대한 업데이트를 실행하는 쿼리에서
해당 값이 결과셋에서 고유하지 않은 경우라도 해당 값이 원본 테이블에서는 고유해야 한다.
'NS_DEPTNO'가 결과셋에서는 중복되어 나왔지만, 'NEW_SAL' 테이블에서는 무조건 고유해야 한다.
그래서 처음 테이블 생성 때 PK로 만들어준 것이다.
이런 설정을 해두면, 결과셋에서 해당 값이 고유하지 않다고 해도 키가 보존된 것으로 간주되고 업데이트가 정상적으로 행해진다.
UPDATE
에서 직접 JOIN
이 가능한 MARIA의 쿼리가 굉장히 편해보인다상관 서브쿼리: 읽은 글
1. SQL 상관 서브쿼리: muntari Log
2. 상관관계 서브쿼리: Java 맛 코드의 향기