[SQLD] 12. DML (데이터 조작어)

TJK·2025년 8월 4일
0

DML (데이터 조작어)

DML(Data Manipulation Language)은 테이블에 저장된 데이터를 조회(SELECT), 삽입(INSERT), 수정(UPDATE), 삭제(DELETE)하는 명령어의 집합임. DML 작업은 트랜잭션(Transaction) 단위로 관리되므로, COMMIT을 통해 변경 사항을 영구히 반영하거나 ROLLBACK을 통해 이전 상태로 되돌릴 수 있음.

DML (데이터 조작어)

  • SELECT
  • INSERT
  • UPDATE
  • DELETE

1. INSERT - 데이터 삽입

테이블에 새로운 행(Row)을 추가함.

1.1 INSERT INTO ... VALUES

  • 한 번에 하나의 행을 삽입하는 가장 기본적인 방법.
  • 모든 컬럼의 값을 순서대로 입력하거나, 특정 컬럼을 지정하여 값을 입력할 수 있음.
/*
 * -- 컬럼을 명시하여 데이터 삽입 (권장) --
 * 컬럼 순서가 바뀌어도 안전하며, 가독성이 높음.
 */
INSERT INTO
    Student (student_id, student_name, email)
VALUES
    (101, '김철수', 'test@example.com');

/*
 * -- 모든 컬럼 값을 순서대로 삽입 --
 * 테이블의 컬럼 순서와 정확히 일치해야 함.
 */
INSERT INTO
    Student
VALUES
    (102, '박영희', 'park@example.com');

1.2 INSERT INTO ... SELECT

  • 서브쿼리(Subquery)의 조회 결과를 통째로 다른 테이블에 삽입함.
  • 대량의 데이터를 이전하거나, 특정 조건의 데이터를 백업/가공하여 새로운 테이블을 생성할 때 유용함.
/*
 * -- Marketing_Target 테이블에 특정 강좌 수강생 명단을 삽입 --
 * Enrollments 테이블과 Student 테이블을 조인하여
 * course_id가 1인 강좌의 수강생 정보를 조회하고, 그 결과를 삽입함.
 */
INSERT INTO
    Marketing_Target (student_id, student_name)
SELECT
    s.student_id,
    s.student_name
FROM
    Student s
INNER JOIN
    Enrollment e ON s.student_id = e.student_id
WHERE
    e.course_id = 1;

1.3 INSERT ALL (Oracle 전용)

  • 하나의 SELECT 결과를 여러 조건에 따라 여러 테이블에 동시에 삽입하는 기능.
  • 데이터를 한 번만 읽어 효율적으로 분산 저장이 가능함.
-- Course 테이블의 데이터를 가격에 따라 Premium_Course와 Basic_Course 테이블에 나눠서 삽입
INSERT ALL
    WHEN price >= 30000 THEN
        INTO Premium_Course (course_id, course_name, price)
        VALUES (course_id, course_name, price)
    WHEN price <= 10000 THEN
        INTO Basic_Course (course_id, course_name, price)
        VALUES (course_id, course_name, price)
SELECT course_id, course_name, price FROM Course;

2. UPDATE - 데이터 수정

테이블의 기존 데이터를 새로운 값으로 변경함.

  • SET 절에 변경할 컬럼과 값을 지정함.
  • WHERE 절로 수정할 행을 특정하지 않으면, 테이블의 모든 행이 변경되므로 사용에 각별한 주의가 필요함.
-- student_id가 101인 학생의 이메일과 이름을 변경
UPDATE
    Student
SET
    email = 'new.email@example.com',
    student_name = '김영수'
WHERE
    student_id = 101;
  • 서브쿼리를 활용한 UPDATE: SET 절이나 WHERE 절에 서브쿼리를 사용하여 동적으로 데이터를 수정할 수 있음.
    • SET 절의 서브쿼리는 반드시 단일 행, 단일 컬럼(Scalar Subquery)을 반환해야 함.
-- 수강생이 5명 이상인 인기 강좌의 가격을 10% 인상
UPDATE
    Course
SET
    price = price * 1.1
WHERE
    course_id IN (
        SELECT course_id
        FROM Enrollment
        GROUP BY course_id
        HAVING COUNT(*) >= 5
    );

3. DELETE - 데이터 삭제

테이블에서 특정 행을 삭제함.

  • UPDATE와 마찬가지로, WHERE 절이 없으면 테이블의 모든 행이 삭제됨.
  • 한 행씩 삭제 로그(Log)를 기록하므로 대량 데이터 삭제 시 속도가 느릴 수 있음.
-- 수강신청 테이블에서 특정 학생의 특정 강좌 신청 기록을 삭제
DELETE FROM
    Enrollment
WHERE
    student_id = 101 AND course_id = 1;

4. MERGE - 데이터 병합 (UPSERT)

두 테이블을 비교하여, 조건에 따라 UPDATE 또는 INSERT 작업을 한 번에 수행하는 강력한 기능. 데이터 동기화 작업에 매우 유용함.

  • ON (비교 조건): 두 테이블을 비교할 기준(연결고리)을 지정.
  • WHEN MATCHED THEN: 비교 조건이 일치하는 행이 있을 경우 수행할 작업 (주로 UPDATE).
  • WHEN NOT MATCHED THEN: 비교 조건이 일치하는 행이 없을 경우 수행할 작업 (주로 INSERT).
/*
 * -- Daily_Update 데이터를 Student 메인 테이블에 동기화 --
 * student_id를 기준으로,
 * 이미 존재하는 학생이면 email 정보를 UPDATE 하고,
 * 존재하지 않는 신규 학생이면 INSERT 함.
 */
MERGE INTO Student s  -- 목표 테이블
USING Daily_Update d -- 소스 테이블
   ON (s.student_id = d.student_id)
 WHEN MATCHED THEN
      UPDATE SET s.email = d.email
 WHEN NOT MATCHED THEN
      INSERT (student_id, student_name, email)
      VALUES (d.student_id, d.student_name, d.email);

5. 시험 문제 유형 및 함정 포인트

  • INSERT 컬럼 명시: 컬럼을 명시한 INSERT와 생략한 INSERT의 차이점을 묻는 문제가 출제될 수 있음. 컬럼을 생략하면 테이블 정의 순서대로 모든 값을 입력해야 함.
  • UPDATEDELETEWHERE: WHERE 절을 생략했을 때 발생하는 결과(모든 행 변경/삭제)는 단골 출제 포인트임.
  • DELETE vs TRUNCATE: DML인 DELETEROLLBACK이 가능하고, DDL인 TRUNCATE는 불가능하다는 점. 그리고 TRUNCATEWHERE 절을 사용할 수 없다는 점을 명확히 구분해야 함.
  • MERGE 문의 구조: MERGE 문의 기본 구조(USING, ON, WHEN MATCHED, WHEN NOT MATCHED)를 이해하고, 각 절의 역할을 파악하는 문제가 출제될 수 있음.
  • 서브쿼리 활용: INSERT, UPDATE 문에서 서브쿼리를 활용하는 다양한 용례를 숙지해야 함. 특히 UPDATESET 절에 사용되는 스칼라 서브쿼리의 조건을 기억해야 함.
profile
Hello world!

0개의 댓글