英文:
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...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论