fix_quota_unique_constraint.sql 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. -- ========================================
  2. -- 修复奖学金名额分配唯一约束问题
  3. -- 创建时间: 2025-01-28
  4. -- 问题描述: 唯一约束包含deleted字段导致逻辑删除时出现约束冲突
  5. -- ========================================
  6. USE hzdyjs_xg;
  7. -- 1. 查看当前的唯一约束问题数据
  8. SELECT
  9. batch_id,
  10. scholarship_type_id,
  11. target_dept_id,
  12. deleted,
  13. COUNT(*) as count_records,
  14. GROUP_CONCAT(id) as record_ids,
  15. GROUP_CONCAT(status) as statuses
  16. FROM jcbt_scholarship_quota
  17. GROUP BY batch_id, scholarship_type_id, target_dept_id, deleted
  18. HAVING COUNT(*) > 1
  19. ORDER BY batch_id, scholarship_type_id, target_dept_id;
  20. -- 2. 查看可能存在冲突的记录(同一组合下有删除和未删除的记录)
  21. SELECT
  22. q1.id as active_id,
  23. q1.batch_id,
  24. q1.scholarship_type_id,
  25. q1.target_dept_id,
  26. q1.deleted as active_deleted,
  27. q1.status as active_status,
  28. q2.id as deleted_id,
  29. q2.deleted as deleted_deleted,
  30. q2.status as deleted_status
  31. FROM jcbt_scholarship_quota q1
  32. INNER JOIN jcbt_scholarship_quota q2 ON
  33. q1.batch_id = q2.batch_id
  34. AND q1.scholarship_type_id = q2.scholarship_type_id
  35. AND q1.target_dept_id = q2.target_dept_id
  36. AND q1.deleted = 0
  37. AND q2.deleted = 1
  38. ORDER BY q1.batch_id, q1.scholarship_type_id, q1.target_dept_id;
  39. -- 3. 删除旧的唯一约束(包含deleted字段的约束)
  40. ALTER TABLE jcbt_scholarship_quota DROP INDEX uk_batch_type_dept;
  41. -- 4. 先清理可能的重复数据,然后重新添加不包含deleted字段的唯一约束
  42. -- 这样可以避免删除时的约束冲突,同时保证业务数据的唯一性
  43. -- 清理重复的已删除记录(保留最新的一条)
  44. DELETE q1 FROM jcbt_scholarship_quota q1
  45. INNER JOIN jcbt_scholarship_quota q2
  46. WHERE q1.batch_id = q2.batch_id
  47. AND q1.scholarship_type_id = q2.scholarship_type_id
  48. AND q1.target_dept_id = q2.target_dept_id
  49. AND q1.deleted = 1
  50. AND q2.deleted = 1
  51. AND q1.id < q2.id;
  52. -- 如果仍然存在同一业务组合的active和deleted记录,物理删除deleted记录
  53. DELETE FROM jcbt_scholarship_quota
  54. WHERE deleted = 1
  55. AND EXISTS (
  56. SELECT 1 FROM jcbt_scholarship_quota q2
  57. WHERE q2.batch_id = jcbt_scholarship_quota.batch_id
  58. AND q2.scholarship_type_id = jcbt_scholarship_quota.scholarship_type_id
  59. AND q2.target_dept_id = jcbt_scholarship_quota.target_dept_id
  60. AND q2.deleted = 0
  61. );
  62. -- 重新添加不包含deleted字段的唯一约束
  63. ALTER TABLE jcbt_scholarship_quota
  64. ADD CONSTRAINT uk_batch_type_dept_business
  65. UNIQUE (batch_id, scholarship_type_id, target_dept_id);
  66. -- 5. 验证修复结果
  67. SELECT
  68. '修复后检查' as check_type,
  69. batch_id,
  70. scholarship_type_id,
  71. target_dept_id,
  72. COUNT(*) as count_records,
  73. GROUP_CONCAT(CONCAT('id:', id, ',deleted:', deleted)) as record_details
  74. FROM jcbt_scholarship_quota
  75. WHERE deleted = 0
  76. GROUP BY batch_id, scholarship_type_id, target_dept_id
  77. HAVING COUNT(*) > 1
  78. UNION ALL
  79. SELECT
  80. '已删除记录检查' as check_type,
  81. batch_id,
  82. scholarship_type_id,
  83. target_dept_id,
  84. COUNT(*) as count_records,
  85. GROUP_CONCAT(CONCAT('id:', id, ',deleted:', deleted)) as record_details
  86. FROM jcbt_scholarship_quota
  87. WHERE deleted = 1
  88. GROUP BY batch_id, scholarship_type_id, target_dept_id
  89. HAVING COUNT(*) > 1;
  90. -- 6. 显示当前表的约束信息
  91. SHOW INDEX FROM jcbt_scholarship_quota WHERE Key_name LIKE '%batch%' OR Key_name LIKE '%type%' OR Key_name LIKE '%dept%';