Files
DBAdmin/scripts/MySQL/Procedure_archive_data.sql
2026-05-18 06:40:19 +00:00

115 lines
3.0 KiB
SQL

DELIMITER $$
CREATE PROCEDURE archive_last_days_dynamic(
IN p_source_table VARCHAR(64),
IN p_archive_table VARCHAR(64),
IN p_date_column VARCHAR(64),
IN p_days_back INT,
IN p_batch_size INT
)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE rows_affected INT DEFAULT 0;
DECLARE total_rows INT DEFAULT 0;
DECLARE insert_sql VARCHAR(4000);
DECLARE delete_sql VARCHAR(4000);
-- Validation
IF p_source_table IS NULL OR p_source_table = '' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Source table name is required';
END IF;
IF p_archive_table IS NULL OR p_archive_table = '' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Archive table name is required';
END IF;
IF p_date_column IS NULL OR p_date_column = '' THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Date column name is required';
END IF;
IF p_days_back IS NULL OR p_days_back <= 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Days back must be greater than 0';
END IF;
-- If batch size is NULL or <= 0, run once without LIMIT
IF p_batch_size IS NULL OR p_batch_size <= 0 THEN
SET insert_sql = CONCAT(
'INSERT INTO `', p_archive_table, '` ',
'SELECT * FROM `', p_source_table, '` ',
'WHERE `', p_date_column, '` <= NOW() - INTERVAL ', p_days_back, ' DAY'
);
SET delete_sql = CONCAT(
'DELETE FROM `', p_source_table, '` ',
'WHERE `', p_date_column, '` <= NOW() - INTERVAL ', p_days_back, ' DAY'
);
START TRANSACTION;
SET @insert_sql = insert_sql;
PREPARE stmt_insert FROM @insert_sql;
EXECUTE stmt_insert;
SET rows_affected = ROW_COUNT();
SET total_rows = rows_affected;
DEALLOCATE PREPARE stmt_insert;
SET @delete_sql = delete_sql;
PREPARE stmt_delete FROM @delete_sql;
EXECUTE stmt_delete;
DEALLOCATE PREPARE stmt_delete;
COMMIT;
ELSE
REPEAT
SET insert_sql = CONCAT(
'INSERT INTO `', p_archive_table, '` ',
'SELECT * FROM `', p_source_table, '` ',
'WHERE `', p_date_column, '` <= NOW() - INTERVAL ', p_days_back, ' DAY ',
'LIMIT ', p_batch_size
);
SET delete_sql = CONCAT(
'DELETE FROM `', p_source_table, '` ',
'WHERE `', p_date_column, '` <= NOW() - INTERVAL ', p_days_back, ' DAY ',
'LIMIT ', p_batch_size
);
START TRANSACTION;
SET @insert_sql = insert_sql;
PREPARE stmt_insert FROM @insert_sql;
EXECUTE stmt_insert;
SET rows_affected = ROW_COUNT();
SET total_rows = total_rows + rows_affected;
DEALLOCATE PREPARE stmt_insert;
IF rows_affected > 0 THEN
SET @delete_sql = delete_sql;
PREPARE stmt_delete FROM @delete_sql;
EXECUTE stmt_delete;
DEALLOCATE PREPARE stmt_delete;
END IF;
COMMIT;
IF rows_affected < p_batch_size THEN
SET done = TRUE;
END IF;
UNTIL done END REPEAT;
END IF;
SELECT 'ok' AS status, total_rows AS total_rows_moved;
END $$
DELIMITER ;
//USE
CALL archive_last_days_dynamic('source_table', 'archive_table', 'created_at', 30, 500);