HaniBlindBox/server/scripts/checkpoint_validate_all_tables.sql
2026-01-02 05:18:05 +08:00

304 lines
12 KiB
Transact-SQL

-- ============================================================
-- Checkpoint 9: 表结构创建综合验证脚本
-- Feature: database-migration, Property 1: 表结构完整性
-- Validates: All Requirements from Tasks 2-8
-- ============================================================
SET NOCOUNT ON;
PRINT '========================================';
PRINT 'Checkpoint 9: 表结构创建综合验证报告';
PRINT '执行时间: ' + CONVERT(VARCHAR, GETDATE(), 120);
PRINT '========================================';
PRINT '';
-- ============================================================
-- 1. 验证所有预期表是否存在
-- ============================================================
PRINT '1. 验证所有预期表是否存在';
PRINT '========================================';
DECLARE @expected_tables TABLE (
category NVARCHAR(50),
table_name NVARCHAR(50),
source_table NVARCHAR(50),
expected_records INT
);
-- 用户系统表 (Task 2)
INSERT INTO @expected_tables VALUES ('用户系统', 'users', 'user', 2202);
INSERT INTO @expected_tables VALUES ('用户系统', 'user_accounts', 'user_account', 3452);
INSERT INTO @expected_tables VALUES ('用户系统', 'user_login_logs', 'user_login_log', 11584);
INSERT INTO @expected_tables VALUES ('用户系统', 'user_addresses', 'user_address', 51);
-- 商品系统表 (Task 3)
INSERT INTO @expected_tables VALUES ('商品系统', 'goods', 'goods', 503);
INSERT INTO @expected_tables VALUES ('商品系统', 'goods_items', 'goods_list', 1852);
INSERT INTO @expected_tables VALUES ('商品系统', 'goods_types', 'goods_type', 13);
INSERT INTO @expected_tables VALUES ('商品系统', 'goods_extensions', 'goods_extend', 34);
INSERT INTO @expected_tables VALUES ('商品系统', 'prize_levels', 'shang', 106);
-- 订单系统表 (Task 4)
INSERT INTO @expected_tables VALUES ('订单系统', 'orders', 'order', 15);
INSERT INTO @expected_tables VALUES ('订单系统', 'order_items', 'order_list', 67);
INSERT INTO @expected_tables VALUES ('订单系统', 'order_items_recovery', 'order_list_recovery', 8);
INSERT INTO @expected_tables VALUES ('订单系统', 'order_items_send', 'order_list_send', 0);
-- 财务系统表 (Task 5)
INSERT INTO @expected_tables VALUES ('财务系统', 'profit_money', 'profit_money', 25770);
INSERT INTO @expected_tables VALUES ('财务系统', 'profit_integral', 'profit_integral', 33187);
INSERT INTO @expected_tables VALUES ('财务系统', 'profit_money2', 'profit_money2', 19277);
INSERT INTO @expected_tables VALUES ('财务系统', 'profit_pay', 'profit_pay', 3211);
INSERT INTO @expected_tables VALUES ('财务系统', 'profit_score', 'profit_score', 0);
INSERT INTO @expected_tables VALUES ('财务系统', 'profit_ou_qi', 'profit_ou_qi', 8339);
-- 优惠券系统表 (Task 6)
INSERT INTO @expected_tables VALUES ('优惠券系统', 'coupons', 'coupon', 19);
INSERT INTO @expected_tables VALUES ('优惠券系统', 'coupon_receives', 'coupon_receive', 7799);
INSERT INTO @expected_tables VALUES ('优惠券系统', 'user_coupons', 'user_coupon', 0);
-- 钻石系统表 (Task 6)
INSERT INTO @expected_tables VALUES ('钻石系统', 'diamond_products', 'diamond_products', 5);
INSERT INTO @expected_tables VALUES ('钻石系统', 'diamond_orders', 'diamond_orders', 398);
-- 任务签到系统表 (Task 7)
INSERT INTO @expected_tables VALUES ('任务签到', 'tasks', 'task_list', 9);
INSERT INTO @expected_tables VALUES ('任务签到', 'user_tasks', 'user_task_list', 4899);
INSERT INTO @expected_tables VALUES ('任务签到', 'sign_configs', 'sign_config', 35);
INSERT INTO @expected_tables VALUES ('任务签到', 'user_signs', 'user_sign', 702);
-- VIP系统表 (Task 7)
INSERT INTO @expected_tables VALUES ('VIP系统', 'vip_levels', 'quan_yi_level', 75);
INSERT INTO @expected_tables VALUES ('VIP系统', 'vip_level_rewards', 'quan_yi_level_jiang', 225);
INSERT INTO @expected_tables VALUES ('VIP系统', 'user_vip_rewards', 'user_quan_yi_level_jiang', 1393);
-- 系统配置表 (Task 8)
INSERT INTO @expected_tables VALUES ('系统配置', 'configs', 'config', 25);
INSERT INTO @expected_tables VALUES ('系统配置', 'deliveries', 'delivery', 11);
INSERT INTO @expected_tables VALUES ('系统配置', 'pictures', 'picture', 1176);
INSERT INTO @expected_tables VALUES ('系统配置', 'adverts', 'advert', 16);
-- 管理后台表 (Task 8)
INSERT INTO @expected_tables VALUES ('管理后台', 'admins', 'admin', 3);
INSERT INTO @expected_tables VALUES ('管理后台', 'admin_login_logs', 'admin_login_log', 0);
INSERT INTO @expected_tables VALUES ('管理后台', 'admin_operation_logs', 'admin_operation_log', 0);
-- 验证表存在性
SELECT
e.category AS [类别],
e.table_name AS [目标表名],
e.source_table AS [源表名],
CASE WHEN t.TABLE_NAME IS NOT NULL THEN '✓ 存在' ELSE '✗ 不存在' END AS [状态]
FROM @expected_tables e
LEFT JOIN INFORMATION_SCHEMA.TABLES t
ON t.TABLE_NAME = e.table_name
AND t.TABLE_TYPE = 'BASE TABLE'
ORDER BY e.category, e.table_name;
-- 统计表存在情况
DECLARE @total_expected INT;
DECLARE @total_exists INT;
SELECT @total_expected = COUNT(*) FROM @expected_tables;
SELECT @total_exists = COUNT(*)
FROM @expected_tables e
INNER JOIN INFORMATION_SCHEMA.TABLES t
ON t.TABLE_NAME = e.table_name
AND t.TABLE_TYPE = 'BASE TABLE';
PRINT '';
PRINT '表存在性统计: ' + CAST(@total_exists AS VARCHAR) + '/' + CAST(@total_expected AS VARCHAR) + ' 表已创建';
PRINT '';
-- ============================================================
-- 2. 验证主键约束
-- ============================================================
PRINT '2. 验证主键约束';
PRINT '========================================';
SELECT
e.category AS [类别],
e.table_name AS [表名],
ISNULL(tc.CONSTRAINT_NAME, '✗ 无主键') AS [主键约束],
CASE WHEN tc.CONSTRAINT_NAME IS NOT NULL THEN '✓ 通过' ELSE '✗ 失败' END AS [状态]
FROM @expected_tables e
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON tc.TABLE_NAME = e.table_name
AND tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
ORDER BY e.category, e.table_name;
-- 统计主键情况
DECLARE @pk_count INT;
SELECT @pk_count = COUNT(DISTINCT e.table_name)
FROM @expected_tables e
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON tc.TABLE_NAME = e.table_name
AND tc.CONSTRAINT_TYPE = 'PRIMARY KEY';
PRINT '';
PRINT '主键约束统计: ' + CAST(@pk_count AS VARCHAR) + '/' + CAST(@total_expected AS VARCHAR) + ' 表有主键';
PRINT '';
-- ============================================================
-- 3. 验证索引数量
-- ============================================================
PRINT '3. 验证索引数量';
PRINT '========================================';
SELECT
e.category AS [类别],
e.table_name AS [表名],
COUNT(i.name) AS [索引数量]
FROM @expected_tables e
LEFT JOIN sys.tables t ON t.name = e.table_name
LEFT JOIN sys.indexes i ON i.object_id = t.object_id AND i.name IS NOT NULL
GROUP BY e.category, e.table_name
ORDER BY e.category, e.table_name;
PRINT '';
-- ============================================================
-- 4. 验证表注释
-- ============================================================
PRINT '4. 验证表注释';
PRINT '========================================';
SELECT
e.category AS [类别],
e.table_name AS [表名],
CAST(ep.value AS NVARCHAR(100)) AS [表注释],
CASE WHEN ep.value IS NOT NULL THEN '✓ 有注释' ELSE '✗ 无注释' END AS [状态]
FROM @expected_tables e
LEFT JOIN sys.tables t ON t.name = e.table_name
LEFT JOIN sys.extended_properties ep
ON ep.major_id = t.object_id
AND ep.minor_id = 0
AND ep.name = 'MS_Description'
ORDER BY e.category, e.table_name;
-- 统计表注释情况
DECLARE @comment_count INT;
SELECT @comment_count = COUNT(*)
FROM @expected_tables e
INNER JOIN sys.tables t ON t.name = e.table_name
INNER JOIN sys.extended_properties ep
ON ep.major_id = t.object_id
AND ep.minor_id = 0
AND ep.name = 'MS_Description';
PRINT '';
PRINT '表注释统计: ' + CAST(@comment_count AS VARCHAR) + '/' + CAST(@total_expected AS VARCHAR) + ' 表有注释';
PRINT '';
-- ============================================================
-- 5. 验证字段数量
-- ============================================================
PRINT '5. 验证字段数量';
PRINT '========================================';
SELECT
e.category AS [类别],
e.table_name AS [表名],
COUNT(c.COLUMN_NAME) AS [字段数量]
FROM @expected_tables e
LEFT JOIN INFORMATION_SCHEMA.COLUMNS c ON c.TABLE_NAME = e.table_name
GROUP BY e.category, e.table_name
ORDER BY e.category, e.table_name;
PRINT '';
-- ============================================================
-- 6. 验证唯一约束
-- ============================================================
PRINT '6. 验证唯一约束';
PRINT '========================================';
SELECT
t.name AS [表名],
i.name AS [唯一约束名],
c.name AS [约束列]
FROM sys.tables t
INNER JOIN sys.indexes i ON t.object_id = i.object_id AND i.is_unique = 1 AND i.is_primary_key = 0
INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE t.name IN (SELECT table_name FROM @expected_tables)
ORDER BY t.name, i.name;
PRINT '';
-- ============================================================
-- 7. 验证无外键约束 (Requirements 12.3)
-- ============================================================
PRINT '7. 验证无外键约束 (Requirements 12.3)';
PRINT '========================================';
DECLARE @fk_count INT;
SELECT @fk_count = COUNT(*)
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
WHERE tc.TABLE_NAME IN (SELECT table_name FROM @expected_tables)
AND tc.CONSTRAINT_TYPE = 'FOREIGN KEY';
IF @fk_count = 0
PRINT '✓ 通过: 所有表均无外键约束';
ELSE
PRINT '✗ 失败: 发现 ' + CAST(@fk_count AS VARCHAR) + ' 个外键约束';
PRINT '';
-- ============================================================
-- 8. 验证总结
-- ============================================================
PRINT '========================================';
PRINT '验证总结';
PRINT '========================================';
PRINT '';
-- 计算各项统计
DECLARE @missing_tables INT = @total_expected - @total_exists;
DECLARE @missing_pk INT = @total_expected - @pk_count;
DECLARE @missing_comments INT = @total_expected - @comment_count;
-- 输出总结
IF @missing_tables = 0
PRINT '✓ 表结构: 所有 ' + CAST(@total_expected AS VARCHAR) + ' 个表已创建';
ELSE
PRINT '✗ 表结构: 缺少 ' + CAST(@missing_tables AS VARCHAR) + ' 个表';
IF @missing_pk = 0
PRINT '✓ 主键约束: 所有表都有主键';
ELSE
PRINT '⚠ 主键约束: ' + CAST(@missing_pk AS VARCHAR) + ' 个表缺少主键';
IF @fk_count = 0
PRINT '✓ 外键约束: 符合要求,无外键';
ELSE
PRINT '✗ 外键约束: 不符合要求,存在外键';
IF @missing_comments = 0
PRINT '✓ 表注释: 所有表都有注释';
ELSE
PRINT '⚠ 表注释: ' + CAST(@missing_comments AS VARCHAR) + ' 个表缺少注释';
PRINT '';
-- 最终结果
IF @missing_tables = 0 AND @missing_pk = 0 AND @fk_count = 0
BEGIN
PRINT '========================================';
PRINT '✓ Checkpoint 9 验证通过!';
PRINT '所有表结构创建正确,可以继续数据迁移。';
PRINT '========================================';
END
ELSE
BEGIN
PRINT '========================================';
PRINT '✗ Checkpoint 9 验证失败!';
PRINT '请检查上述问题后重新验证。';
PRINT '========================================';
END
PRINT '';
PRINT '验证完成时间: ' + CONVERT(VARCHAR, GETDATE(), 120);