Cómo realizar una consulta similar TypeORM

4 minutos de lectura

Avatar de usuario de Gardezi
Gardezi

Hola chicos, estoy tratando de encontrar todos los resultados que tienen un en ellos. He intentado un par de formas, pero el problema es que nada funciona. Simplemente devuelve una matriz vacía.

var data = await getRepository(User)
  .createQueryBuilder("user")
  .where("user.firstName = %:name%", { name: firstName })
  .getMany();

y algo como esto

var data = await getRepository(User)
  .createQueryBuilder("user")
  .where("user.firstName like %:name%", { name: firstName })
  .getMany();

pero nada funciona. Todos estos me están devolviendo una matriz vacía. alguien me puede ayudar gracias

avatar de usuario de pleerock
pleerock

La forma correcta es:

 var data = await getRepository(User)
                  .createQueryBuilder("user")
                  .where("user.firstName like :name", { name:`%${firstName}%` })
                  .getMany();

  • ¿Escapará esto correctamente? firstName?

    – usuario3413723

    8 sep 2018 a las 15:25

  • Lo probé… Creo que sí lo parametriza.

    – usuario3413723

    8 sep 2018 a las 15:28

  • @ user3413723 Acabo de probar esto. Escapa las comillas y otros caracteres, pero no (y no podría) escapar de los caracteres “%” y “_”.

    – david_p

    19 de febrero de 2019 a las 19:17

  • ¡¡¡¡Inyección SQL!!!!

    – Siyavash Hamdi

    11 de enero a las 3:07

  • ¿Hay documentación oficial para esto? no pude encontrar

    – Siva Shankaran

    27 abr a las 13:10

TypeORM proporciona fuera de la caja Like función. Ejemplo de sus documentos:

import {Like} from "typeorm";

const loadedPosts = await connection.getRepository(Post).find({
    title: Like("%out #%")
});

en tu caso:

var data = await getRepository(User).find({
    name: Like(`%${firstName}%`)
});

  • Si vienes aquí buscando ilike como yo, parece que llegará en un próximo lanzamiento: github.com/typeorm/typeorm/pull/5828

    – Aarón

    21 de julio de 2020 a las 13:36

  • Si el firstName no es un valor seguro, su solución no está protegida contra inyección SQL

    – Luca Roverelli

    8 sep 2020 a las 11:00

  • @LucaRoverelli, ¿cómo puedo protegerlo de la inyección de sql? ¿Es posible usar la misma sintaxis?

    – para J

    23 de junio de 2021 a las 3:21

  • no funciona en mongodb

    – Muhammad Awais

    2 jun a las 15:10

  • @LucaRoverelli, creo que la solución está protegida contra la inyección de sql porque aquí no estamos creando una consulta sin procesar. el valor se inyectará como parametrizado en la consulta sql. Podemos verificar la consulta subyacente al habilitar la opción de registro en la fuente de datos.

    – pate.kiran

    25 oct a las 10:53

También puede utilizar la función de base de datos para la concatenación. En postgres por ejemplo:

 var data = await getRepository(User)
              .createQueryBuilder("user")
              .where("user.firstName like '%' || :name || '%'", {name: firstName })
              .getMany();

Parece que todas las respuestas al momento de escribir, incluida la respuesta aceptada por pleerock, son vulnerables a la inyección de SQL a menos que la entrada del usuario se haya desinfectado de antemano.

 var data = await getRepository(User)
              .createQueryBuilder("user")
              .where("user.firstName like :name", { name:`%${firstName}%`})
              .getMany();

El hecho de que el código anterior sea válido en TypeORM hace que cualquier consulta de este estilo sea vulnerable a la exfiltración de datos. Imaginando la siguiente consulta similar:

 const data = await getRepository(User)
          .createQueryBuilder("user")
          .where("user.firstName like :name", { name: firstName })
          .getOne();

Datos no desinfectados provenientes del usuario que contienen % personaje enviado a firstName en la consulta anterior (por ejemplo let firstName="%John") permitiría a un usuario filtrar datos potencialmente privados sobre otros usuarios.

Por lo tanto, donde el caso de uso lo permita, uno debería asegurar que cualquier entrada del usuario se desinfecte y se eliminen los caracteres especiales.

Alternativamente, en MySQL, donde el caso de uso exige que estén presentes caracteres especiales en el texto, una búsqueda de texto completo puede ser más apropiada. Sin embargo, esto es más caro de mantener.

Cree una búsqueda de texto completo en la columna relevante y realice una consulta

    export class User {
        @PrimaryGeneratedColumn()
        id: number;

        @Index({fulltext: true})
        @Column()
        name: string;
    }

    const data = await this.repository
         .createQueryBuilder()
         .select()
         .where('MATCH(name) AGAINST (:name IN BOOLEAN MODE)', {name: name})
         .getOne()

var data = await  getRepository(User)
                        .createQueryBuilder("user")
                        .where("user.firstName ILIKE %q, {q:`%${VALUE_HERE}%` })
                .getMany();

Así es como lo hago. Espero eso ayude

  • Esto es vulnerable a la inyección de sql.

    – curtidor burton

    21 de diciembre de 2021 a las 23:04

Avatar de usuario de Salah ED
Salah ED

usando repositorios lo puse en el dónde por ejemplo :

await this.userRepository.findAndCount({
      relations: ['roles', 'company'],
      where: `(username like '%${seachValue}%' or firstname like '%${seachValue}%' 
      or lastname like '%${seachValue}%' or email like '%${seachValue}%')`,
      order: {
        [sortField]: sortDirection,
      },
    });

  • Esto es vulnerable a la inyección de sql.

    – curtidor burton

    21 de diciembre de 2021 a las 23:04

¿Ha sido útil esta solución?