Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

233
Views
La introducción de un parámetro con nombre rompe la consulta jOOQ

Para consultar una base de datos PostgreSQL 10.11, estoy usando jOOQ 3.12.4, que viene incluido con Spring Boot 2.2.

Supongamos que he creado una consulta usando jOOQ como esta:

 final String[] ids = ...; final var query = dslContext.selectFrom(MY_TABLE).where(MY_TABLE.ID.in(ids)); final Map<String, List<MyTable>> changeDomains = query.fetch().intoGroups(MY_TABLE.ID, MyTable.class);

Este código funciona bien y produce los resultados esperados. Pero cuando refactorizo mi consulta e introduzco un parámetro con nombre (para reutilizar la consulta en varias partes de mi código), así:

 final String[] ids = ...; final var query = dslContext.selectFrom(MY_TABLE).where(MY_TABLE.ID.in(param("ids"))); final Map<String, List<MyTable>> changeDomains = query.bind("ids", ids).fetch().intoGroups(MY_TABLE.ID, MyTable.class);

De repente empiezo a recibir el siguiente error:

 org.springframework.jdbc.BadSqlGrammarException: jOOQ; bad SQL grammar ...; nested exception is org.postgresql.util.PSQLException: ERROR: operator does not exist: text = character varying[] Hinweis: No operator matches the given name and argument type(s). You might need to add explicit type casts.

Editar: me sale el mismo error cuando uso

 MY_TABLE.ID.in(param("ids", String[].class))

en cambio.

¿Cómo puedo resolver o evitar este problema?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Una mejor solución para su enfoque de reutilización de código

Pero cuando refactorizo mi consulta e introduzco un parámetro con nombre (para reutilizar la consulta en varias partes de mi código)

Si bien podría usar jOOQ de esta manera (¡tenga cuidado al mutar y reutilizar las consultas de jOOQ de una manera que no sea segura para subprocesos!), generalmente se recomienda usar jOOQ de una manera más funcional, consulte, por ejemplo:

  • https://blog.jooq.org/2017/01/16/un-enfoque-de-programación-funcional-para-sql-dinámico-con-jooq/
  • https://www.jooq.org/doc/latest/manual/sql-building/dynamic-sql/

No gana mucho reutilizando una consulta jOOQ, específicamente, apenas hay ganancia de rendimiento.

Entonces, en lugar de esto:

 final var query = dslContext.selectFrom(MY_TABLE) .where(MY_TABLE.ID.in(param("ids"))); final Map<String, List<MyTable>> changeDomains = query .bind("ids", ids).fetch().intoGroups(MY_TABLE.ID, MyTable.class);

Escribe esto:

 public ResultQuery<MyTableRecord> query(String[] ids) { return dslContext.selectFrom(MY_TABLE).where(MY_TABLE.ID.in(ids)); } // And then: final Map<String, List<MyTable>> changeDomains = query(ids) .fetch().intoGroups(MY_TABLE.ID, MyTable.class);

El problema real con el que te encontraste:

jOOQ, JDBC y SQL no admiten listas IN de valor de enlace único. Si bien parece útil escribir esto:

 SELECT * FROM t WHERE c IN (:bind_value)

Y pasar una matriz o lista como un valor de enlace único, esto no es compatible con SQL. Algunas API pueden pretender que esto es compatible (pero detrás de escena, reemplace el valor de enlace único por múltiples ?, ?, ..., ?

PostgreSQL admite el operador = ANY (:bind_value) con matrices

 SELECT * FROM t WHERE c = ANY (:bind_value)

Podrías usarlo en jOOQ usando

 dslContext.selectFrom(MY_TABLE).where(MY_TABLE.ID.eq(any(ids)));

De esa forma, podría llamar al método bind() para reemplazar la matriz antes de la ejecución. Sin embargo, sigo recomendando que escriba funciones que devuelvan consultas dinámicamente.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!