创建含INSERT语句的循环以补全tbmSecFieldGroup权限表
解决方案:补全所有权限组合记录
完全可行!这种补全维度组合的需求在数据库场景里很常见,咱们可以通过生成所有可能的权限组合,再对比原表插入缺失记录的方式实现。下面是具体的SQL脚本和步骤,针对SQL Server环境(你的表结构是SQL Server风格的):
步骤1:复制原表到新表(安全操作,避免修改原数据)
首先建议先把原表复制到一个新表操作,验证无误后再替换原表,防止误操作丢失数据:
-- 复制原表结构和已有数据到新表 SELECT * INTO [dbo].[tbmSecFieldGroup_Full] FROM [dbo].[tbmSecFieldGroup];
步骤2:生成所有缺失的权限组合并插入
接下来我们用CTE生成所有可能的权限组合(用户组+字段+指定安全过滤器+安全类型),然后把原表中不存在的组合插入进去:
WITH AllPossibleCombinations AS ( -- 获取所有用户组ID(如果有单独的用户组表,比如tbmGroups,建议用这个表替代,避免遗漏未设置权限的组) SELECT DISTINCT groupID FROM [dbo].[tbmSecFieldGroup] -- 替换成这个(如果有用户组表):SELECT groupID FROM [dbo].[tbmGroups] CROSS JOIN -- 获取所有字段ID(同理,如果有字段表tbmFields,用这个更准确) SELECT DISTINCT fldID FROM [dbo].[tbmSecFieldGroup] -- 替换成这个(如果有字段表):SELECT fldID FROM [dbo].[tbmFields] CROSS JOIN -- 你指定的需要覆盖的安全过滤器ID列表 (SELECT SecID FROM (VALUES (1),(2),(3),(4),(5),(8),(9)) AS TempSec(SecID)) AS AllSecFilters CROSS JOIN -- 安全类型:只读、不可用(这里假设typeID=1是只读,2是不可用,根据你的实际系统调整值) (SELECT typeID FROM (VALUES (1),(2)) AS TempType(typeID)) AS AllSecurityTypes ) -- 插入所有原表中不存在的组合 INSERT INTO [dbo].[tbmSecFieldGroup_Full] (groupID, fldID, SecID, typeID) SELECT apc.groupID, apc.fldID, apc.SecID, apc.typeID FROM AllPossibleCombinations apc WHERE NOT EXISTS ( SELECT 1 FROM [dbo].[tbmSecFieldGroup_Full] existing WHERE existing.groupID = apc.groupID AND existing.fldID = apc.fldID AND existing.SecID = apc.SecID AND existing.typeID = apc.typeID );
关键注意事项
- 用户组/字段来源:如果你的系统有单独的用户组表(比如
tbmGroups)或字段表(比如tbmFields),一定要用这些表来获取groupID和fldID,而不是从原权限表取去重值——因为原表可能没有包含那些还没设置过任何权限的用户组或字段,会导致遗漏。 - 安全类型ID:脚本里的
typeID值(1和2)是假设的,你需要替换成你系统中对应「只读」和「不可用」的实际数值。 - 性能优化:如果总组合数很大(按你说的65组×35000字段×7过滤器×2类型≈3185万条),建议先删除新表上的索引(比如主键索引),插入完成后再重建索引,能大幅提升插入速度。
- 验证数据:插入完成后,可以用下面的语句验证某组某字段的记录是否齐全:
-- 验证指定组、指定字段的所有组合(替换成实际groupID和fldID) SELECT * FROM [dbo].[tbmSecFieldGroup_Full] WHERE groupID = '你的目标组ID' AND fldID = 3257 ORDER BY SecID, typeID;
最终替换原表(可选)
如果验证新表数据正确,你可以替换原表:
-- 重命名原表为备份 EXEC sp_rename '[dbo].[tbmSecFieldGroup]', '[dbo].[tbmSecFieldGroup_Backup]'; -- 把新表重命名为原表名 EXEC sp_rename '[dbo].[tbmSecFieldGroup_Full]', '[dbo].[tbmSecFieldGroup]';
内容的提问来源于stack exchange,提问作者Themisunderstud
相关产品推荐
相关产品推荐

