MSSQL LAB
MSSQL 1.8 · 1부. 기초

행을 넣고 고치고 지우기

INSERT · UPDATE · DELETE 와 OUTPUT 절입니다. WHERE 를 빠뜨리면 어떤 일이 벌어지는지 직접 봅니다.

예상 학습 시간 20분 난이도 입문
개념 설명

자료를 바꾸는 세 문장

지금까지는 읽기만 했습니다. 자료를 바꾸는 문장은 셋입니다.

문장하는 일
INSERT행을 넣습니다
UPDATE이미 있는 행의 값을 고칩니다
DELETE행을 지웁니다

셋 다 되돌리는 단추가 없습니다. 잘못 실행하면 그대로 반영됩니다. 그래서 이 단원은 실습 데이터를 건드리지 않고 dbo.NOTE 라는 연습 테이블을 따로 만들어 사용하고, 마지막에 지웁니다.

USE MssqlLab;

CREATE TABLE dbo.NOTE (
    num        INT            IDENTITY(1, 1) NOT NULL,
    title      NVARCHAR(100)                NOT NULL,
    writer     NVARCHAR(30)                 NOT NULL,
    hit_count  INT            NOT NULL DEFAULT 0,
    reg_date   DATETIME2(0)                 NOT NULL,

    CONSTRAINT PK_NOTE PRIMARY KEY (num)
);
최소 예제

행 넣기 — INSERT

열 이름을 적고 그 차례대로 값을 넣습니다. 적지 않은 열은 기본값이 들어갑니다hit_countDEFAULT 0 이라 0 이 되고, numIDENTITY 라 자동으로 매겨집니다.

SQL
INSERT INTO dbo.NOTE (title, writer, reg_date)
VALUES (N'첫 글', N'홍길동', '2026-01-01 09:00:00');

SELECT num, title, writer, hit_count FROM dbo.NOTE ORDER BY num;
결과
numtitlewriterhit_count
1첫 글홍길동0
(1개 행이 영향을 받음)

열 이름을 생략하지 마십시오. INSERT INTO dbo.NOTE VALUES (…) 처럼 적으면 테이블의 열 차례에 기대게 되어, 나중에 열이 늘거나 자리가 바뀌면 엉뚱한 값이 들어갑니다.

여러 행을 한 번에

괄호를 쉼표로 이으면 한 문장으로 여러 행이 들어갑니다.

SQL
INSERT INTO dbo.NOTE (title, writer, hit_count, reg_date) VALUES
    (N'둘째 글', N'김철수', 10, '2026-01-02 09:00:00'),
    (N'셋째 글', N'이영희', 20, '2026-01-03 09:00:00');
결과
numtitlewriterhit_count
1첫 글홍길동0
2둘째 글김철수10
3셋째 글이영희20
(2개 행이 영향을 받음)

행마다 INSERT 를 부르는 것보다 빠릅니다. 한 번의 왕복으로 끝나기 때문입니다.

조회 결과를 그대로 넣기

VALUES 자리에 SELECT 를 두면 조회한 것이 그대로 들어갑니다. 자료를 옮기거나 복사할 때 사용합니다.

SQL
INSERT INTO dbo.NOTE (title, writer, hit_count, reg_date)
SELECT TOP 3 title, N'옮겨옴', hit_count, reg_date
FROM Board.POSTS
WHERE board_num = 1
ORDER BY num;
결과
numtitlewriterhit_count
1첫 글홍길동0
2둘째 글김철수10
3셋째 글이영희20
4제약 조건 질문드립니다옮겨옴70
5인덱스 정리해 봤습니다옮겨옴140
6제약 조건 정리해 봤습니다옮겨옴210
(3개 행이 영향을 받음)

SELECT 에 적은 차례와 INSERT INTO 의 열 차례가 서로 맞아야 합니다. 이름이 아니라 자리로 맞춥니다.

최소 예제

값 고치기 — UPDATE

SET 에 고칠 열과 값을 적고, WHERE 로 어느 행인지 좁힙니다. 지금 값을 바탕으로 셈할 수도 있습니다.

OUTPUT 을 붙이면 무엇이 어떻게 바뀌었는지 돌려받습니다. 고치기 전 값은 deleted, 고친 뒤 값은 inserted 로 부릅니다.

SQL
UPDATE dbo.NOTE
   SET hit_count = hit_count + 100
OUTPUT deleted.num,
       deleted.hit_count  AS 이전,
       inserted.hit_count AS 이후
WHERE num <= 2;
결과
num이전이후
10100
210110
(2개 행이 영향을 받음)

조회수를 올리거나 상태를 바꾸는 일이 실제로 몇 건에 걸렸는지 확인할 때 유용합니다. 기록을 남겨야 하는 자리에서도 사용합니다 — 바뀐 값을 이력 테이블에 그대로 넣을 수 있습니다.

최소 예제

행 지우기 — DELETE

DELETEOUTPUT 을 받습니다. 무엇이 사라졌는지 확인할 수 있습니다.

SQL
DELETE FROM dbo.NOTE
OUTPUT deleted.num, deleted.title
WHERE hit_count < 50;
결과
numtitle
3셋째 글
(1개 행이 영향을 받음)

앞에서 1·2번의 조회수를 100 이상으로 올렸으므로 20 이었던 3번만 지워졌습니다.

상세 사용법

WHERE 를 빠뜨리면 전부 바뀝니다

이것이 이 단원에서 가장 중요한 이야기입니다. UPDATEDELETEWHERE 가 없어도 오류를 내지 않습니다. 테이블에 있는 모든 행에 적용될 뿐입니다.

SQL
-- WHERE 가 없습니다. 연습 테이블이라 벌여 보는 것입니다.
UPDATE dbo.NOTE SET writer = N'누구세요';

SELECT num, title, writer FROM dbo.NOTE ORDER BY num;
결과
numtitlewriter
1첫 글누구세요
2둘째 글누구세요
4제약 조건 질문드립니다누구세요
5인덱스 정리해 봤습니다누구세요
6제약 조건 정리해 봤습니다누구세요
(5개 행이 영향을 받음)

다섯 행의 글쓴이가 모두 바뀌었습니다. 원래 누가 작성했는지는 이제 알 수 없습니다. 운영 중인 테이블에서 이 일이 벌어지면 백업으로 되돌리는 것 말고는 방법이 없습니다.

그래서 이렇게 합니다

  • 먼저 SELECT 로 확인합니다. 고칠 조건을 그대로 넣어 조회해 보고, 나온 행이 뜻한 것과 같은지 본 뒤에 SELECT …UPDATE … 로 바꿉니다.
  • 키로 좁힙니다. 되도록 기본 키를 조건에 넣으십시오. 조건이 틀려도 번호 하나만 잘못 바뀝니다.
  • 트랜잭션으로 감쌉니다. 확인하고 되돌릴 수 있습니다. 4.6 에서 다룹니다.
-- 1) 먼저 이렇게 보고
SELECT * FROM dbo.NOTE WHERE num <= 2;

-- 2) 나온 행이 맞으면 앞부분만 바꿉니다
UPDATE dbo.NOTE SET writer = N'홍길동' WHERE num <= 2;
상세 사용법

비우는 방법 둘 — DELETE 와 TRUNCATE

테이블을 통째로 비울 때는 TRUNCATE TABLE 이 훨씬 빠릅니다. 그런데 번호를 매기는 방식이 다릅니다.

SQL
-- DELETE 로 지운 뒤 새 행을 넣으면
DELETE FROM dbo.NOTE WHERE num >= 4;
INSERT INTO dbo.NOTE (title, writer, reg_date)
VALUES (N'DELETE 뒤에 넣은 글', N'박민수', '2026-01-04 09:00:00');

SELECT num, title FROM dbo.NOTE ORDER BY num;
결과
numtitle
1첫 글
2둘째 글
3셋째 글
7DELETE 뒤에 넣은 글
(4개 행이 영향을 받음)

4 가 아니라 7 입니다. IDENTITY 는 한 번 사용한 번호를 되돌려 주지 않습니다. 지워진 자리를 다시 채우지 않으므로 번호에 구멍이 생기는 것은 정상입니다.

SQL
-- TRUNCATE 로 비운 뒤 넣으면
TRUNCATE TABLE dbo.NOTE;
INSERT INTO dbo.NOTE (title, writer, reg_date)
VALUES (N'TRUNCATE 뒤에 넣은 글', N'최지우', '2026-01-05 09:00:00');

SELECT num, title FROM dbo.NOTE ORDER BY num;
결과
numtitle
1TRUNCATE 뒤에 넣은 글
(1개 행이 영향을 받음)

번호가 1 로 돌아갔습니다. 둘의 차이를 정리하면 이렇습니다.

항목DELETETRUNCATE
조건WHERE 로 고를 수 있습니다없습니다. 전부 비웁니다
IDENTITY이어서 매깁니다1 부터 다시
속도행마다 기록을 남깁니다훨씬 빠릅니다
OUTPUT받을 수 있습니다받을 수 없습니다
외래 키가리키는 행이 없으면 지워집니다가리키는 테이블이 있으면 막힙니다

연습이 끝났으니 지웁니다 — DROP TABLE dbo.NOTE;

실습 문제

직접 해보기

1. 넣고 고치고 지우기 난이도 하

연습 테이블을 하나 만들어 두 행을 넣고, 그중 하나의 값을 고친 뒤, 다른 하나를 지워 보세요. 고칠 때와 지울 때 OUTPUT 으로 무엇이 바뀌었는지 확인하십시오.

CREATE TABLE dbo.TODO ( num INT IDENTITY(1, 1) NOT NULL, task NVARCHAR(100) NOT NULL, done BIT NOT NULL DEFAULT 0, CONSTRAINT PK_TODO PRIMARY KEY (num) ); INSERT INTO dbo.TODO (task) VALUES (N'장보기'), (N'청소하기'); UPDATE dbo.TODO SET done = 1 OUTPUT deleted.task, deleted.done AS 이전, inserted.done AS 이후 WHERE num = 1; DELETE FROM dbo.TODO OUTPUT deleted.num, deleted.task WHERE num = 2; DROP TABLE dbo.TODO;
2. 고치기 전에 확인하기 난이도 중

"질문답변 게시판에서 조회수가 400 이상인 글의 조회수를 0 으로 되돌린다" 를 실행하기 전에, 몇 건이 걸리는지 먼저 확인하는 문장을 적어 보세요. 실행은 하지 마십시오.

-- 1) 먼저 세어 봅니다 SELECT COUNT(*) FROM Board.POSTS WHERE board_num = 3 AND hit_count >= 400; -- 2) 어떤 글인지도 봅니다 SELECT num, title, hit_count FROM Board.POSTS WHERE board_num = 3 AND hit_count >= 400 ORDER BY num; -- 3) 확인한 뒤에야 앞부분을 바꿉니다 -- UPDATE Board.POSTS SET hit_count = 0 -- WHERE board_num = 3 AND hit_count >= 400; -- WHERE 를 그대로 두고 SELECT 를 UPDATE 로 바꾸는 것이 핵심입니다. -- 조건을 새로 적으면 그 사이에 실수가 끼어듭니다.
요약
  • INSERT열 이름을 반드시 적습니다. 자리에 기대면 열이 바뀔 때 어긋납니다.
  • VALUES 자리에 SELECT 를 두면 조회 결과가 그대로 들어갑니다.
  • OUTPUT 으로 바뀌기 전(deleted)과 뒤(inserted) 를 돌려받습니다.
  • WHERE 가 없으면 테이블 전체에 적용됩니다. 오류가 나지 않습니다.
  • 고치기 전에 같은 조건으로 SELECT 해 보십시오. 조건은 그대로 두고 앞부분만 바꿉니다.
  • TRUNCATE 는 빠르지만 조건을 줄 수 없고 IDENTITY 가 1 로 돌아갑니다.