UPDATE
UPDATE#
구문#
update ::=#
set_clause_list ::=#
where_clause ::=#
limit_clause ::=#
tbl_ref ::=#
one_table ::=#
join_table ::=#
전제 조건#
SYS 사용자, 테이블 소유자, UPDATE ANY TABLE 시스템 권한을 가진 사용자 및 테이블에 대한 UPDATE 객체 권한을 가진 사용자만이 이 구문으로 해당 테이블의 데이터를 갱신할 수 있다.
뷰의 레코드를 UPDATE할 때 사용자는 베이스 테이블에 대해서 위와 동일한 권한을 가져야 한다.
설명#
조건을 만족하는 레코드를 찾아 명시한 칼럼들의 값을 변경하는 구문이다.
파티션을 명시할 경우 해당 파티션에서 조건을 만족하는 레코드의 칼럼 값을 변경한다.
user_name#
변경될 레코드가 속한 테이블의 소유자 이름을 명시한다. 생략하면 Altibase는 테이블이 현재 세션에 연결된 사용자의 스키마에 속한 것으로 간주한다.
tbl_name#
변경될 레코드가 속한 테이블의 이름을 명시한다.
view_name#
갱신될 뷰의 이름을 명시한다.
subquery#
갱신 대상이 될 뷰를 서브쿼리로 명시한다.
set_clause_list#
변경할 칼럼 이름과 값을 명시한다. 이 절에서 부질의를 사용할 수 있으며, 아래의 사항을 유의한다.
- 부질의는 한 개의 행만 반환해야 한다.
- SET절에 명시된 칼럼의 개수와 검색 대상 칼럼의 개수가 동일해야 한다.
- 부질의에 대한 결과가 없으면 칼럼에 NULL이 갱신된다.
- 부질의를 사용할 때, 칼럼에 DEFAULT을 할당하면 칼럼의 DEFAULT 속성 값으로 갱신된다.
TIMESTAMP 칼럼의 데이터 수정#
TIMESTAMP 칼럼에 대해 UPDATE문 수행 시 기본적으로 칼럼 값이 시스템 시간 값으로 갱신된다. 따라서 TIMESTAMP 칼럼의 데이터 수정 시 값을 명시하지 않으면 널이 아닌 시스템 시간 값으로 변경된다.
TIMESTAMP 칼럼의 값을 시스템 시간으로 변경하는 또다른 방법은 칼럼 값에 DEFAULT키워드를 사용하는 것이다.
returning_clause#
DELETE 구문의 returning_clause를 참고하라.
multiple_update #
join 조건을 만족하는 레코드를 찾아 명시한 칼럼들의 값을 변경하는 구문이다.
multiple update 제약 사항:
- limit_clause 와 returning_clause 를 사용할 수 없다.
- dictionary table 을 사용할 수 없다.
- full outer join 을 사용할 수 없다.
tbl_ref#
multiple update 를 하기 위한 table 을 명시한다.
one_table#
한 개의 table이거나 혹은 view 를 명시한다.
join_table#
table 사이의 join 조건을 명시한다.
HINTS 옵션#
힌트의 문법과 자세한 설명은 "힌트 구문"과 "힌트 목록"을 참고하기 바란다.
주의 사항#
- SET 절에 같은 칼럼을 두번 이상 사용할 수 없다.
- 파티션 키 칼럼의 값이 수정되어 그 데이터가 포함된 레코드가 다른 파티션으로 이동해야 할 필요가 있을 경우, 파티션드 테이블이 ENABLE ROW MOVEMENT 옵션을 이용해서 생성되었거나 ALTER TABLE ENABLE ROW MOVEMENT 구문으로 테이블 속성이 변경되었다면 레코드가 자동으로 이동되지만, 그렇지 않을 때에는 에러가 발생한다.
- 널 제약조건이 있는 칼럼에 널을 삽입하거나 그 칼럼의 값을 널로 변경할 수 없다.
- CHECK 제약조건으로 인해 UPDATE가 실패할 수 있다.
예제#
칼럼 데이터 갱신#
<질의> 이름이 Davenport인 직원의 월급을 갱신하라.
iSQL> UPDATE employees
SET salary = 2500
WHERE e_lastname = 'Davenport';
1 row updated.
<질의> 전 직원의 월급을 7% 인상하라.
iSQL> UPDATE employees
SET salary = salary * 1.07;
20 rows updated.
WHERE 절에 부질의를 사용해서 데이터 갱신#
<질의> MYLEE 직원이 받은 주문들의 수량을 50개씩 빼라.
iSQL> UPDATE orders
SET qty = qty - 50
WHERE eno IN(
SELECT eno
FROM employees
WHERE e_lastname ='Hammond');
9 rows updated.
파티션드 테이블의 데이터 갱신#
iSQL> UPDATE T1 PARTITION(P1) SET I1 = 200;
SET 절에 부질의를 갖는 데이터 갱신#
<질의> 다음 예제는 두개의 중첩된 SELECT 부질의를 갖는 UPDATE 문의 구조를 보여준다.
iSQL> CREATE TABLE bonuses
(eno INTEGER, bonus NUMBER(10, 2) DEFAULT 100, commission NUMBER(10, 2) DEFAULT 50);
Create success.
iSQL> INSERT INTO bonuses(eno)
(SELECT e.eno FROM employees e, orders o
WHERE e.eno = o.eno
GROUP BY e.eno);
3 rows inserted.
iSQL> SELECT * FROM bonuses;
BONUSES.ENO BONUSES.BONUS BONUSES.COMMISSION
------------------------------------------------
12 100 50
19 100 50
20 100 50
3 rows selected.
iSQL> UPDATE bonuses
SET eno = eno + 100, (bonus, commission) =
(SELECT 1.1 * AVG(bonus), 1.5 * AVG(commission) FROM bonuses)
WHERE eno IN
(SELECT eno
FROM orders
WHERE qty >= 10000);
1 row updated.
iSQL> SELECT * FROM bonuses;
BONUSES.ENO BONUSES.BONUS BONUSES.COMMISSION
------------------------------------------------
12 100 50
20 100 50
119 110 75
3 rows selected.
Note: WHERE 절의 부질의 결과가 한 건도 없으면 어떠한 레코드도 영향을 받지 않으나, SET 절의 부질의 결과가 한 건도 없으면 해당 칼럼은 널값으로 갱신될 것이다.
iSQL> UPDATE orders
SET qty = qty - 50
WHERE eno IN(
SELECT eno
FROM employees
WHERE e_lastname ='Frederick');
No rows updated.
iSQL> UPDATE employees
SET dno =
(SELECT dno
FROM departments
WHERE dep_location = 'Timbuktu');
20 rows updated.
iSQL> SELECT e_lastname, dno
FROM employees
WHERE eno = 12;
E_LASTNAME DNO
-------------------------------
Hammond
1 row selected.
<질의> 다음 예제는 UPDATE질의문의 SET절에 DEFAULT를 칼럼에 할당한 후에 질의문을 수행한다.
iSQL> CREATE TABLE EMPLOYEES (
ENO INTEGER PRIMARY KEY,
E_LASTNAME CHAR(20) NOT NULL,
E_FIRSTNAME CHAR(20) NOT NULL,
EMP_JOB VARCHAR(15),
EMP_TEL CHAR(15),
DNO SMALLINT,
SALARY NUMBER(10,2) DEFAULT 0,
SEX CHAR(1),
BIRTH CHAR(6),
JOIN_DATE DATE,
STATUS CHAR(1) DEFAULT 'H' );
Create success.
iSQL> SELECT E_FIRSTNAME, SALARY, EMP_JOB FROM EMPLOYEES WHERE EMP_JOB = 'manager' ;
E_FIRSTNAME SALARY EMP_JOB
-------------------------------------------------------
Gottlieb 500 manager
Xiong manager
Wei-Wei 2300 manager
3 rows selected.
iSQL> UPDATE EMPLOYEES SET SALARY=DEFAULT WHERE EMP_JOB = 'manager';
3 rows updated.
iSQL> SELECT E_FIRSTNAME, SALARY, EMP_JOB FROM EMPLOYEES WHERE EMP_JOB = 'manager';
E_FIRSTNAME SALARY EMP_JOB
-------------------------------------------------------
Gottlieb 0 manager
Xiong 0 manager
Wei-Wei 0 manager
3 rows selected.
Returning 절을 사용한 갱신#
<질의> 다음 예제는 갱신된 행의 값을 출력 바인드 변수 :v1, :v2로 반환한다.
iSQL> create table employees ( eno integer, ename varchar(20));
Create success.
iSQL> var v1 output integer;
iSQL> var v2 output varchar(30);
iSQL> insert into employees values (1, 'jake');
iSQL> insert into employees values (2, 'nikita');
iSQL> insert into employees values (3, 'dana');
iSQL> prepare update employees set ename='rachel' where eno=3 return eno, ename into :v1, :v2;
1 row updated.
iSQL> print var
[ HOST VARIABLE ]
-------------------------------------------------------
NAME TYPE VALUE
-------------------------------------------------------
V1 INTEGER 3
V2 VARCHAR(30) rachel
조인 뷰의 데이터 갱신#
<질의> employees와 departments 테이블의 조인 뷰를 생성한 후, 칼럼 salary를 갱신한다.
iSQL> CREATE VIEW simple_emp AS
SELECT e.eno, e.e_lastname, e.salary, d.dname
FROM employees e, departments d
WHERE e.dno = d.dno;
Create success.
iSQL> select * from simple_emp;
ENO E_LASTNAME SALARY DNAME
-----------------------------------------------------------------------------------
3 Kobain 2000 RESEARCH DEVELOPMENT DEPT 1
16 Chen 2300 RESEARCH DEVELOPMENT DEPT 1
6 Momoi 1700 RESEARCH DEVELOPMENT DEPT 2
13 Jones 980 RESEARCH DEVELOPMENT DEPT 2
10 Bae 4000 SOLUTION DEVELOPMENT DEPT
11 Liu 2750 SOLUTION DEVELOPMENT DEPT
14 Miura 2003 SOLUTION DEVELOPMENT DEPT
15 Davenport 1000 SOLUTION DEVELOPMENT DEPT
17 Fubuki 1400 QUALITY ASSURANCE DEPT
4 Foster 1800 CUSTOMERS SUPPORT DEPT
1 Moon PRESALES DEPT
5 Ghorbani 2500 PRESALES DEPT
8 Wang MARKETING DEPT
9 Diaz 1200 MARKETING DEPT
18 Huxley 1900 MARKETING DEPT
7 Fleischer 500 BUSINESS DEPT
12 Hammond 1890 BUSINESS DEPT
19 Marquez 1800 BUSINESS DEPT
20 Blake BUSINESS DEPT
19 rows selected.
iSQL> UPDATE simple_emp SET salary=3000 WHERE dname='RESEARCH DEVELOPMENT DEPT 1';
2 rows updated.
Multiple table 갱신#
<질의> employees와 departments 테이블을 join 후 칼럼 salary를 갱신한다.
UPDATE employees e, departments d SET salary=4000 WHERE e.dno = d.dno and d.dname='BUSINESS DEPT';
4 rows updated.