Contents
see List작성일 2015. 05. 02.
Oracle 계층구조(답글, 댓글) 전부 삭제하기
게시판에서 원글을 삭제할 때 하위 답글, 댓글까지 모두 삭제하는 Oracle 쿼리입니다.
언제 사용하나요?
- 게시글 삭제 시 모든 답글/대댓글 함께 삭제
- 카테고리 삭제 시 하위 카테고리 함께 삭제
- 조직도에서 부서 삭제 시 하위 부서 포함 삭제
- 트리 구조 데이터의 일괄 삭제
테이블 구조 예시
CREATE TABLE board (
board_seq NUMBER PRIMARY KEY,
parent_seq NUMBER, -- 부모글 번호 (NULL이면 원글)
title VARCHAR2(200),
content CLOB,
use_yn CHAR(1) DEFAULT \047Y\047
);
-- 답글 구조
-- board_seq=1 (원글)
-- └ board_seq=2 (답글, parent_seq=1)
-- └ board_seq=3 (대댓글, parent_seq=2)
-- └ board_seq=4 (답글, parent_seq=1)계층 구조 조회 (CONNECT BY)
-- 특정 글과 모든 하위 글 조회
SELECT board_seq, parent_seq, title, LEVEL
FROM board
START WITH board_seq = 1 -- 시작점 (원글)
CONNECT BY PRIOR board_seq = parent_seq -- 부모-자식 연결
ORDER SIBLINGS BY board_seq;계층 구조 삭제 (서브쿼리 사용)
-- 방법 1: 서브쿼리로 삭제
DELETE FROM board
WHERE board_seq IN (
SELECT board_seq
FROM board
START WITH board_seq = :delete_seq
CONNECT BY PRIOR board_seq = parent_seq
);논리적 삭제 (USE_YN 업데이트)
-- 실제 삭제 대신 USE_YN = \047N\047으로 변경
UPDATE board
SET use_yn = \047N\047
WHERE board_seq IN (
SELECT board_seq
FROM board
START WITH board_seq = :delete_seq
CONNECT BY PRIOR board_seq = parent_seq
);MyBatis 적용
<!-- BoardMapper.xml -->
<delete id="deleteWithReplies" parameterType="long">
DELETE FROM board
WHERE board_seq IN (
SELECT board_seq
FROM board
START WITH board_seq = #{boardSeq}
CONNECT BY PRIOR board_seq = parent_seq
)
</delete>
<update id="softDeleteWithReplies" parameterType="long">
UPDATE board
SET use_yn = \047N\047,
upd_date = SYSDATE
WHERE board_seq IN (
SELECT board_seq
FROM board
START WITH board_seq = #{boardSeq}
CONNECT BY PRIOR board_seq = parent_seq
)
</update>CTE(Common Table Expression) 방식
-- Oracle 11g R2 이상
WITH RECURSIVE tree AS (
SELECT board_seq
FROM board
WHERE board_seq = :delete_seq
UNION ALL
SELECT b.board_seq
FROM board b
INNER JOIN tree t ON b.parent_seq = t.board_seq
)
DELETE FROM board
WHERE board_seq IN (SELECT board_seq FROM tree);외래키 CASCADE 설정
-- 테이블 생성 시 CASCADE 설정
CREATE TABLE board (
board_seq NUMBER PRIMARY KEY,
parent_seq NUMBER REFERENCES board(board_seq) ON DELETE CASCADE,
title VARCHAR2(200)
);
-- 이렇게 하면 부모 삭제 시 자식 자동 삭제
DELETE FROM board WHERE board_seq = 1; -- 하위 글도 자동 삭제삭제 전 하위 글 개수 확인
SELECT COUNT(*) as total_count
FROM board
START WITH board_seq = :board_seq
CONNECT BY PRIOR board_seq = parent_seq;주의사항
- 삭제 전 트랜잭션 시작 필수
- 대용량 삭제 시 배치 처리 고려
- 실제 DELETE 전 SELECT로 영향 받는 데이터 확인
- 첨부파일 등 연관 데이터도 함께 처리 필요
연관 테이블 함께 삭제
-- 첨부파일, 댓글 등도 함께 삭제
DELETE FROM board_file
WHERE board_seq IN (
SELECT board_seq
FROM board
START WITH board_seq = :delete_seq
CONNECT BY PRIOR board_seq = parent_seq
);
DELETE FROM board_comment
WHERE board_seq IN (
SELECT board_seq
FROM board
START WITH board_seq = :delete_seq
CONNECT BY PRIOR board_seq = parent_seq
);
DELETE FROM board
WHERE board_seq IN (
SELECT board_seq
FROM board
START WITH board_seq = :delete_seq
CONNECT BY PRIOR board_seq = parent_seq
);database
| No | 작성일 | Title |
|---|---|---|
| 3380 | 2026. 08. 20. | PostgreSQL 느린 조회를 진단하는 방법: EXPLAIN ANALYZE와 복합 인덱스 실전 가이드 |
| 3348 | 2026. 08. 11. | PostgreSQL 잠금 대기 줄이기: 트랜잭션 범위와 lock_timeout 설정 실전 가이드 |
| 3316 | 2026. 08. 03. | PostgreSQL 백업 복구 실전 가이드: pg_dump·pg_restore로 장애 복구 절차 만들기 |
| 3284 | 2026. 07. 26. | PostgreSQL 인덱스가 있는데도 느린 쿼리 해결하기: EXPLAIN ANALYZE와 복합 인덱스 설계 |
| 3254 | 2026. 07. 18. | PostgreSQL 잠금 대기 진단 가이드: pg_stat_activity로 블로킹 쿼리 찾고 장애 줄이기 |
| 3202 | 2026. 07. 09. | PostgreSQL 백업 복구 검증 가이드: pg_dump와 psql로 실제 복원까지 확인하기 |
| 3170 | 2026. 07. 01. | MySQL 느린 쿼리 원인 찾기: EXPLAIN과 복합 인덱스 점검 가이드 |
| 3116 | 2026. 06. 23. | PostgreSQL 트랜잭션 충돌 줄이기: 잠금 순서와 짧은 재시도로 데드락 대응하기 |
| 3058 | 2026. 06. 15. | PostgreSQL JSONB 조회 튜닝: GIN 인덱스와 생성 컬럼으로 느린 검색 줄이기 |
| 2971 | 2026. 06. 07. | MySQL/MariaDB 복합 인덱스 설계: 느린 목록 조회를 줄이는 WHERE·ORDER BY 점검법 |