Type something to search...

08 SQL INSERT, UPDATE, DELETE 명령어 실습

1. 인트로

데이터를 넣고(INSERT(인서트)), 수정하고(UPDATE(업데이트)), 삭제하는(DELETE(딜리트)) 명령어를 익힌다. 이 세 명령어는 DML(Data Manipulation Language(데이터 매니퓰레이션 랭귀지))에 속하며, 리액트 앱의 회원가입, 정보 수정, 탈퇴 기능의 핵심이다.


2. 실습 DB 준비

1
import sqlite3
2
3
conn = sqlite3.connect("sns.db")
4
cur = conn.cursor()
5
6
cur.execute("""
7
CREATE TABLE IF NOT EXISTS posts (
8
id INTEGER PRIMARY KEY AUTOINCREMENT,
9
username TEXT NOT NULL,
10
content TEXT NOT NULL,
11
likes INTEGER DEFAULT 0,
12
created_at TEXT DEFAULT (datetime('now','localtime'))
13
)
14
""")
15
conn.commit()
16
print("posts 테이블 생성 완료")

3. SQL INSERT 명령어의 이해 및 실습

3.1. 기본 INSERT

1
# 게시글 한 개 삽입
2
cur.execute(
3
"INSERT INTO posts (username, content) VALUES (?, ?)",
4
("김철수", "오늘 점심 맛있었다 🍜")
5
)
6
conn.commit()
7
print("게시글 작성 완료, id:", cur.lastrowid)

코드 설명:

  • 3행: 값을 넣을 컬럼명을 명시한다. id, likes, created_at은 DEFAULT 값이 있어 생략 가능하다.
  • 4행: ? 플레이스홀더에 실제 값을 전달한다.
  • 6행: cur.lastrowid — 방금 삽입된 행의 id를 반환한다.

3.2. 여러 행 한 번에 삽입 — executemany

1
sample_posts = [
2
("이영희", "오늘 운동 완료! 💪"),
3
("박지민", "새 앨범 나왔다!! 🎵"),
4
("최수진", "비 오는 날 커피 ☕"),
5
("홍길동", "파이썬 공부 중 🐍"),
6
("강민준", "주말 영화 추천 받아요 🎬"),
7
]
8
9
cur.executemany(
10
"INSERT INTO posts (username, content) VALUES (?, ?)",
11
sample_posts
12
)
13
conn.commit()
14
print(f"{cur.rowcount}개 게시글 삽입 완료")

코드 설명:

  • 1~7행: 삽입할 데이터를 튜플 리스트로 준비한다.
  • 9행: executemany()는 같은 SQL을 리스트 길이만큼 반복 실행한다.
  • 13행: cur.rowcount는 영향받은 행의 수를 반환한다.

3.3. 삽입 결과 확인

1
import pandas as pd
2
df = pd.read_sql("SELECT * FROM posts", conn)
3
print(df)

4. SQL UPDATE 명령어의 이해 및 실습

4.1. 단일 행 수정

1
# id가 1인 게시글의 likes를 10으로 수정
2
cur.execute("UPDATE posts SET likes = 10 WHERE id = 1")
3
conn.commit()
4
print("좋아요 업데이트 완료")

코드 설명:

  • 2행: SET likes = 10 — likes 컬럼 값을 10으로 변경한다.
  • 2행: WHERE id = 1 — id가 1인 행만 수정한다. WHERE가 없으면 전체 행이 수정된다.

4.2. 조건에 맞는 여러 행 수정

1
# 좋아요 0인 게시글을 1로 초기화
2
cur.execute("UPDATE posts SET likes = 1 WHERE likes = 0")
3
conn.commit()
4
print(f"{cur.rowcount}개 게시글 좋아요 초기화")

4.3. 현재 값 기준으로 수정

1
# id=2 게시글 좋아요 +5 증가
2
cur.execute("UPDATE posts SET likes = likes + 5 WHERE id = 2")
3
conn.commit()
4
5
# 확인
6
cur.execute("SELECT id, username, likes FROM posts WHERE id = 2")
7
print("수정 후:", cur.fetchone())

코드 설명:

  • 2행: likes = likes + 5 — 기존 값에 5를 더한다. 리액트 앱의 좋아요 버튼 클릭 시 사용되는 패턴이다.

5. SQL DELETE 명령어의 이해 및 실습

5.1. 특정 행 삭제

1
# id가 3인 게시글 삭제
2
cur.execute("DELETE FROM posts WHERE id = 3")
3
conn.commit()
4
print(f"{cur.rowcount}개 게시글 삭제 완료")

코드 설명:

  • 2행: WHERE id = 3 — id가 3인 행만 삭제한다. 조건이 없으면 전체 삭제된다.

5.2. 조건으로 여러 행 삭제

1
# 좋아요 2 이하인 게시글 삭제
2
cur.execute("DELETE FROM posts WHERE likes <= 2")
3
conn.commit()
4
print(f"{cur.rowcount}개 비인기 게시글 삭제")

5.3. 삭제 전 확인 패턴 (권장)

1
# 삭제 전에 먼저 SELECT로 확인
2
cur.execute("SELECT id, username, content FROM posts WHERE likes <= 2")
3
targets = cur.fetchall()
4
print("삭제 예정 게시글:")
5
for t in targets:
6
print(f" id={t[0]} {t[1]}: {t[2]}")
7
8
# 확인 후 삭제
9
ans = input("삭제하시겠습니까? (y/n): ")
10
if ans.lower() == 'y':
11
cur.execute("DELETE FROM posts WHERE likes <= 2")
12
conn.commit()
13
print("삭제 완료")
14
else:
15
print("취소")

코드 설명:

  • 2~6행: 삭제 전에 SELECT로 대상을 먼저 확인한다. 실무에서 권장하는 패턴이다.
  • 9~13행: 사용자 입력을 받아 최종 확인 후 삭제한다.

6. 트랜잭션(Transaction(트랜잭션)) 이해

트랜잭션은 여러 작업을 하나의 단위로 묶는 개념이다. 모두 성공하거나, 하나라도 실패하면 전체를 되돌린다.

1
try:
2
# 게시글 작성 + 작성자 포인트 증가를 하나의 트랜잭션으로 처리
3
cur.execute("INSERT INTO posts (username, content) VALUES (?, ?)",
4
("테스트유저", "트랜잭션 테스트 게시글"))
5
6
# 의도적 오류 발생 (테스트용)
7
# cur.execute("UPDATE 없는테이블 SET x=1")
8
9
conn.commit() # 모두 성공하면 저장
10
print("게시글 작성 성공")
11
12
except Exception as e:
13
conn.rollback() # 실패하면 전체 되돌리기
14
print(f"오류 발생, 되돌림: {e}")

코드 설명:

  • 1행: try 블록 안에서 여러 SQL을 실행한다.
  • 9행: 모두 정상이면 commit()으로 저장한다.
  • 12행: 하나라도 실패하면 rollback(롤백)으로 이전 상태로 되돌린다.

7. 활용 Plus — 리액트 연동 관점

리액트 SNS 앱의 각 기능과 SQL의 매핑이다.

리액트 기능SQL 명령
게시글 작성INSERT INTO posts
좋아요 클릭UPDATE posts SET likes = likes + 1 WHERE id = ?
게시글 수정UPDATE posts SET content = ? WHERE id = ?
게시글 삭제DELETE FROM posts WHERE id = ?

8. 문제풀기

동일한 SQL 문을 여러 데이터에 반복 실행할 때 코드를 간결하게 만들고 성능을 향상시키기 위해서이다.

테이블의 모든 행이 수정된다. 반드시 WHERE로 수정 대상을 지정해야 한다.

트랜잭션 도중 오류가 발생했을 때 변경사항 전체를 취소하고 이전 상태로 되돌릴 때 사용한다.

lastrowid: 마지막으로 INSERT된 행의 id 값을 반환한다. rowcount: 마지막 SQL로 영향받은 행의 수를 반환한다.