SQLite触发器实现动态N条INSERT的方案(无循环/变量支持场景)
实现方案
核心思路:SQLite 3.8.3及以上版本支持递归公共表表达式(CTE),可以替代循环生成指定数量的行,不需要用到变量,完全可以满足你的需求。
如果你的SQLite版本特别旧不支持递归CTE,也可以通过提前创建数字辅助表的方式实现。
触发器完整代码
CREATE TRIGGER insert_sub_after_complete AFTER UPDATE OF Complete ON LineUp -- 仅当Complete从非TRUE改为TRUE时触发,避免重复更新导致重复插入 WHEN NEW.Complete = TRUE AND OLD.Complete != TRUE BEGIN -- 递归CTE生成Number_Sub行数据 WITH RECURSIVE generate_rows(n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM generate_rows WHERE n < NEW.Number_Sub ) INSERT INTO Sub (Fixture) SELECT NEW.Fixture FROM generate_rows; END;
如果你的业务中Number_Sub最大值超过1000,需要调整递归深度上限,在触发器BEGIN之后第一行添加:
PRAGMA max_recursion_depth = 10000;
数值根据你的业务最大Number_Sub调整即可。
低版本SQLite兼容方案
如果你的SQLite版本低于3.8.3不支持递归CTE,可以预先创建数字辅助表实现:
-- 提前创建数字辅助表,存储1到业务最大可能的Number_Sub值,这里示例存1到10000 CREATE TABLE numbers (n INT PRIMARY KEY); -- 一次性插入足够的数字 WITH RECURSIVE generate_num(n) AS ( SELECT 1 UNION ALL SELECT n+1 FROM generate_num WHERE n < 10000 ) INSERT INTO numbers SELECT n FROM generate_num; -- 触发器INSERT逻辑改为 INSERT INTO Sub (Fixture) SELECT NEW.Fixture FROM numbers WHERE n <= NEW.Number_Sub;
测试验证
执行以下SQL即可验证效果:
-- 将Fixture=2的行Complete设为TRUE UPDATE LineUp SET Complete = TRUE WHERE Fixture = 2; -- 查询Sub表可看到新增了3条Fixture=2的记录 SELECT * FROM Sub;
问题表述优化建议
- 补充你使用的SQLite具体版本,不同版本支持的语法特性有差异
- 说明
LineUp表的主键字段,比如Fixture是否为唯一值,是否存在同一个Fixture对应多条LineUp记录的场景 - 补充边界场景要求:比如
Number_Sub为0、负数时是否需要跳过插入,多次更新Complete为TRUE时是否要避免重复插入 - 说明
Sub表是否有其他约束字段,比如自增ID、唯一约束等,方便给出更贴合场景的方案
内容的提问来源于stack exchange,提问作者Dan Wright
相关产品推荐
相关产品推荐

