2과목 · SQL 기본 및 활용·3장
DML (INSERT / UPDATE / DELETE / MERGE)
INSERT 다양 형식, UPDATE 조건, DELETE, MERGE(UPSERT)까지 데이터 조작 SQL을 총정리합니다.
1. INSERT
단건 삽입
INSERT INTO emp (emp_id, name, dept_id) VALUES (1, '김개발', 10);
복수 행 삽입
INSERT INTO emp (emp_id, name, dept_id) VALUES
(1, '김개발', 10),
(2, '이기획', 20),
(3, '박마케', 30);
SELECT 결과 삽입 (INSERT INTO ... SELECT)
INSERT INTO emp_archive (emp_id, name, hired_at)
SELECT emp_id, name, hired_at FROM emp WHERE hired_at < DATE '2020-01-01';
생략 규칙
- 컬럼 리스트를 생략하면 테이블 선언 순서대로 값이 매핑된다.
- 리스트에 빠진 컬럼은 DEFAULT 또는 NULL로 들어감.
- 생성 순서나 PK 순서 바꾸기를 가정하지 말고 항상 컬럼 리스트를 명시하는 습관이 안전.
2. UPDATE
조건부 갱신
UPDATE emp
SET salary = salary + 100000,
updated_at = CURRENT_TIMESTAMP
WHERE dept_id = 10;
상관 서브쿼리로 UPDATE
UPDATE emp e
SET salary = (SELECT AVG(salary) FROM emp WHERE dept_id = e.dept_id)
WHERE e.performance = 'S';
JOIN 스타일 UPDATE (PG/MySQL)
-- PostgreSQL
UPDATE emp e
SET salary = e.salary + b.bonus
FROM bonus b
WHERE e.emp_id = b.emp_id;
WHERE가 없으면 테이블 전체가 갱신됩니다. 실무 사고의 고전 원인.
3. DELETE
DELETE FROM emp WHERE hired_at < DATE '2000-01-01';
-- 서브쿼리 조건
DELETE FROM emp
WHERE emp_id IN (SELECT emp_id FROM blacklist);
DELETE FROM emp;— 전체 삭제 (롤백 가능, 트리거 발화).- 대량 삭제가 필요하면
TRUNCATE가 빠름 (단, DDL이라 롤백 불가).
4. MERGE (UPSERT)
존재하면 UPDATE, 없으면 INSERT — 한 문장으로 처리.
ANSI / Oracle
MERGE INTO emp_target t
USING emp_source s ON (t.emp_id = s.emp_id)
WHEN MATCHED THEN
UPDATE SET t.salary = s.salary, t.updated_at = CURRENT_TIMESTAMP
WHEN NOT MATCHED THEN
INSERT (emp_id, name, salary)
VALUES (s.emp_id, s.name, s.salary);
PostgreSQL — ON CONFLICT
INSERT INTO emp (emp_id, name, salary) VALUES (1, '김개발', 3800000)
ON CONFLICT (emp_id)
DO UPDATE SET name = EXCLUDED.name, salary = EXCLUDED.salary;
MySQL — ON DUPLICATE KEY UPDATE
INSERT INTO emp (emp_id, name, salary) VALUES (1, '김개발', 3800000)
ON DUPLICATE KEY UPDATE name = VALUES(name), salary = VALUES(salary);
5. 트랜잭션과 DML
DML은 자동 커밋이 아닙니다 (Oracle 기준). 반드시 COMMIT 또는 ROLLBACK을 호출해야 변경이 확정·취소됩니다.
BEGIN;
UPDATE account SET balance = balance - 10000 WHERE id = 'A';
UPDATE account SET balance = balance + 10000 WHERE id = 'B';
COMMIT;
6. DML과 NULL
-- 위험: NULL 비교 실수
UPDATE emp SET salary = salary + 1 WHERE bonus != 0;
-- bonus가 NULL인 사원은 갱신되지 않음 (UNKNOWN 취급)
-- 명시적 처리
UPDATE emp SET salary = salary + 1 WHERE COALESCE(bonus, 0) != 0;
7. 자주 출제되는 포인트
INSERT INTO ... SELECT로 대량 적재 가능.UPDATE에 WHERE 누락 → 전체 행 갱신 (시험·실무 모두 위험).MERGE는 UPSERT 패턴. Oracle은 MERGE, PG는 ON CONFLICT, MySQL은 ON DUPLICATE KEY.DELETE는 DML(롤백 O),TRUNCATE는 DDL(롤백 X).
8. 요약 체크리스트
- INSERT의 3가지 형태(단건/복수/SELECT)를 쓸 수 있다.
- 상관 서브쿼리 UPDATE를 작성할 수 있다.
- MERGE 구문의 WHEN MATCHED / NOT MATCHED를 이해한다.
- DML과 DDL의 트랜잭션 동작 차이를 설명할 수 있다.