ether-pms/sql/cleanup-orphan-data.sql

135 lines
4.4 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- =============================================
-- 清理孤立数据(在添加外键前必须执行)
-- 版本: cleanup-script
-- 日期: 2026-04-07
-- 说明: 删除所有违反引用完整性的孤立数据
-- =============================================
BEGIN;
-- ============================================================
-- 第一部分:清理项目员工表的孤立数据
-- ============================================================
-- 1.1 删除引用不存在项目的员工记录
DELETE FROM project_staff
WHERE project_id IS NOT NULL
AND project_id NOT IN (SELECT id FROM mdm_project);
-- 1.2 删除引用不存在用户的员工记录(理论上不应该存在,因为已有外键)
DELETE FROM project_staff
WHERE user_id NOT IN (SELECT id FROM auth_user);
-- 1.3 删除引用不存在班组长ID的记录leader_id允许为NULL
UPDATE project_staff
SET leader_id = NULL
WHERE leader_id IS NOT NULL
AND leader_id NOT IN (SELECT id FROM auth_user);
-- ============================================================
-- 第二部分:清理房屋表的孤立数据
-- ============================================================
-- 2.1 删除引用不存在项目的房屋记录
DELETE FROM space
WHERE project_id NOT IN (SELECT id FROM mdm_project);
-- ============================================================
-- 第三部分:清理用户表的可能孤立数据
-- ============================================================
-- 3.1 清理用户表中引用不存在部门的记录dept_id允许为NULL
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'auth_user'
AND column_name = 'dept_id'
) THEN
UPDATE auth_user
SET dept_id = NULL
WHERE dept_id IS NOT NULL
AND dept_id NOT IN (SELECT id FROM dept);
END IF;
END $$;
-- ============================================================
-- 第四部分:清理角色表的可能孤立数据
-- ============================================================
-- 4.1 清理角色表中引用不存在项目的记录project_id允许为NULL
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'auth_role'
AND column_name = 'project_id'
) THEN
UPDATE auth_role
SET project_id = NULL
WHERE project_id IS NOT NULL
AND project_id NOT IN (SELECT id FROM mdm_project);
END IF;
END $$;
-- ============================================================
-- 第五部分:清理用户角色关联表的可能孤立数据
-- ============================================================
-- 5.1 清理用户角色表中引用不存在项目的记录project_id允许为NULL
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'auth_user_role'
AND column_name = 'project_id'
) THEN
UPDATE auth_user_role
SET project_id = NULL
WHERE project_id IS NOT NULL
AND project_id NOT IN (SELECT id FROM mdm_project);
END IF;
END $$;
-- ============================================================
-- 第六部分:统计清理结果(用于验证)
-- ============================================================
-- 创建临时表记录清理结果(可选)
DROP TABLE IF EXISTS cleanup_statistics;
CREATE TEMPORARY TABLE cleanup_statistics (
table_name VARCHAR(50),
check_type VARCHAR(100),
orphan_count INT,
cleaned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 插入统计信息
INSERT INTO cleanup_statistics (table_name, check_type, orphan_count)
SELECT 'project_staff', 'invalid_project_id', COUNT(*)
FROM project_staff
WHERE project_id IS NOT NULL
AND project_id NOT IN (SELECT id FROM mdm_project);
INSERT INTO cleanup_statistics (table_name, check_type, orphan_count)
SELECT 'space', 'invalid_project_id', COUNT(*)
FROM space
WHERE project_id NOT IN (SELECT id FROM mdm_project);
-- 输出清理结果
SELECT * FROM cleanup_statistics ORDER BY table_name, check_type;
COMMIT;
-- =============================================
-- 使用说明:
--
-- 1. 在生产环境执行前,请先备份数据库
-- 2. 建议在维护窗口期执行
-- 3. 执行完成后检查cleanup_statistics确认无孤立数据
-- 4. 确认无误后,再执行 V999__add_foreign_keys.sql
--
-- 回滚方案:如果有误删,从备份恢复
-- =============================================