Как встроить оператор Insert в оператор select, использующий постоянные значения, с помощью JOOQ Query Builder - PullRequest
0 голосов
/ 30 августа 2018

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

Insert into repository.buffer (
    b_external_id,
    b_buffer_type_id,
    b_entrypoints,
    b_site_id,
    b_state,
    b_uri)
select '100A',bt_id,'["/locations/100A"]'::jsonb,s_id,'ready','/buffers/100A'
from  repository.site, repository.buffer_type
where s_name = 'bar'
and bt_external_id = 'FOO';

Мой код JOOQ Query Builder выглядит следующим образом

dslContext
            .insertInto(
                table("repository.buffer"),
                field("b_external_id"),
                field("b_buffer_type_id"),
                field("b_entrypoints"),
                field("b_site_id"),
                field("b_state"),
                field("b_uri"))
            .select(select(
                    inline(null, String.class),
                    field("bt_id"),
                    inline(null, Object.class),
                    field("s_id"),
                    inline(null, String.class),
                    inline(null, String.class))
                    .from(table("repository.site"), table("repository.buffer_type"))
                    .where(field("s_name").eq(cast(null, String.class)))
                    .and(field("bt_external_id").eq(cast(null, Integer.class))))
                .onConflict().doNothing()
            .getSQL();

Этот оператор не компилируется со следующей ошибкой

Error:(98, 25) java: incompatible types: org.jooq.SelectConditionStep<org.jooq.Record6<java.lang.String,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.String,java.lang.String>> cannot be converted to org.jooq.Select<? extends org.jooq.Record6<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object>>

Каким-то образом, как только я использую inline в возвращаемом типе select, select меняет SelectConditionStep вместо Select.

Любой ключ, чтобы решить эту проблему?

1 Ответ

0 голосов
/ 31 августа 2018

Тот факт, что компилятор выводит SelectConditionStep, здесь не имеет значения, поскольку он является подтипом Select и, как таковой, полностью приемлем для оператора INSERT .. SELECT. Проблема заключается в том, что при использовании простого SQL в предложении insertInto() и отсутствии каких-либо типов данных столбца компилятор выведет Object для каждого отдельного столбца вместо String.

Помните, что jOOQ - это очень строго типизированный API, и это в основном помогает вам правильно понимать SQL. В вашем конкретном случае убедитесь, что вы указали тип данных для каждой ссылки на столбец:

dslContext
    .insertInto(
        table("repository.buffer"),
        field("b_external_id", String.class), // Change here
        field("b_buffer_type_id"),
        field("b_entrypoints", Object.class), // Change here
        field("b_site_id"),
        field("b_state", String.class), // Change here
        field("b_uri", String.class)) // Change here
    .select(select(
            inline(null, String.class),
            field("bt_id"),
            inline(null, Object.class),
            field("s_id"),
            inline(null, String.class),
            inline(null, String.class))
            .from(table("repository.site"), table("repository.buffer_type"))
            .where(field("s_name").eq(cast(null, String.class)))
            .and(field("bt_external_id").eq(cast(null, Integer.class))))
        .onConflict().doNothing()
    .getSQL();

Или, что еще лучше, используйте генератор кода, в случае которого все это будет выполнено автоматически, улучшая читабельность.

...