You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeORM多参数过滤不同类型值报Operand should contain 1 column(s)错误

问题根因

直接将_.pickBy生成的普通过滤对象传入where()方法时,TypeORM默认会将对象解析为字段=值的等值匹配逻辑:

  • 字段值为单值(比如数字类型的orgId、单元素数组)时,TypeORM可以正常解析为等值查询
  • 字段值为多元素数组时,TypeORM不会自动转换为IN查询,反而会生成类似WHERE status = ('approved', 'pending')的非法SQL,等于号右侧出现多值集合就会抛出Operand should contain 1 column(s)错误。
修复方案

不要直接传递原生对象作为where条件,手动区分单值等值匹配、数组值IN匹配场景,使用TypeORM原生条件构造+参数绑定实现,同时规避SQL注入风险。
直接在查询构造阶段遍历合法字段拼接条件即可,无需保留原有返回原生对象的getFilterConditions逻辑,修复后的代码如下:

protected getAll(filter: GetAllDataFilter): SelectQueryBuilder<EntityName> {
  const qb = Repository<EntityName>
    .createQueryBuilder('entityName')
    .select([
      'entityName.id',
      'entityName.status',
      'entityName.orgId',
    ])
    .groupBy('entityName.id');

  Object.entries(filter).forEach(([key, value]) => {
    // 跳过非实体字段、未传值的参数
    if (!this.entityProperties.has(key) || value === undefined) return;

    if (Array.isArray(value)) {
      // 数组类型参数走IN查询
      qb.andWhere(`entityName.${key} IN (:...${key})`, { [key]: value });
    } else {
      // 单值参数走等值匹配
      qb.andWhere(`entityName.${key} = :${key}`, { [key]: value });
    }
  });

  return qb;
}

如果需要拆分条件构造逻辑,也可以把遍历拼接条件的部分单独抽到getFilterConditions方法中,接收qb实例做条件追加即可,不要返回原生对象直接传给where()。

效果说明

传入过滤条件{ orgId: 12345, status: ['approved', 'pending'] }时,最终生成的SQL片段为:

WHERE entityName.orgId = 12345 AND entityName.status IN ('approved', 'pending')

完全满足多值枚举匹配、单值精确匹配、可选参数任意组合的过滤需求,所有参数通过TypeORM内置机制绑定,不存在SQL注入风险。

内容的提问来源于stack exchange,提问作者kayvera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 07:39:30