JOOQ-запрос для предложения JOIN ON WITH

Как я могу написать запрос JOOQ для присоединения к полю из предложения "with"?

Например, я пробовал:

create.with("a").as(select(
                           val(1).as("x"),
                           val("a").as("y")
                   ))
      .select()
      .from(tableByName("a")
      .join(ANOTHER_TABLE)
          .on(ANOTHER_TABLE.ID.eq(tableByName("a").field("x")))
      .fetch();

Однако, поскольку компилятор не знает тип tableByName("a"). Field("x"), он не может определить, какой метод eq() использовать. Учитывая, что я знаю тип, есть ли способ, которым я могу предоставить его явно? Или есть другой подход, который я должен использовать, чтобы присоединиться к полю из предложения "с"?

2 ответа

Решение

Хотя я, безусловно, согласен с тем, что ответ flutter является более желательным путем к решению, я просто быстро добавлю ответ, который отвечает на ваш конкретный вопрос об ошибке компиляции.

Есть три вещи, которые не подходят для вашего текущего предиката соединения:

ANOTHER_TABLE.ID.eq(tableByName("a").field("x"))
  1. DSL.tableByName() устарела. Как правило, рекомендуется использовать table(Name) вместо.
  2. Такой динамически построенный Table не знает ни одного из его field() ссылки, таким образом table(name("a")).field("x") вернусь null
  3. Ошибка компиляции из-за вашего ID ссылка на тип Field<Integer> (вероятно), и, таким образом, Field.eq() метод ожидает Field<Integer> аргумент также. Без каких-либо знаний о типе вашей области "x", выводит jOOQ API / Java компилятор Field<Object>, который является недействительным.

Итак, решение было бы написать:

// field(Name, Class)
ANOTHER_TABLE.ID.eq(field(name("a", "x"), Integer.class))

// field(Name, DataType)
ANOTHER_TABLE.ID.eq(field(name("a", "x"), ANOTHER_TABLE.ID.getDataType()))

Т.е. использовать DSL.field(Name, Class<T>), или же DSL.field(Name, DataType<T>) если вы используете пользовательские привязки / преобразователи типов данных.

Как насчет объявления CTE первым? Явные общие табличные выражения

CommonTableExpression<Record2<Integer, String>> a =
  name("a").fields("x", "y").as(select(val(1), val("a")));

create.with(a)
      .select()
      .from(a)
      .join(ANOTHER_TABLE)
      .on(ANOTHER_TABLE.ID.eq(a.field("x")))
      .fetch();

Если это не работает, вы всегда можете получить DataType<?> или Class<?> через Field, который вы можете получить через Table,

Другие вопросы по тегам