首页 > 解决方案 > Jooq INSERT...ON CONFLICT DO UPDATE...RETURNING 不返回值或捕获数据库异常

问题描述

使用 Jooq 3.13.5、Postgresql 10。

期望是插入查询将在该行不存在的情况下将其插入到数据库表中,并且无论如何都返回id列。

桌子:

CREATE descriptor_table(id 序列主键,名称文本唯一);

工作 SQL 查询:

INSERT INTO descriptor_table (name)
  VALUES('a name')
ON CONFLICT("name")
  DO UPDATE SET name=EXCLUDED.name
RETURNING id;

Java代码:

DSLContext dsl = jooqProvider.getDSLContext();
dsl.transaction(configuration -> {
  MyRecord                                                             
      idValue =                                                              
      DSL.using(configuration)                                                 
         .insertInto(DESCRIPTOR_TABLE)                                               
         .set(DESCRIPTOR_TABLE.NAME, "a name")                            
         .onConflict(Keys.DESCRIPTOR_TABLE_NAME_KEY.getFieldsArray())                
         .doUpdate()                                                           
         .set(DESCRIPTOR_TABLE.NAME, "EXCLUDED.name")                                
         .where(DESCRIPTOR_TABLE.NAME.eq("a name")))                       
         .returning(DESCRIPTOR_TABLE.ID)                                             
         .fetchOne();
}

生成的 MyRecord 值为 null。

标签: javapostgresqljooqpostgresql-10

解决方案


您的字符串"EXCLUDED.name"只是一个字符串绑定变量,而不是表达式。NAME这与将列设置为 eg"Mike"或 like your other bind variable没有什么不同"a name"

如果您想要一个普通的 SQL表达式,请使用DSL.field(String, DataType)或类似的重载:

.set(DESCRIPTOR_TABLE.NAME, field("EXCLUDED.name", DESCRIPTOR_TABLE.NAME.getDataType()))

请注意,您的 jOOQ 查询有一个where()子句,与您的 SQL 查询不同...


推荐阅读