如何在SQLite中通过视图实现简单的物料清单(BOM)递归查询?

P粉602998670

P粉602998670

2026-07-14

912人浏览

原创

sqlite 3.8.3+虽支持with recursive,但若编译未启用sqlite_enable_recursive则失效;此时需用应用层循环调用单层视图模拟bom递归展开,或使用临时视图封装递归查询。

如何在sqlite中通过视图实现简单的物料清单(bom)递归查询?

SQLite 不支持标准递归 CTE 的变通方案

SQLite 从 3.8.3 版本起确实支持 WITH RECURSIVE,但很多嵌入式场景(如旧版 Android、某些 Electron 应用或精简 SQLite 构建)仍可能禁用该功能。若你执行 WITH RECURSIVE ... 报错 no such function: recursive 或直接提示语法错误,说明当前 SQLite 编译时未启用 ENABLE_RTREE 和/或 ENABLE_FTS5 之外的关键开关 —— 实际上是 ENABLE_RECURSIVE_TRIGGERS 并不相关,真正需要的是编译时定义 SQLITE_ENABLE_recursive(注意下划线)。别急着重编译,先确认版本和能力:

SELECT sqlite_version(), compile_options LIKE '%ENABLE_RECURSIVE%';

返回 0 表示不可用,此时视图本身无法递归,必须换思路。

用普通视图 + 应用层循环模拟 BOM 展开

视图在 SQLite 中是静态查询封装,不能带参数、不能递归、也不能引用自身。所以「通过视图实现递归 BOM」的准确理解是:用视图封装单层子项查询,再由外部代码反复调用。假设你的 BOM 表结构为:

CREATE TABLE bom (
  parent TEXT,
  child TEXT,
  qty INTEGER
);

那么可建一个清晰的单层展开视图:

CREATE VIEW bom_level_1 AS
SELECT parent, child, qty FROM bom;

后续操作交给应用逻辑,例如 Python 中:

SQLite v3.10
SQLite v3.10

SQLite是一款轻型的数据库

下载
  • 初始化栈:stack = [('A', 1)](根物料 A,需求数量 1)
  • 每次 pop 一个 (item, multiplier),查 SELECT child, qty FROM bom_level_1 WHERE parent = ?
  • 将结果乘以 multiplier 后推入栈(如 A→B qty=2,则 B 入栈为 ('B', 1*2)
  • 重复直到栈空;累计各 child 的总需用量

这种模式完全绕过 SQLite 递归限制,且易于调试、支持条件过滤(如只展开到第 3 层)、便于加缓存。

启用递归 CTE 后,视图仍不能递归,但可封装 WITH 查询

即使 SQLite 支持 WITH RECURSIVE,你也**不能**在视图定义里写递归 CTE —— SQLite 明确禁止视图中使用 WITH(报错 near "WITH": syntax error)。正确做法是把完整递归逻辑写成独立查询,或封装为临时视图(仅会话有效):

CREATE TEMP VIEW bom_full AS
WITH RECURSIVE tree(parent, child, qty, level) AS (
  SELECT parent, child, qty, 1 FROM bom WHERE parent = 'A'
  UNION ALL
  SELECT b.parent, b.child, b.qty * t.qty, t.level + 1
  FROM bom b
  JOIN tree t ON b.parent = t.child
  WHERE t.level <p>注意几点:</p>
  • CREATE TEMP VIEW 只在当前连接有效,关闭连接即消失
  • WHERE parent = 'A' 是硬编码,无法参数化;如需动态根节点,必须拼 SQL 或用绑定参数重执行整个 WITH 查询
  • level 是安全兜底,防止环形引用导致无限循环
  • 递归分支中 b.qty * t.qty 是典型 BOM 数量叠加逻辑,别漏乘上层数量

环形引用检测与性能陷阱

BOM 数据常含隐性循环(如 A→B→C→A),递归 CTE 默认不检测,会卡死或超限报错 too many levels of recursion。手动加环检测需额外字段或临时表,成本高。更务实的做法是:

  • 入库前用应用层校验图结构(如 DFS 记录路径 Set)
  • 查询时强制加 LIMIT 1000 到递归 CTE 的顶层查询,而非仅靠 level
  • 对高频查询的根物料,预计算并缓存扁平化结果到新表,用触发器维护一致性
  • 避免在递归 CTE 中 JOIN 大表或用 LIKE 模糊匹配,每层都会放大数据集

视图在这里只是壳,真正的复杂度在数据建模和查询边界控制上——别指望一个 CREATE VIEW 解决 BOM 递归的所有问题。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

2023.06.29

1282

3

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2023.08.14

2787

10

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

2023.08.31

1234

3

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.05

525

5

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.09

1290

5

数据库对象名无效怎么解决
数据库对象名无效怎么解决

数据库对象名无效解决办法:1、检查使用的对象名是否正确,确保没有拼写错误;2、检查数据库中是否已存在具有相同名称的对象,如果是,请更改对象名为一个不同的名称,然后重新创建;3、确保在连接数据库时使用了正确的用户名、密码和数据库名称;4、尝试重启数据库服务,然后再次尝试创建或使用对象;5、尝试更新驱动程序,然后再次尝试创建或使用对象。

2023.10.16

1288

4

vb连接access数据库的方法
vb连接access数据库的方法

vb连接access数据库方法:1、使用ADO连接,首先导入System.Data.OleDb模块,然后定义一个连接字符串,接着创建一个OleDbConnection对象并使用Open() 方法打开连接;2、使用DAO连接,首先导入 Microsoft.Jet.OLEDB模块,然后定义一个连接字符串,接着创建一个JetConnection对象并使用Open()方法打开连接即可。

2023.10.16

2326

3

vb连接数据库的方法
vb连接数据库的方法

vb连接数据库的方法有使用ADO对象库、使用OLEDB数据提供程序、使用ODBC数据源等。详细介绍:1、使用ADO对象库方法,ADO是一种用于访问数据库的COM组件,可以通过ADO连接数据库并执行SQL语句。可以使用ADODB.Connection对象来建立与数据库的连接,然后使用ADODB.Recordset对象来执行查询和操作数据;2、使用OLEDB数据提供程序方法等等。

2023.10.19

1166

3

mdf文件导入数据库的方法
mdf文件导入数据库的方法

mdf文件导入数据库的方法有使用SQL Server Management Studio、使用SQL Server命令行工具、使用SQL Server Integration Services等方法。想了解更多mdf文件导入数据库的方法的相关内容,可以阅读本专题下面的文章。

2023.10.23

959

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SQLite参考手册
SQLite参考手册

共0课时 | 0.1万人学习

SQLite经典教程
SQLite经典教程

共51课时 | 36.8万人学习