135 lines
4.4 KiB
PL/PgSQL
135 lines
4.4 KiB
PL/PgSQL
-- =============================================
|
||
-- 清理孤立数据(在添加外键前必须执行)
|
||
-- 版本: 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
|
||
--
|
||
-- 回滚方案:如果有误删,从备份恢复
|
||
-- =============================================
|