【发布时间】:2016-09-21 12:08:17
【问题描述】:
我不断收到此错误:
Error code 20000, SQL state 23505
Insert command failed: The statement was aborted because it would have caused a duplicate key value in a unique or primary key constraint or unique index identified by 'SQL160524112023610' defined on 'TEST'.
当我运行这段代码时:
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DerbyBatch {
private static Connection connection;
public static void main(String args[]) {
try {
createDatabase();
createTable();
insertBatch();
} catch (ClassNotFoundException | SQLException ex) {
Logger.getLogger(DerbyBatch.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void createDatabase() throws SQLException {
connection = DriverManager.getConnection("jdbc:derby:" + new File("test").getAbsolutePath() + ";" + "create=true");
disconnect();
}
public static void createTable() throws ClassNotFoundException, SQLException {
connect();
String createTable = "CREATE TABLE \"APP\".\"TEST\" (ID INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), TEXT VARCHAR (30000) NOT NULL, PRIMARY KEY (ID))";
PreparedStatement preparedStatement = connection.prepareStatement(createTable);
preparedStatement.executeUpdate();
preparedStatement.close();
connection.commit();
disconnect();
}
public static void insertBatch() throws SQLException, ClassNotFoundException {
connect();
String sql = "INSERT INTO TEST (ID, TEXT) VALUES (?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 1);
preparedStatement.setString(2, "TEST");
preparedStatement.addBatch();
preparedStatement.executeBatch();
connection.commit();
disconnect();
Logger.getLogger(DerbyBatch.class.getName()).log(Level.SEVERE, "All data inserted.");
}
public static void connect() throws ClassNotFoundException, SQLException {
Class.forName("net.sf.log4jdbc.DriverSpy");
Connection temp = DriverManager.getConnection("jdbc:log4jdbc:derby:" + new File("test").getAbsolutePath());
connection = new net.sf.log4jdbc.ConnectionSpy(temp);
connection.setAutoCommit(false);
}
public static void disconnect() throws SQLException {
connection.close();
}
}
然后尝试在netbeans服务选项卡->数据库中手动插入一条记录:
我确保所有内容都已提交并且连接已正确关闭,所以我不确定为什么 derby 在执行批量插入后不断拾取重复索引?
【问题讨论】:
-
我认为每次插入相同的 ID,这是您的主键。
-
无法用给定的代码重现问题。
-
@Moh-Aw:我的德比版本是10.10.1.1,log4jdbc是1.2,slf4j-api是1.7.21,slf4j-log4j12是1.7.21
-
如果您自己插入 ID,Derby 将使用您插入的内容,它不会生成 ID。这就是
GENERATED BY DEFAULT的意思。如果您希望 Derby 生成 ID,那么您应该使用GENERATED ALWAYS,并且永远不要自己提供 ID,或者如果您想使用GENERATED BY DEFAULT,那么您需要NOT 提供 ID如果您希望 Derby 为您生成它。 IOW,GENERATED BY DEFAULT的意思是:“只有在我自己不插入 ID 时才生成 ID”。 -
不要在这里发布文字图片,尤其是您已经发布了文字。
标签: java netbeans prepared-statement derby embedded-database