我正在尝试将从数据库的一个表检索到的行更新插入到另一个数据库中的相同表中。两个数据库都是 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();
}
我可以看到我成功检索了记录。
但是,不知何故,记录值在由 jooq 在 for 循环内创建的 upsert 查询中发送为空,并且出现以下异常:
org.jooq.exception.DataAccessException:SQL [在冲突([未知主键])时插入“public”。“mytable”值()执行更新集[没有更新任何字段]];错误:“)”处或附近的语法错误 位置: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
)提供本机支持,因此请改用本机语法。