# 18강. 데이터 갱신하기 - UPDATE
테이블의 셀에 저장되어 있는 값을 갱신하려면 UPDATE 명령을 사용합니다.

**`UPDATE 명령`**
```
UPDATE 테이블명 SET 열1 = 값1, 열2= 값2, ... WHERE 조건식
```

---

## 1. UPDATE로 데이터 갱신하기
- `RDBMS`에서는 `UPDATE` 명령으로 데이터를 갱신할 수 있다.
- `UPDATE` 명령을 테이블의 셀 값을 갱신하는 명령이다.

**`UPDATE 명령`**
```
UPDATE 테이블명 SET 열명 = 값 WHERE 조건식
```

- `DELETE`와 달리 `UPDATE`는 셀 단위로 데이터를 갱신할 수 있다.
- `WHERE` 구에 조건을 지정하면 그에 일치하는 행을 갱신할 수 있다.
- `WHERE` 구를 생략한 경우에는 `DELETE`의 경우와 마찬가지로 테이블의 모든 행이 갱신된다.
- `UPDATE` 명령에서는 `SET` 구를 사용하여 갱신할 열과 값을 지정한다.
- 문법은 `SET 열명 = 값`이다. 이때 `=`은 비교 연산자가 아닌, 값을 대입하는 대입 연산자이다.
- 또한 테이블에 존재하지 않는 열을 지정하면 에러가 발생하여 `UPDATE` 명령은 실행되지 않는다.
- 값은 상수로 표기한다. `INSERT` 명령과 마찬가지로 자료형에 맞는 값을 지정해야 한다.
- 갱신해야 할 열과 값이 복수인 경우에는 `열 = 값`을 `콤마(,)`로 구분하여 리스트 형식으로 지정할 수 있다.
- `SET` 구에 지정한 갱신내용은 처리 대상이 되는 모든 행에 적용된다.

```
UPDATE sample41 SET b = '2014-09-07' WHERE no = 2;
```
- 날짜형의 값을 갖는 열은 날짜의 리터럴로 값을 표기한다.

##### UPDATE 명령으로 행의 셀 값을 갱신할 수 있다!

- `UPDATE` 명령의 `WHERE` 조건문 역시 `DELETE` 명령과 마찬가지로 조건에 일치하는 모든 행이 그 대상이 된다.
- 그리고 `WHERE` 구를 생략하면 테이블의 모든 행이 갱신 대상이 된다.
- 즉, `WHERE` 구를 생략하거나 잘못 지정할 경우 `DELETE` 명령에서 언급한 것처럼 의도하지 않은 처리가 발생할 수 있으므로 주의해야 한다.

##### UPDATE 명령에서는 WHERE 조건에 일치하는 '모든 행'이 갱신된다!

---

## 2. UPDATE로 갱신할 경우 주의사항
- `SET` 구에서 `=`은 대입 연산자이다.
- `UPDATE` 명령은 이미 존재하는 행에 대해 값을 갱신하므로 이전의 값과 이후의 값의 두 가지 상태를 생각할 수 있다.

여기에서 다음과 같은 `UPDATE` 명령을 실행하면 어떻게 될까?
```
UPDATE sample41 SET no = no + 1;
```

- 이 명령문에는 `WHERE` 구가 지정되어 있지 않으므로 갱신 대상은 테이블의 모든 행이 된다.
- `SET` 구에서는 `no` 열의 값을 갱신하는데, 갱신 후의 값은 본래 값(갱신 전의 값)에서 1을 더한 결과이다.
- 실행을 해보면, 모든 행의 `no` 값에 1씩 더해진 것을 알 수 있다.
- 이처럼 갱신할 값을 열이 포함된 식으로도 표기할 수 있다.
- 이때 해당 열이 갱신 대상이 되는 열이라 해도 상관없다.
- 위의 예시를 간단하게 설명하면 `현재의 no 값에 1을 더한 값으로 no 열을 갱신하라`는 의미이다.
- 갱신은 행 단위로 처리되므로 `현재의 no 값`은 그 행이 갱신되기 전의 값에 해당한다.

---

## 3. 복수열 갱신
- `UPDATE` 명령의 `SET` 구에서는 필요에 따라 `콤마(,)`로 구분하여 갱신할 열을 여러 개 지정할 수 있다.

**`UPDATE 명령`**
```
UPDATE 테이블명 SET 열명1 = 값1, 열명2 = 값2, .... WHERE 조건식
```

**`두 구문으로 나누어 UPDATE 명령 실행`**
```
UPDATE sample41 SET a = 'xxx' WHERE no = 2;
UPDATE sample41 SET b = '2014-01-01' WHERE no = 2;
```

**`하나로 묶어서 UPDATE 명령 실행`**
```
UPDATE sample41 SET a = 'xxx', b = '2014-01-01' WHERE no = 2;
```

### SET 구의 실행 순서
- 여러 개의 열을 한 번에 갱신할 수 있어 편리하기는 하지만, 그 전에 `SET` 구는 어떤 순서로 갱신 처리를 하는지 알아둘 필요가 있다.
- 예를 들어, 다음과 같은 2개의 `UPDATE` 명령이 있을 때 어떤 순서로 처리되는지 알아보자.

```
UPDATE sample41 SET no = no + 1, a = no; ①
UPDATE sample41 SET a = no, no = no + 1; ②
```

- 이 두 `UPDATE` 명령은 `콤마(,)`로 구분된 갱신 식의 순서가 서로 다르다.
- 이에 대한 결과는 데이터베이스 제품에 따라서 달라진다.
- `MySQL`에서는 서로 다른 결괏값이 나오지만 `Oracle`에서는 어느 명령을 실행해도 결과는 같다.
- `MySQL`에서 첫 번째 `UPDATE` 명령을 실행하면 `no` 열과 `a` 열의 값이 서로 같아진다.
- `no` 열의 값에 1을 더하여 `no` 열에 저장한 뒤, 그 값이 다시 `a` 열에 대입되기 때문이다.
- 두 번째 `UPDATE` 명령을 실행하면 `no` 열의 값을 `a` 열에 대입한 후, `no` 열의 값을 + 1 한다. 따라서 `a` 열의 값은 `no - 1`한 값이 된다.
- `MySQL`에서 ①을 실행했을 때 `no` 열과 `a` 열의 값은 같아진다. 하지만 ②를 실행하면 `no` 열과 `a` 열의 값은 서로 달라진다. 한편 `Oracle`에서는 ①을 실행해도 ②를 실행해도 `a` 열의 값은 `no - 1` 상태를 유지한다.
- 즉, `Oracle`에서는 `SET` 구에 기술한 식의 순서가 처리에 영향을 주지 않는다.
- 갱신식의 오른쪽에 위치한 `no` 열의 값이 항상 갱신 이전의 값을 반환하기 때문이다.
- 한편 `MySQL`에서는 `SET` 구에 기술된 순서로 갱신 처리가 일어나므로 `no` 열의 값은 갱신 이전의 값이 아닌 갱신된 이후의 값을 반환한다.
- 따라서 `MySQL`의 경우, 갱신식 안에서 열을 참조할 때는 처리 순서를 고려할 필요가 있다.

---

## 4. NULL로 갱신하기
- `UPDATE` 명령으로 셀 값을 `NULL`로 갱신할 수 있다.
- `UPDATE sample41 SET b = NULL`과 같이 갱신할 값으로 `NULL`을 지정하면 된다.
- 이처럼 `NULL`로 값을 갱신하는 것을 보통 `NULL 초기화`라 부르기도 한다.

```
UPDATE sample41 SET a = NULL;
```

- 다만 `NOT NULL` 제약이 설정되어 있는 열은 `NULL`이 허용되지 않는다.
- `UPDATE` 명령에 있어서도 `NOT NULL` 제약은 유효하다. `no` 열에는 `NOT NULL` 제약이 설정되어 있으므로 `no` 열의 셀을 `NULL`로 갱신할 수 없다.
- 즉, `UPDATE sample41 SET no = NULL`을 실행하면 `NOT NULL` 제약에 위반되어 에러가 발생한다.

---