SQLite 复合外键:其中一列为空,为什么剩下一列不再检查匹配 一条记录用租户和编号共同指向父表,租户写成不存在的值,编号却为空,插入竟然成功。若只检查PRAGMA foreign_keys已经打开,很容易把它当成SQLite漏验。真正原因是复合外键对NULL有明确规则:任意一个... yunqueblog/ 技术教程/ 2026-10-03/ 4 阅读
SQLite 授权回调的 IGNORE:列值被隐藏了,为什么带条件的整行也不见了 一个查询工具想保留记录编号,但不返回某个字段,于是在SQLite授权回调里对该字段返回SQLITE_IGNORE。直接SELECT时字段变成空值,看起来符合预期;再加一个字段大于零的条件,整条记录却消失了。这个返回值... yunqueblog/ 技术教程/ 2026-10-02/ 3 阅读
SQLite min 与 max 的参数个数:多写一个值,为什么汇总结果变成了逐行结果 原查询用 max(v) 求整张表的最大值。为了让结果至少为五,维护者顺手改成 max(v, 5),结果接口突然收到三行。这里多出来的实参改变了函数类别:SQLite 的 min 和 max 在只有一个实参时进行聚合,... yunqueblog/ 技术教程/ 2026-10-02/ 2 阅读
SQLite 空值排序:改成降序后,缺失记录为什么换到了另一端 一个清单按预计耗时从小到大显示,未填写耗时的项目突然出现在最前面。改成降序后,它们又跑到最后。开发者原本只想翻转已有数字的顺序,却同时改变了缺失记录的位置。SQLite 默认在升序时把 NULL 排在前面,降序时放在... yunqueblog/ 技术教程/ 2026-10-02/ 2 阅读
SQLite UNIQUE 遇到 NULL:用部分唯一索引限制每个用户只有一个默认项 地址簿里每个用户可以保存多条地址,但最多只能有一个默认地址。有人会增加一个可空标记,再建立联合唯一索引,期待数据库自动理解“默认只能有一个”。问题在于,唯一约束比较的是被索引的值,它不会替应用推断哪类记录需要竞争同一... yunqueblog/ 技术教程/ 2026-10-01/ 2 阅读
SQLite EXCEPT 做差集:缺少的编号与缺少的明细不能用同一种比较 核对两份导出清单时,常会问“左边有哪些右边没有的内容”。这句话看起来明确,实际却至少有两种意思:缺少哪些编号,或缺少哪些编号与状态的组合。EXCEPT 比较的是查询输出的整行,选择哪些列,本身就在定义什么算同一条。它... yunqueblog/ 技术教程/ 2026-10-01/ 2 阅读
SQLite CHECK 约束:写了数量大于零,为什么 NULL 仍能插入 条件看起来够严,空值还是通过了给数量列写上 CHECK(qty > 0),通常是想保证每一条记录都有正数数量。但导入缺失数据时,NULL 仍可能写入成功。原因是 SQLite 的 CHECK 只在表达式求值并转成数值... yunqueblog/ 技术教程/ 2026-10-01/ 2 阅读
SQL NULL 三值逻辑:为什么“不等于”会漏掉空值 想找出“状态不是已完成”的记录,写了 status 不等于 done,却发现未知状态的行没有出现。这不是数据库随机漏数据,而是 NULL 参与比较时会产生未知结果。本文使用 PostgreSQL 18 的普通标量表达... yunqueblog/ 技术教程/ 2026-10-01/ 2 阅读