ID | CODE_NUM | ITEM_NAME |
215 | 과자 | |
216 | 음료수 | |
217 | 견과류 | |
218 | 217 | 아몬드 |
219 | 217 | 땅콩 |
220 | 217 | 호두 |
221 | 219 | 오징어땅콩 |
222 | 219 | 계피맛땅콩 |
223 | 221 | 작은봉지 |
224 | 221 | 큰봉지 |
테이블 삭제 관련 하여 질문 드립니다. 하루종일 해매다 글 남겨 놓네요 ㅠ0ㅠ;
테이블 구조는 위와같습니다.
테이블 이름: ITEM_LIST
견과류
- 땅콩
- 계피맛땅콩
- 오징어땅콩
- 작은봉지
- 큰봉지
- 아몬드
- 호두
이와 같은 형태 인데
견과류를 삭제하면 자동으로 아래 하위 목록까지 테이블에서 다 삭제 하고 싶습니다.
원하는 결과값
ID | CODE_NUM | ITEM_NAME |
215 | 과자 | |
216 | 음료수 |
이부분 명령어를 어떻게 해야 될까요?ㅠ0ㅠ 고수님들의 답변 부탁드립니다.
견과류 ID를 가지고 있는 아이템을 찾아내고 삭제하고 삭제된 셀에 ID를 가지고 있는 셀을 검색해서 또 삭제하고
다시 삭제된 셀에 ID를 갖고 있는 셀을 찾아내서 삭제하고... 이런식으로 반복해서 삭제하면 될것 같긴한데 잘 모르겠습니다.
위 테이블명를 토대로 예를 들어 쿼리문을 알려주시면 정말 감사하겠습니다.
--CONNECT_BY_ROOT를 이용하면 됩니다. WITH T(id, code_num, item_name) AS ( SELECT 215, NULL, '과자' FROM DUAL UNION ALL SELECT 216, NULL, '음료수' FROM DUAL UNION ALL SELECT 217, NULL, '견과류' FROM DUAL UNION ALL SELECT 218, 217, '아몬드' FROM DUAL UNION ALL SELECT 219, 217, '땅콩' FROM DUAL UNION ALL SELECT 220, 217, '호두' FROM DUAL UNION ALL SELECT 221, 219, '오징어땅콩' FROM DUAL UNION ALL SELECT 222, 219, '계피맛땅콩' FROM DUAL UNION ALL SELECT 223, 221, '작은봉지' FROM DUAL UNION ALL SELECT 224, 221, '큰봉지' FROM DUAL UNION ALL SELECT 227, 224, '밀폐형' FROM DUAL ) SELECT id, code_num, LPAD(' ', LEVEL, ' ')||item_name, CONNECT_BY_ROOT id AS rid FROM T START WITH code_num IS NULL CONNECT BY PRIOR id = code_num
--위 결과를 이용하여 견과류 키 값 217 하위 다 삭제 처리 DELETE FROM [TABLE_NAME] WHERE id IN( SELECT id FROM ( SELECT id, code_num, LPAD(' ', LEVEL, ' ')||item_name, CONNECT_BY_ROOT id AS rid FROM T START WITH code_num IS NULL CONNECT BY PRIOR id = code_num ) WHERE rid = 217 )
DELETE FROM ITEM_LIST WHERE ID IN( SELECT ID FROM ( SELECT ID, CODE_NUM, LPAD(' ', LEVEL, ' ')||ITEM_NAME, CONNECT_BY_ROOT ID AS rid FROM T START WITH CODE_NUM IS NULL CONNECT BY PRIOR ID= CODE_NUM ) WHERE rid = 217 ) 답변 정말 감사합니다. 지금 활용해 볼려고.. 이렇게 217에 관한 애들을 삭제하라고 명령을 주었는데 쿼리문 오류가 납니다. ㅠ0ㅠ 어떤것이 잘못된 것일까요?
ㅠ_ㅠ;; MySQL 오랫만에 했더니, 정신 없네요.
일단 1depth 처리하는 프로시저랑 사용 예 드립니다.
필요하시다면, 1depth 이상도 삭제 되는 프로시저로 수정해서 드리겠습니다.
일단 프로시저는 아래 스크립트 복사해서 생성하시면 됩니다.
CREATE PROCEDURE PRC_DELETE_CHILD( super_parent_id INT, table_name VARCHAR(100), id_field_name VARCHAR(20), parent_id_field_name VARCHAR(20) ) BEGIN SET @cnt = 0; SET @query = CONCAT("SELECT COUNT(*) INTO @cnt FROM ", table_name, " WHERE ", parent_id_field_name, " = ", super_parent_id); SELECT CONCAT('EXECUTE SQL : ', @query); PREPARE stmt FROM @query; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT @cnt; IF @cnt != '0' THEN SET @query = CONCAT("DELETE FROM ", table_name, " WHERE ", parent_id_field_name, " = ", super_parent_id); PREPARE stmt FROM @query; EXECUTE stmt; DEALLOCATE PREPARE stmt; SET @query = CONCAT("DELETE FROM ", table_name, " WHERE ", id_field_name, " = ", super_parent_id); PREPARE stmt FROM @query; EXECUTE stmt; DEALLOCATE PREPARE stmt; END IF; END;
MySQL 프로시져를 안해봐서...직접 작성은 못하겠고...
자기 자신의 프로시져를 다시 호출하는 게 가능하다면? (오라클은 가능함)
재귀 호출방식의 삭제 프로시져를 만드시면 간단할 듯 하네요.
아래는 오라클 재귀 호출 프로시져 예시입니다.
CREATE OR REPLACE PROCEDURE p_delete(v_id NUMBER) IS BEGIN DELETE FROM t WHERE id = v_id; FOR c IN (SELECT id FROM t WHERE code_num = v_id) LOOP p_delete(c.id); END LOOP; END; /