Исключить предоставленные значения из select с помощью jooq

#java #postgresql #jooq #sql-except

#java #postgresql #jooq #sql-исключение

Вопрос:

Я пытаюсь найти список значений, присутствующих в данном списке, которых нет в таблице базы данных, используя jOOQ.

Например, у меня есть значения 1 , , 2 , 3 , 4 присутствующие в моем списке.

В базе данных уже есть записи для 1 и 2 .

Я ищу запрос jOOQ, который вернет мне результаты 3 , 4 .

Я понимаю, что это может быть достигнуто с VALUES помощью терминов EXCEPT и в sql, и я знаю, что они присутствуют в jOOQ, и я пытался их воспроизвести, однако простой случай, описанный здесь для использования значений, использует статический список (тогда как мой будет предоставлен программно), и я не уверен, что этоявляется причиной или, если это более общий синтаксис. Я не нашел хорошего примера except в jOOQ онлайн.

Что я пробовал:

 List<String> valuesList
  
 create.select()
    .from(values(getRowsFromList(valuesList)))
    .except(select(TABLE.VALUE).from(TABLE))
    .fetch(TABLE.VALUE)
  

значения ожидают RowN объект vararg, поэтому я преобразую значения как таковые

 private RowN[] getRowsFromList(List<String> rows)
{
    return rows.stream().map(DSL::row).toArray(RowN[]::new);
}
  

Ошибка:

 java.lang.IllegalArgumentException: Field ("public"."table"."value") is not contained in Row ("v"."c1")
  

Использование java 11, серверной части postgres 11, jooq 3.13.12

Ответ №1:

В вашем запросе нет table.value столбца. У него даже нет value столбца. При использовании операций set имена прогнозируемых столбцов совпадают с именами первого подзапроса операции set, например:

 SELECT a
FROM (VALUES (1), (2), (3), (4)) AS t (a)
EXCEPT
SELECT value
FROM table
  

В результате создается таблица со столбцом a . Но вы не назвали свой столбец первого EXCEPT подзапроса, поэтому имя не определено (jOOQ и / или PostgreSQL могут создать его, но я бы не стал на это полагаться).

Решение состоит в том, чтобы присвоить вашим столбцам имена, используя производный список столбцов ( AS t (a) синтаксис, который я использовал выше). Это должно исправить ваш запрос:

 create.select()
    .from(values(getRowsFromList(valuesList)).as("t", TABLE.VALUE.getName())
    .except(select(TABLE.VALUE).from(TABLE))
    .fetch(TABLE.VALUE)
  

Комментарии:

1. Это действительно помогло, спасибо (!) — я использовал псевдоним ранее, но я, очевидно, также неправильно понял формат, и это также приводило к ошибкам, поэтому я пытался работать с (как я думал) самой простой версией того, что я хотел. Приветствия!