简体   繁体   English

jdbc java.sql.preparedstatement在插入期间复制行

[英]jdbc java.sql.preparedstatement duplicating rows during insert

I have a program in scala that connects to an oracle database using ojdbc, queries a table, and tries to insert records from the java.sql.resultSet into another table on a separate jdbc connection. 我在scala中有一个程序,它使用ojdbc连接到oracle数据库,查询表,并尝试将java.sql.resultSet中的记录插入到另一个jdbc连接上的另一个表中。

//conn1 to oracle: java.sql.Connection = oracle.jdbc.driver.T4CConnection@698122b2
//conn2 to another non-oracle database: java.sql.Connection = com.snowflake.client.jdbc.SnowflakeConnectionV1@6e4566f1

My attempt at capturing results from an oracle table: 我尝试从oracle表中捕获结果:

val stmt1 = conn1.createStatement()
stmt1.setFetchSize(3000)
val sql1 = "select userid from nex.users"
val result = stmt1.executeQuery(sql1)

and code for attempting to insert records from result to a separate database and table via jdbc: 和尝试通过jdbc将结果中的记录插入到单独的数据库和表中的代码:

val insert_sql = "insert into test.users (userid) values (?)"
val ps = conn2.prepareStatement(insert_sql)
val batchSize = 3000
var count = 0
while (result.next) {
    ps.setInt(1, result.getInt(1))
    ps.addBatch()
    count += 1
    if (count % batchSize == 0) ps.executeBatch()
}

What's stumping me is this is almost the exact same syntax in many examples of using jdbc, but in my second table, I'm seeing 4x the original number of rows from the first table. 令我感到困惑的是,在使用jdbc的许多示例中,这几乎是完全相同的语法,但在我的第二个表中,我看到第一个表中原始行数的4倍。

select userid, count(*) from test.users group by userid


1 4
2 4
3 4
4 4
5 4
6 4
etc

The issue was that I needed to execute ps.clearBatch() after every execute, otherwise the next batch would get piled on top of the previous batch. 问题是我需要在每次执行后执行ps.clearBatch() ,否则下一批将堆积在上一批之上。 When trying this on a large table that would need to call executeBatch more often, the amount of duplicate rows were x times higher. 在需要更频繁地调用executeBatch的大型表上尝试此操作时,重复行的数量是x倍。 The final code looks similar but with ps.clearBatch() . 最终的代码看起来很相似,但有ps.clearBatch()

val ps = conn2.prepareStatement(insert_sql)
val batchSize = 3000
var count = 0
while (result.next) {
    ps.setInt(1, result.getInt(1))
    ps.addBatch()
    count += 1
    if (count % batchSize == 0) 
        ps.executeBatch()
        ps.clearBatch()
}

Yes, clearBatch is missing. 是的,缺少clearBatch。

executeBatch() calls clearBatch() in the end. executeBatch()最后调用clearBatch()。 But there is no guarantee for that will be exactly the same in other implementations. 但是不能保证在其他实现中完全相同。

Also, if needed, I am making a minor-subtle addition to tchoedak's answer :) 此外,如果需要,我正在对tchoedak的答案进行微妙的补充:)

ps.executeBatch();
conn2.commit();
ps.clearBatch(); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java.sql.PreparedStatement 无法转换为 com.mysql.jdbc.PreparedStatement - java.sql.PreparedStatement cannot be converted to com.mysql.jdbc.PreparedStatement com.mysql.jdbc.PreparedStatement包之间的区别是什么? 和java.sql.PreparedStatement? - What is the difference between package com.mysql.jdbc.PreparedStatement; and java.sql.PreparedStatement? java.sql.PreparedStatement 的 setBoolean() 方法 - setBoolean() method of java.sql.PreparedStatement 无法在Java中准备Postgres语句(java.sql.PreparedStatement) - Unable to Prepare a Postgres Statement in Java (java.sql.PreparedStatement) Janino 找不到 java.sql.PreparedStatement 如果 mvn 测试 - Janino cant find java.sql.PreparedStatement if mvn test 类型不匹配:无法从java.sql.PreparedStatement转换为jdbcDemo.PreparedStatement - Type mismatch: cannot convert from java.sql.PreparedStatement to jdbcDemo.PreparedStatement java.sql.Statement或java.sql.PreparedStatement - 带参数的可滚动结果集 - java.sql.Statement or java.sql.PreparedStatement - scrollable resultset with parameters 为什么用getInterfaces()搜索时java.sql.PreparedStatement接口没有出现 - Why java.sql.PreparedStatement interface don't appear when searched with getInterfaces() org.sqlite.jdbc4.JDBC4PreparedStatement.setBinaryStream(JDBC4PreparedStatement.java:96)上的java.sql.SQLFeatureNotSupportedException - java.sql.SQLFeatureNotSupportedException at org.sqlite.jdbc4.JDBC4PreparedStatement.setBinaryStream(JDBC4PreparedStatement.java:96) Java:使用 PreparedStatement 将多行插入 MySQL - Java: Insert multiple rows into MySQL with PreparedStatement
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM