Jooq的INSERT…ON CONFLICT DO UPDATE…RETURNING语句不会返回值或捕获数据库异常。

huangapple go评论76阅读模式
英文:

Jooq INSERT...ON CONFLICT DO UPDATE...RETURNING doesn't return value or catch the database exception

问题

使用 Jooq 3.13.5,PostgreSQL 10。

期望的是,如果数据库表中不存在该行,则插入查询将插入该行,并返回 id 列。

表格:

CREATE descriptor_table (
id serial primary key,
name text unique
);

工作中的 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。

英文:

Using Jooq 3.13.5, Postgresql 10.

The expectation is that the insert query will insert the row into the database table if it doesn't already exist and return the id column regardless.

Table:

CREATE descriptor_table (
id serial primary key,
name text unique
);

Working SQL query:

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

Java code:

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();
}

The resulting MyRecord value is null.

答案1

得分: 3

你的字符串 "EXCLUDED.name" 只是一个字符串绑定变量,而不是表达式。这与将 NAME 列设置为例如 "Mike" 或类似于你的另一个绑定变量 "a name" 没有任何区别。

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

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

请注意,你的jOOQ查询有一个 where() 子句,而你的SQL查询却没有...

英文:

Your string "EXCLUDED.name" is just a string bind variable, not an expression. It's no different from setting the NAME column to e.g. "Mike" or like your other bind variable "a name".

If you want a plain SQL expression, use DSL.field(String, DataType) or a similar overload:

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

Note that your jOOQ query has a where() clause, unlike your SQL query...

huangapple
  • 本文由 发表于 2020年10月23日 03:44:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/64489471.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定