DML 가운데 INSERT는 행을 넣고, UPDATE는 조건에 맞는 행의 값을 고치고, DELETE는 조건에 맞는 행을 지웁니다. 바뀐 결과는 SELECT로 확인합니다.
새 학기가 되면 수강 신청이 들어오고(넣기), 성적이 정정되고(고치기), 수강 철회가 생깁니다(지우기). 표의 틀은 그대로 두고 표 안의 행만 바꾸는 일입니다. 이 일을 하는 문장이 INSERT·UPDATE·DELETE입니다. SELECT 기본: 조건과 정렬에서 배운 WHERE 조건을 UPDATE와 DELETE에도 그대로 씁니다. 실기는 요구를 읽고 이 문장을 쓰게 하고, 필기는 문장의 꼴과 DELETE·TRUNCATE·DROP의 차이를 묻습니다.
그림은 12행이 든 수강 표에서 세 문장을 한 세션에서 차례로 실행합니다.
1INSERT — 행 넣기
INSERT INTO 수강 … VALUES가 106번 학생의 DS 70점 행 하나를 넣습니다. 수강 표는 13행이 됩니다.
열 목록과 VALUES의 값은 같은 차례로 짝을 짓습니다.
2UPDATE — 조건에 맞는 행의 값 고치기
UPDATE 수강 SET 점수 = 점수 + 5에 WHERE 과목코드 = 'OS'를 붙이면 OS 3행의 점수만 5점씩 오릅니다. 다른 행과 다른 열은 그대로입니다.
점수 = 점수 + 5는 그 행의 지금 점수에 5를 더한 값으로 바꿉니다.
열 여럿을 바꿀 때는 SET 학년 = 2, 학과코드 = 'CS'처럼 쉼표로 잇습니다.
WHERE를 빼면 모든 행이 바뀝니다.
3DELETE — 조건에 맞는 행 지우기
DELETE FROM 수강 WHERE 점수 < 60은 55점과 50점인 2행을 지웁니다. 11행이 남습니다.
외래키에 ON DELETE 옵션을 주지 않았다면, 다른 표가 가리키는 행은 지울 수 없습니다. 수강이 가리키는 학생 107을 학생 표에서 지우면 ORA-02292 오류가 납니다. 까닭은 무결성 제약 조건에서 봅니다.
4DELETE·TRUNCATE·DROP을 가르는 기준
시험은 '지운다'는 세 문장을 한 보기에 놓고 가르게 합니다. WHERE가 없는 DELETE FROM 수강은 모든 행을 지우고 틀(열)은 남깁니다. TRUNCATE TABLE 수강도 모든 행을 지우고 틀을 남기지만, 조건을 걸 수 없고 지운 것을 되돌릴 수 없습니다. DROP TABLE 수강은 틀까지 없애서 수강 표가 사라집니다.
| 가르는 기준 | DELETE | TRUNCATE | DROP |
|---|---|---|---|
| 지우는 것 | 조건에 맞는 행 | 모든 행 | 표 전체(틀과 행) |
| 지운 뒤 | 빈 표가 남음 | 빈 표가 남음 | 표가 없음 |
| WHERE | 쓸 수 있음 | 없음 | 없음 |
| 되돌리기 | 된다 | 안 된다 | 안 된다 |
| 종류 | DML | DDL | DDL |
지운 것을 되돌리는 문장은 ROLLBACK이고, 뒤 단원의 트랜잭션과 ACID에서 배웁니다. 여기서는 셋 가운데 DELETE만 되돌릴 수 있다는 것까지 알아 둡니다.
예제
예제는 블록마다 처음 데이터에서 시작합니다. 세 문장의 꼴은 다음과 같습니다. 대괄호는 생략할 수 있는 부분입니다.
INSERT INTO 표 [(열, …)]
VALUES (값, …);
UPDATE 표
SET 열 = 값 [, 열 = 값 …]
[WHERE 조건];
DELETE FROM 표
[WHERE 조건];
INSERT
INSERT INTO 수강
(학번, 과목코드, 점수)
VALUES (106, 'DS', 70);
SELECT *
FROM 수강
WHERE 학번 = 106;
| 학번 | 과목코드 | 점수 |
|---|---|---|
| 106 | DS | 70 |
열 목록을 빼면 VALUES에 모든 열의 값을 표의 열 차례대로 씁니다. 다음 문장도 위와 같은 행을 넣습니다.
INSERT INTO 수강
VALUES (106, 'DS', 70);
열 목록에서 뺀 열에는 NULL이 들어갑니다. 기본값(DEFAULT)이 정해진 열이면 기본값이 들어갑니다.
INSERT INTO 학생
(학번, 이름, 학년)
VALUES (108, '윤하은', 1);
SELECT *
FROM 학생
WHERE 학번 = 108;
| 학번 | 이름 | 학년 | 학과코드 |
|---|---|---|---|
| 108 | 윤하은 | 1 | NULL |
SELECT 결과를 INSERT
VALUES 대신 SELECT 문을 쓰면 조회한 행을 한꺼번에 넣습니다. 3학년만 담을 삼학년 표를 만들고 채웁니다.
CREATE TABLE 삼학년 (
학번 INT,
이름 VARCHAR(20)
);
INSERT INTO 삼학년
SELECT 학번,
이름
FROM 학생
WHERE 학년 = 3;
SELECT *
FROM 삼학년
ORDER BY 학번;
| 학번 | 이름 |
|---|---|
| 101 | 김민수 |
| 105 | 최민준 |
| 106 | 정하윤 |
UPDATE
UPDATE 수강
SET 점수 = 점수 + 5
WHERE 과목코드 = 'OS';
SELECT 학번,
점수
FROM 수강
WHERE 과목코드 = 'OS'
ORDER BY 학번;
| 학번 | 점수 |
|---|---|
| 101 | 80 |
| 102 | 65 |
| 104 | 80 |
DELETE
DELETE FROM 수강
WHERE 점수 < 60;
SELECT 학번,
과목코드,
점수
FROM 수강
WHERE 과목코드 = 'NW'
ORDER BY 학번;
| 학번 | 과목코드 | 점수 |
|---|---|---|
| 101 | NW | 80 |
| 104 | NW | 95 |
| 105 | NW | 90 |
NW 5행 가운데 55점(103)과 50점(107)이 지워졌습니다.
DELETE·TRUNCATE·DROP
WHERE 없는 DELETE는 행을 모두 지우지만 표는 남습니다. COUNT(*)는 행 수를 세는 함수로, 그룹과 집계: GROUP BY·HAVING에서 자세히 봅니다.
DELETE FROM 수강;
SELECT COUNT(*) AS 행수
FROM 수강;
| 행수 |
|---|
| 0 |
TRUNCATE도 12행을 모두 지우고 빈 표를 남깁니다. 다른 점은 지운 뒤 되돌아오지 않는다는 것입니다. 다음 블록은 지운 뒤 바로 되돌리기(ROLLBACK)를 실행했는데도 0행입니다. 같은 자리에서 DELETE였다면 12행이 돌아옵니다.
TRUNCATE TABLE 수강;
ROLLBACK;
SELECT COUNT(*) AS 행수
FROM 수강;
| 행수 |
|---|
| 0 |
TRUNCATE에는 조건을 붙일 수 없습니다. TRUNCATE TABLE 뒤의 표 이름에 WHERE를 이어 붙이면 쓸 수 없는 옵션이라는 오류(ORA-03291)가 납니다.
DROP TABLE 수강; 뒤에 수강을 조회하면 표가 없다는 오류(ORA-00942)가 납니다.
시험 포인트
- 필기: 문장의 꼴은
INSERT INTO … VALUES,UPDATE … SET … WHERE,DELETE FROM … WHERE입니다. WHERE가 없으면 UPDATE·DELETE는 모든 행에 걸립니다. DELETE는 조건을 걸 수 있고 되돌릴 수 있는 DML이라 빈 표가 남고, TRUNCATE는 조건 없이 모든 행을 지우고 되돌릴 수 없는 DDL이라 빈 표가 남으며, DROP은 틀까지 없애는 DDL입니다. - 실기: 요구를 읽고 INSERT·UPDATE·DELETE 문을 씁니다. 키워드 빈칸(INTO·VALUES·SET·FROM)을 채웁니다. 행 하나를 고칠 때는 기본키의 열을 모두 WHERE에 씁니다. 조건 없이 모든 행을 지우면서 표의 틀은 남기는 DDL의 이름은 TRUNCATE입니다.
확인 문제
1. 수강 표에 12행이 있습니다. DELETE FROM 수강;을 실행한 뒤 수강 표의 모습으로 알맞은 것을 고르세요.
- ① 12행이 그대로 있다
- ② 열은 그대로 있고 값만 모두 NULL이 된다
- ③ 행이 하나도 없는 빈 표가 남는다
- ④ 표가 없어져 조회하면 오류가 난다
정답
③입니다. DELETE는 행을 지우고 표의 틀은 그대로 둡니다. WHERE가 없으니 12행이 모두 지워지고, 열 이름과 제약 조건을 갖춘 빈 표가 남습니다.
- ① WHERE가 없으면 지울 행이 정해지지 않아 아무것도 지워지지 않는다고 봤습니다. WHERE가 없으면 모든 행에 걸립니다.
- ② 값만 비운다고 봤습니다. 값만 비우는 것은
UPDATE 수강 SET 점수 = NULL입니다. - ④ DROP과 섞어 봤습니다. 표를 틀까지 없애는 것은
DROP TABLE 수강입니다.
TRUNCATE TABLE 수강;도 ③과 같은 빈 표를 남깁니다. 다만 TRUNCATE는 DDL이라 조건을 걸 수 없고, 지운 뒤 되돌릴 수 없습니다.
2. 학과 표를 다루는 (가)~(라)의 일에 쓰는 명령어와, 그 명령어와 짝을 짓는 키워드를 함께 쓰세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
- (가) 학과 표에 새 학과 한 줄을 더합니다.
- (나) 이미 있는 학과의 건물만 다른 건물 이름으로 바꿉니다.
- (다) 경영 학과 한 줄을 지웁니다. 학과 표는 그대로 두고 씁니다.
- (라) 학과 표를 열 이름과 제약 조건까지 통째로 없앱니다.
정답
받는 답: (가) INSERT INTO … VALUES · (나) UPDATE … SET · (다) DELETE FROM · (라) DROP TABLE
(가)~(다)는 표 안의 행을 다루는 DML이고, (라)만 표의 틀을 없애는 DDL입니다. (다)와 (라)는 둘 다 '지운다'지만 남는 것이 다릅니다.
- 틀리는 꼴 (가) INSERT TO: 표 이름 앞에는 INTO를 씁니다.
- 틀리는 꼴 (다) DELETE 뒤에 열 이름을 쓴 꼴: DELETE는 행을 통째로 지워 열을 고르지 않습니다. 한 열의 값만 비우려면 UPDATE … SET 열 = NULL입니다.
- 틀리는 꼴 (라) DELETE — (라)에: 행만 지워 빈 표가 남습니다. 열 이름과 제약 조건까지 없애는 것은 DROP TABLE입니다.
3. 수강 표를 고칩니다. (1)~(3)을 차례로 풀어 보세요. 답을 끝까지 쓴 뒤 정답을 펼치세요.
(1) 다음은 학생 103의 NW 점수만 70으로 고치려는 문장입니다. ①·②에 들어갈 키워드를 쓰세요. 괄호는 빈칸 표시입니다.
UPDATE 수강
( ① ) 점수 = 70
WHERE 학번 = 103
( ② ) 과목코드 = 'NW';
(2) 학생 106이 NW 과목을 신청했습니다. 점수는 아직 적지 않습니다. 수강 표에 넣는 INSERT 문을 쓰세요.
(3) 점수를 아직 적지 않은 행만 지우는 DELETE 문을 쓰고, 지운 뒤 수강 표에 몇 행이 남는지 쓰세요.
정답
받는 답: (1) ① SET · ② AND · (2)·(3)은 아래 블록, 남는 행은 12행
(1)에서 ②를 빼면 103의 DS 점수까지 70으로 바뀝니다. 수강 표는 학번과 과목코드를 모두 적어야 행 하나가 정해집니다. (2)는 열 목록에서 점수를 빼 NULL이 들어가고, (3)이 그 행을 지워 12행으로 돌아옵니다.
UPDATE 수강
SET 점수 = 70
WHERE 학번 = 103
AND 과목코드 = 'NW';
INSERT INTO 수강
(학번, 과목코드)
VALUES (106, 'NW');
DELETE FROM 수강
WHERE 점수 IS NULL;
SELECT COUNT(*) AS 행수
FROM 수강;| 행수 |
|---|
| 12 |
- 틀리는 꼴 (2)
VALUES (106, 'NW')만 쓰고 열 목록을 뺀 꼴: 열 목록을 빼면 VALUES에 세 열의 값을 모두 적어야 합니다. 점수 자리에 NULL을 적으면 같은 행이 들어갑니다. - 틀리는 꼴 (3)
WHERE 점수 = NULL: NULL과=로 견준 결과는 참이 되지 않아 한 행도 지워지지 않고 13행이 남습니다. - 틀리는 꼴 (3) 13행: (2)에서 넣은 행만 지워진다는 것을 놓쳤습니다. 처음 12행에는 점수가 빈 행이 없습니다.
더 자세히: SQLD의 DML