
本文详解如何在 Prisma 查询中正确实现“字段等于指定值 或为 NULL”的复合条件(如 name = 'John' OR name IS NULL 且 age = 22 OR age IS NULL),解决 in: [val, null] 无法匹配 NULL 的常见误区。
本文详解如何在 prisma 查询中正确实现“字段等于指定值 **或为 null**”的复合条件(如 name = 'john' or name is null 且 age = 22 or age is null),解决 `in: [val, null]` 无法匹配 null 的常见误区。
在 Prisma 中,in 运算符明确排除 NULL 值(即 field: { in: ['a', null] } 实际等价于 field IN ('a'),不会包含 NULL 记录),这是由 SQL 标准和 Prisma 底层行为决定的。因此,若需同时匹配非空值与 NULL,必须显式使用 OR 逻辑组合条件,并配合 AND 组织多字段逻辑。
正确的做法是:对每个需支持“值或 NULL”的字段,单独构建一个 OR 子句;再将各字段的 OR 条件通过 AND 合并,确保所有字段条件同时满足。
以下为完整、类型安全的实现示例(以 MyModel 为例):
import { Prisma } from '@prisma/client';
const results = await prisma.myModel.findMany({
where: {
AND: [
{
// name 等于 "John" 或为 NULL
OR: [
{ name: 'John' },
{ name: null },
],
},
{
// age 等于 22 或为 NULL
OR: [
{ age: 22 },
{ age: null },
],
},
],
},
});✅ 关键要点说明:
- OR 数组内每个对象代表一种可选路径(如 { name: 'John' } 或 { name: null }),Prisma 会将其编译为 name = 'John' OR name IS NULL;
- 外层 AND 确保两个字段的条件同时成立(即 name 满足其 OR 条件 且 age 满足其 OR 条件);
- 使用 Prisma.validator(如答案中所示)可增强 TypeScript 类型安全性,防止拼写错误或非法字段访问,推荐在复杂查询中启用;
- 不要混用 in 与 null —— Prisma 明确不支持 in: [val, null] 表达 NULL 匹配。
⚠️ 注意事项:
- NULL 比较在 SQL 中使用 IS NULL / IS NOT NULL,而非 = NULL,Prisma 会自动转换 { field: null } 为 IS NULL;
- 若需“排除 NULL 并限制多个值”,才使用 in(如 { age: { in: [22, 25, 30] } });
- 多字段联合 NULL 过滤时,避免误用顶层 OR(如原问题代码),否则会导致逻辑错误(例如匹配到 name='John' 但 age 非 22 且非 NULL 的记录)。
掌握 OR + AND 的嵌套结构,是编写健壮、可读性强的 Prisma 复合查询的基础。建议在实际项目中结合 Prisma Studio 验证生成的 SQL,确保语义符合预期。

















