현재 진행하고 있는 프로젝트에서 메뉴 항목들을 DB에서 관리한다.
DB만 업데이트치면 바로 반영되어 좋기는 한데,
메뉴 테이블을 공통으로 사용하기 때문에 변경사항이 큰 작업을 할 때는 부담이 크다.
이번에 기존 메뉴들을 통합하고, 분리하고 이러쿵 저러쿵...한 수정건을 맡게 되었는데,
INSERT하고 UPDATE해야하는 것들이 너무 많아서 백업테이블을 생성한 후 프로젝트가 새로 생성한 테이블을 바라보도록 하였다.
백업테이블에서 수정한건 다른 사람들에게 영향을 주지 않으므로 마음껏 작업할 수 있다!
근데 백업테이블에서 수정한 건들을 다시 원래 테이블로 옮기는 작업이 필요하다.
메뉴테이블을 건들이는 사람이 나밖에 없어, 그냥 덮어씌워도 크게 문제가 되지는 않겠지만
만약 테이블을 누군가 수정하였는데, 내 데이터로 덮어씌운다면 기존 수정건들은 사라진다...!
그래서 현재 테이블과 내가 만든 백업 테이블을 비교하여, 수정된 데이터만 추출 후 UPDATE하려고 한다.
지피티에게 테이블 DDL문을 전달한 후 쿼리를 짜달라고 했다.
챗지피티가 짜준 쿼리를 요약하면 다음과 같다
# UPDATE된 row 조회
SELECT *
FROM tb_sys_menu_m AS original
JOIN tb_sys_menu_m_yoojin AS backup
ON original.menu_id = backup.menu_id
WHERE original.컬럼1 <> backup.컬럼1
OR original.컬럼2 <> backup.컬럼2
...
# INSERT된 row 조회
SELECT *
FROM tb_sys_menu_m_yoojin AS backup
LEFT JOIN tb_sys_menu_m AS original
ON backup.menu_id = original.menu_id
WHERE original.menu_id IS NULL;
쿼리를 실행하면 INSERT, UPDATE된 row 목록이 조회된다.
아 근데 좀 아쉽다. UPDATE된 row들의 수정된 컬럼 목록을 조회하고 싶다.
그래서 아래와 같이 추가적으로 명령했다.
챗지피티가 짜준 쿼리를 요약하면 다음과 같다
SELECT
backup.menu_id,
CONCAT(
IF(original.컬럼1 <> backup.컬럼1, '컬럼1, ', ''),
IF(original.컬럼2 <> backup.컬럼2, '컬럼2, ', ''),
...
) AS modified_columns
FROM tb_sys_menu_m AS original
JOIN tb_sys_menu_m_yoojin AS backup ON original.menu_id = backup.menu_id
WHERE original.컬럼1 <> backup.컬럼1
OR original.컬럼2 <> backup.컬럼2
...
위에 쿼리를 실행하면 menu_id(PK)와 수정된 컬럼명 목록이 조회된다.
좋다. 근데 나는 업데이트문을 추출하고 싶다!
지피티에게 시켰는데, 못알아듣는거 같아 직접 쿼리를 작성하였다.
SELECT
backup.menu_id,
backup.menu_dscr,
CONCAT(
'UPDATE tb_sys_menu_m SET ',
TRIM(TRAILING ', ' FROM CONCAT(
IF(original.컬럼1 <> backup.컬럼1, CONCAT('컬럼1 = \'', backup.컬럼1, '\', '), ''),
IF(original.컬럼2 <> backup.컬럼2, CONCAT('컬럼2 = ', backup.컬럼2, ', '), ''),
...
)),
' WHERE menu_id = \'',
backup.menu_id,
'\';'
) AS update_query
FROM tb_sys_menu_m AS original
JOIN tb_sys_menu_m_yoojin AS backup ON original.menu_id = backup.menu_id
WHERE original.컬럼1 <> backup.컬럼1
OR original.컬럼2 <> backup.컬럼2
...
menu_id와 컬럼1의 데이터타입이 문자이기 때문에 앞뒤에 작은따옴표를 붙여줬다.
TRIM함수를 사용해 SET문 마지막에 붙은 콤마를 삭제해줬다.
실행시켜보자.
좋다. 아주 만족스럽다!!
update_query만 복사하여 그대로 실행하면 내가 원하는대로 동작할거다!
여기에 추가적으로 함께 UPDATE해줘야하는 컬럼이 있어서,
해당 컬럼을 UPDATE하는 부분도 추가하였다.
SELECT
backup.menu_id,
backup.menu_dscr,
CONCAT(
'UPDATE tb_sys_menu_m SET ',
CONCAT(
IF(original.컬럼1 <> backup.컬럼1, CONCAT('컬럼1 = \'', backup.컬럼1, '\', '), ''),
IF(original.컬럼2 <> backup.컬럼2, CONCAT('컬럼2 = ', backup.컬럼2, ', '), ''),
...
),
'data_upd_dttm = NOW() '
'WHERE menu_id = \'',
backup.menu_id,
'\';'
) AS update_query
FROM tb_sys_menu_m AS original
JOIN tb_sys_menu_m_yoojin AS backup ON original.menu_id = backup.menu_id
WHERE original.컬럼1 <> backup.컬럼1
OR original.컬럼2 <> backup.컬럼2
...
data_upd_dttm을 현재일시로 세팅하는 부분이 추가되었고,
맨 마지막 콤마를 제거하는 TRIM함수는 더이상 필요가 없어 삭제하였다.
완벽하다. 내가 꿈꿨던 쿼리다.
근데 단점이 한가지 있다. 테이블마다 컬럼 목록이 다르기 때문에 각자 쿼리를 생성해야한다는 것...
이런건 GPT에게 짬때리면 된다.
내가 만든 뼈대 쿼리를 보낸 후 앞으로 DDL을 보내면 변환해달라고 명령한다
바로 DDL문을 보내 테스트해보았다.
기가맥힌다. 완벽하다 !!!
[datatables.js] 주요 특징과 기능, 사용법, ajax 연동 (0) | 2025.01.13 |
---|---|
인텔리제이 단축키 모음 (0) | 2024.12.23 |
[JS, JQuery] 일자 여러개 입력받을 때 오늘 이후만, 중복 없이, 오름차순으로 입력받도록 input value range 세팅하기 (0) | 2024.12.20 |
[MyBatis] ArrayList 여러개를 하나의 반복문으로 순회하기 (1) | 2024.12.18 |
[MySQL, Draw.io] ERD 반자동화 하기 (0) | 2024.12.17 |