【问题标题】:How to build Insert into with select statement that uses constant values using JOOQ Query Builder如何使用 JOOQ Query Builder 使用常量值的 select 语句构建 Insert into
【发布时间】:2019-02-05 20:25:52
【问题描述】:

我有一个插入语句,它正在插入一些常量值,它需要通过查找从其他表中选择一些引用键。查询看起来像这样。

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 查询生成器代码如下所示

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>>

不知何故,当我在选择返回类型中使用内联时,选择更改为 SelectConditionStep 而不是 Select。

有解决这个问题的线索吗?

【问题讨论】:

    标签: java postgresql jooq


    【解决方案1】:

    编译器推断SelectConditionStep 的事实在这里无关紧要,因为它是Select 的子类型,因此对于INSERT .. SELECT 语句是完全可以接受的。问题是,当在 insertInto() 子句中使用纯 SQL 并且不提供任何列数据类型时,编译器将为每个单独的列推断 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();
    

    或者更好的是,使用代码生成器,在这种情况下,所有这些都会自动为您完成,提高可读性。

    【讨论】:

    • 其实我在发帖一段时间后就明白了,感谢您的及时回答
    猜你喜欢
    • 1970-01-01
    • 2012-10-18
    • 2017-11-09
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多