2026-09-02-verify-jw-export-views.sql 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. -- =============================================================================
  2. -- 教务同步视图生产验证脚本
  3. -- 用途:部署 vw_jw_student_export / vw_jw_student_change_export 后执行
  4. --
  5. -- 用法:
  6. -- mysql -h <host> -u root -p hzdyjs_xg < docs/数据库脚本/2026-09-02-verify-jw-export-views.sql
  7. --
  8. -- 说明:
  9. -- * 脚本仅 SELECT,不修改数据
  10. -- * 若某段报错,说明对应视图或依赖表/字段异常
  11. -- * 「培养层次疑似中文」> 0 表示仍返回中文名称,需核对视图是否已更新
  12. -- =============================================================================
  13. SET NAMES utf8mb4;
  14. SELECT '========== 1. 视图是否存在 ==========' AS section;
  15. SELECT
  16. TABLE_NAME AS view_name,
  17. TABLE_TYPE AS object_type
  18. FROM information_schema.TABLES
  19. WHERE TABLE_SCHEMA = DATABASE()
  20. AND TABLE_NAME IN ('vw_jw_student_export', 'vw_jw_student_change_export')
  21. ORDER BY TABLE_NAME;
  22. SELECT '========== 2. 依赖:班级校区字段是否存在 ==========' AS section;
  23. SELECT
  24. COLUMN_NAME,
  25. COLUMN_TYPE,
  26. COLUMN_COMMENT
  27. FROM information_schema.COLUMNS
  28. WHERE TABLE_SCHEMA = DATABASE()
  29. AND TABLE_NAME = 'xg_class_msg'
  30. AND COLUMN_NAME IN ('campus_id', 'campus_name')
  31. ORDER BY ORDINAL_POSITION;
  32. SELECT '========== 3. 基础数据量对比 ==========' AS section;
  33. SELECT 'xg_student_msg(未删除)' AS metric, COUNT(*) AS cnt
  34. FROM xg_student_msg WHERE deleted = 0
  35. UNION ALL
  36. SELECT 'vw_jw_student_export', COUNT(*) FROM vw_jw_student_export
  37. UNION ALL
  38. SELECT 'vw_jw_student_change_export(全部)', COUNT(*) FROM vw_jw_student_change_export
  39. UNION ALL
  40. SELECT CONCAT('vw_jw_student_change_export(', YEAR(CURDATE()), '年)'),
  41. COUNT(*)
  42. FROM vw_jw_student_change_export
  43. WHERE YEAR(`异动生效时间`) = YEAR(CURDATE());
  44. SELECT '========== 4. vw_jw_student_export 关键字段填充率 ==========' AS section;
  45. SELECT
  46. COUNT(*) AS total,
  47. SUM(`学号` IS NOT NULL AND TRIM(`学号`) <> '') AS has_student_no,
  48. SUM(`班级信息` IS NOT NULL AND TRIM(`班级信息`) <> '') AS has_class,
  49. SUM(`所在校区` IS NOT NULL AND TRIM(`所在校区`) <> '') AS has_campus,
  50. SUM(`系部信息` IS NOT NULL AND TRIM(`系部信息`) <> '') AS has_college,
  51. SUM(`专业信息` IS NOT NULL AND TRIM(`专业信息`) <> '') AS has_major,
  52. SUM(`培养层次` IS NOT NULL AND TRIM(`培养层次`) <> '') AS has_pycc,
  53. SUM(`培养层次` REGEXP '^[0-5]$') AS pycc_dict_value_ok,
  54. SUM(
  55. `培养层次` IS NOT NULL
  56. AND TRIM(`培养层次`) <> ''
  57. AND `培养层次` NOT REGEXP '^[0-5]$'
  58. ) AS pycc_maybe_chinese_name
  59. FROM vw_jw_student_export;
  60. SELECT '========== 5. vw_jw_student_export 培养层次分布(应为 0~5 字典值)==========' AS section;
  61. SELECT
  62. COALESCE(`培养层次`, '(null)') AS pycc_value,
  63. COUNT(*) AS cnt
  64. FROM vw_jw_student_export
  65. GROUP BY `培养层次`
  66. ORDER BY cnt DESC
  67. LIMIT 20;
  68. SELECT '========== 6. vw_jw_student_export 所在校区分布(Top 10)==========' AS section;
  69. SELECT
  70. COALESCE(`所在校区`, '(null)') AS campus,
  71. COUNT(*) AS cnt
  72. FROM vw_jw_student_export
  73. GROUP BY `所在校区`
  74. ORDER BY cnt DESC
  75. LIMIT 10;
  76. SELECT '========== 7. vw_jw_student_export 样例(3 条,含组织信息)==========' AS section;
  77. SELECT
  78. `学号`, `姓名`, `班级信息`, `所在校区`, `系部信息`, `专业信息`, `培养层次`, `学制`, `学生当前状态`
  79. FROM vw_jw_student_export
  80. ORDER BY `学号`
  81. LIMIT 3;
  82. SELECT '========== 8. vw_jw_student_change_export 关键字段填充率 ==========' AS section;
  83. SELECT
  84. COUNT(*) AS total,
  85. SUM(`异动类型` IS NOT NULL AND TRIM(`异动类型`) <> '') AS has_change_type,
  86. SUM(`异动前所在院系` IS NOT NULL AND TRIM(`异动前所在院系`) <> '') AS has_before_college,
  87. SUM(`异动前所在专业` IS NOT NULL AND TRIM(`异动前所在专业`) <> '') AS has_before_major,
  88. SUM(`异动前所在班级` IS NOT NULL AND TRIM(`异动前所在班级`) <> '') AS has_before_class,
  89. SUM(`异动前所在校区` IS NOT NULL AND TRIM(`异动前所在校区`) <> '') AS has_before_campus,
  90. SUM(`异动后所在院系` IS NOT NULL AND TRIM(`异动后所在院系`) <> '') AS has_after_college,
  91. SUM(`异动后所在专业` IS NOT NULL AND TRIM(`异动后所在专业`) <> '') AS has_after_major,
  92. SUM(`异动后所在班级` IS NOT NULL AND TRIM(`异动后所在班级`) <> '') AS has_after_class,
  93. SUM(`异动后所在校区` IS NOT NULL AND TRIM(`异动后所在校区`) <> '') AS has_after_campus
  94. FROM vw_jw_student_change_export;
  95. SELECT '========== 9. vw_jw_student_change_export 异动类型分布 ==========' AS section;
  96. SELECT
  97. `异动类型`,
  98. COUNT(*) AS cnt
  99. FROM vw_jw_student_change_export
  100. GROUP BY `异动类型`
  101. ORDER BY cnt DESC;
  102. SELECT '========== 10. vw_jw_student_change_export 当年记录数(按年)==========' AS section;
  103. SELECT
  104. YEAR(`异动生效时间`) AS effect_year,
  105. COUNT(*) AS cnt
  106. FROM vw_jw_student_change_export
  107. GROUP BY YEAR(`异动生效时间`)
  108. ORDER BY effect_year DESC
  109. LIMIT 10;
  110. SELECT '========== 11. vw_jw_student_change_export 样例(3 条)==========' AS section;
  111. SELECT
  112. `提交时间`, `异动生效时间`, `异动类型`, `申请人学号`, `姓名`,
  113. `异动前所在校区`, `异动前所在院系`, `异动前所在专业`, `异动前所在班级`,
  114. `异动后所在校区`, `异动后所在院系`, `异动后所在专业`, `异动后所在班级`
  115. FROM vw_jw_student_change_export
  116. ORDER BY `异动生效时间` DESC
  117. LIMIT 3;
  118. SELECT '========== 12. jw_cx 账号视图权限(可选)==========' AS section;
  119. SELECT
  120. GRANTEE,
  121. TABLE_NAME,
  122. PRIVILEGE_TYPE
  123. FROM information_schema.TABLE_PRIVILEGES
  124. WHERE TABLE_SCHEMA = DATABASE()
  125. AND TABLE_NAME IN ('vw_jw_student_export', 'vw_jw_student_change_export')
  126. AND GRANTEE LIKE '%jw_cx%'
  127. ORDER BY TABLE_NAME, PRIVILEGE_TYPE;
  128. SELECT '========== 13. 快速结论(人工查看)==========' AS section;
  129. SELECT
  130. CASE
  131. WHEN (
  132. SELECT COUNT(*) FROM information_schema.TABLES
  133. WHERE TABLE_SCHEMA = DATABASE()
  134. AND TABLE_NAME IN ('vw_jw_student_export', 'vw_jw_student_change_export')
  135. ) = 2 THEN 'PASS'
  136. ELSE 'FAIL'
  137. END AS views_exist,
  138. CASE
  139. WHEN (
  140. SELECT COUNT(*) FROM vw_jw_student_export LIMIT 1
  141. ) >= 0 THEN 'PASS'
  142. ELSE 'FAIL'
  143. END AS student_export_queryable,
  144. CASE
  145. WHEN (
  146. SELECT COUNT(*) FROM vw_jw_student_change_export LIMIT 1
  147. ) >= 0 THEN 'PASS'
  148. ELSE 'FAIL'
  149. END AS change_export_queryable,
  150. CASE
  151. WHEN (
  152. SELECT COUNT(*) FROM vw_jw_student_export
  153. WHERE `培养层次` IS NOT NULL
  154. AND TRIM(`培养层次`) <> ''
  155. AND `培养层次` NOT REGEXP '^[0-5]$'
  156. ) = 0 THEN 'PASS'
  157. ELSE 'WARN'
  158. END AS pycc_is_dict_value,
  159. CASE
  160. WHEN (
  161. SELECT COUNT(*) FROM information_schema.COLUMNS
  162. WHERE TABLE_SCHEMA = DATABASE()
  163. AND TABLE_NAME = 'xg_class_msg'
  164. AND COLUMN_NAME = 'campus_id'
  165. ) = 1 THEN 'PASS'
  166. ELSE 'FAIL'
  167. END AS class_campus_column_exists;