提问人:kocakmo 提问时间:11/5/2023 最后编辑:kocakmo 更新时间:11/6/2023 访问量:61
如何使用jooq更新插入记录?
How to Upsert records with jooq?
问:
我正在尝试将从数据库的一个表中检索到的行更新插入到另一个数据库中的相同表。这两个数据库都是 postgresql。
我只想将表行的整列作为记录检索,然后简单地将其更新插入到另一个数据库中的表中。
我写了以下代码:
try {
String sourceDbUrl = "jdbc:postgresql://localhost:5432/sourcedb";
String sourceDbUsername = "postgres";
String sourceDbPassword = "admin";
Connection sourceConnection = DriverManager.getConnection(sourceDbUrl, sourceDbUsername, sourceDbPassword);
Configuration sourceConfig = new DefaultConfiguration().set(sourceConnection).set(SQLDialect.POSTGRES);
String targetDbUrl = "jdbc:postgresql://localhost:5432/targetdb";
String targetDbUsername = "postgres";
String targetDbPassword = "admin";
Connection targetConnection = DriverManager.getConnection(targetDbUrl, targetDbUsername, targetDbPassword);
Configuration targetConfig = new DefaultConfiguration().set(targetConnection).set(SQLDialect.POSTGRES);
String sourceSchema = "public";
String targetSchema = "public";
Table<Record> sourceTable = DSL.table(DSL.name(sourceSchema, "mytable"));
Table<Record> targetTable = DSL.table(DSL.name(targetSchema, "mytable"));
DSLContext sourceDslContext = DSL.using(sourceConfig);
DSLContext targetDslContext = DSL.using(targetConfig);
String customSelectQuery = "SELECT * FROM " + sourceSchema + ".mytable";
Result<Record> records = sourceDslContext.fetch(customSelectQuery);
for (Record record : records)
targetDslContext
.insertInto(targetTable)
.set(record)
.onDuplicateKeyUpdate()
.set(record)
.execute();
} catch (Exception e) {
e.printStackTrace();
}
我可以看到我已成功检索记录。
但是,不知何故,记录值在 for 循环中由 jooq 创建的 upsert 查询中为空,我得到了以下异常:
org.jooq.exception.DataAccessException:SQL [插入到“public”中。mytable“ 值 () on conflict ([unknown primary key]) do update set [ no fields are updated ]];ERROR:在“)”处或附近出现语法错误 排名:40 在 org.jooq_3.16.1.POSTGRES.debug(来源不明) 在org.jooq.impl.Tools.translate(Tools.java:3089) 在 org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:670) 在org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:349) 在 org.jooq.impl.AbstractDelegatingQuery.execute(AbstractDelegatingQuery.java:115) 在 Main.main(Main.java:48) 原因:org.postgresql.util.PSQLException:错误:语法错误在“)”或附近 排名:40 在 org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2552) 在 org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2284) 在 org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:322) 在 org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:481) 在 org.postgresql.jdbc.PgStatement.execute(PgStatement.java:401) 在 org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:164) 在 org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:153) 在 org.jooq.tools.jdbc.DefaultPreparedStatement.execute(DefaultPreparedStatement.java:219) 在org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:414) 在 org.jooq.impl.AbstractDMLQuery.execute(AbstractDMLQuery.java:961) 在 org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:335) ...另外 2
感谢您的评论。
谢谢
答:
这篇关于为什么应该使用 jOOQ 和代码生成的文章解释了为什么你会遇到这个问题。简而言之,如果没有附加到表的主/唯一键元数据,jOOQ 就无法在 PostgreSQL 方言上模拟 MySQL 子句。ON DUPLICATE KEY UPDATE
但话又说回来,为什么要使用它呢?您使用的是 PostgreSQL,并且 jOOQ 对 PostgreSQL 的子句(或者也适用于更复杂的情况)提供了本机支持,因此请改用本机语法。ON CONFLICT
MERGE
评论
TableImpl
评论