首页 文章

TypeORM Postgres在QueryBuilder或Find中有什么或IN?

提问于
浏览
0

我一直在试图弄清楚如何选择Postgres数据库中的每个记录,其中包含具有整数数组的列中的某个id . 我是新手,但我相信我想要一个如下所示的SQL语句:

SELECT * FROM members WHERE 2 = ANY(skill_id_array);

skill_id_array列中的数据如下所示:{1,4,7} .

从Angular前端我传入一个id如2作为参数 . 登录终端显示select语句的结尾,但它失败了:

... WHERE $1 ANY (skill_id_array) -- PARAMETERS: [2]

我相信问题是我试图将变量传递给代码并且它讨厌它 . 请注意,我一直在尝试使用find方法和QueryBuilder . 结果错误在评论中 . (完整的CRUD正在运行,所以我的整体设置很好 . )

这工作得很好,但我知道这有一个SQL注入问题:

const membersBySkill = await this.entityManager.query(
      `SELECT * FROM members WHERE ${integerId} = ANY(members.skill_id_array)`
    );

这有效,但我不确定sql注入问题加上我想使用TypeORM find或QueryBuilder .

const sql = 'SELECT * FROM members WHERE '+ integerId + ' = ANY(skill_id_array)';
  const membersBySkill = await this.entityManager.query(sql);

在我的服务中:

import {Any} from "typeorm";

  async getMembersBySkill(id) {
    const integerId = parseInt(id, 10); // convert id to integer for Postgres array.
    // console.log('skill_id in service', integerId);
    // Find one skill id in an array of id's.
/*
    const membersBySkill = await this.connection.getRepository(Members).find({
      skill_id_array: Any(integerId)
    });
    //  This results in an IDE error.  It doesn't like a number as 
    //  the ANY param.  "{integerId: number} is not assignable to
    //  parameter type '{}[] | FindOperator<{}>'.
    //  In terminal: error: could not find array type for data type integer[].  
    //  However, the db has integers.
*/

    const membersBySkill = await getRepository(Members)
      .createQueryBuilder("members")
      .select('*')
      .where(":id IN (skill_id_array)", {id: integerId})
      .getMany();
      // SELECT * FROM "members" "members" WHERE $1 IN (skill_id_array) -- PARAMETERS: [2]
      // server console: error: malformed array literal: "2"

    console.log('membersBySkill: ', membersBySkill);
    return membersBySkill;
  }

实体:

@Column('int', { array: true, nullable: true})
  skill_id_array: number[];

Postgres列类型: integer[]

每次更改都会停止并启动Nestjs服务器 .

1 回答

  • 0

    Web上的许多地方都说SQL运算符IN和ANY几乎是等价的 . 因此,除了任何需要'='之外,我在思考它们的方向上处于领先地位几乎相同 . 错了,但花了很长时间才弄明白 .

    QueryBuilder中的这个ANY设置有效:

    const membersBySkill = await getRepository(Members)
          .createQueryBuilder()
          .where(':id = ANY (skill_id_array)', {id: integerId})
          .getMany();
    

    以前我使用的是TypeORM查找选项文档中的“任意”设置,因为在QueryBuilder文档中尚未解决任何问题 . 这似乎是当时的方式,但不要混合它们 .

    TypeORM主要贡献者@pleerock建议在这个设置中使用别名,所以这是他的例子,用别名'member'作为参考:

    const results = await getRepository(Members)
        .createQueryBuilder("member") // you shall assign an alias
        .where(":id = ANY(member.skill_id_array)", { id: 1 }) // and use that alias everywhere in your query builder
        .getMany();
    

    那么IN呢?

    问题是你不能像使用AN一样使用IN变量 . 它永远不会奏效 . 它需要一个'标量列表'而不是表达式是文档如何表达它 . 我的var包含一个标量列表,但IN参数必须有一个列表,而不是列表的引用 .

    IN (id1, id2, id5) 应该工作,你需要用其他整数或字符串填充其他变量 . 对于我的应用程序,这意味着解析我的skill_id_array并将各个整数分配给他们自己独特的变量 . 当ANY轻松完成相同的结果时,这是很多工作 .

相关问题