SQLIntegrityConstraintViolationException由于重复键值

时间:2015-09-05 19:04:14

标签: java sql jdbc

尝试使用下面的代码将新闻行插入数据库表时,我收到了完整性约束违规错误。

public void ExtractBoard() throws IOException, SQLException {
    int rows = 0;
    String sqlInser = "INSERT INTO APP.SUBSCRIBERBR (subID, boardno)"+"VALUES (?,?)";
    PreparedStatement  stmt = conn.prepareStatement(sqlInser, Statement.RETURN_GENERATED_KEYS);
    String[] AryFiles2 = rf.OpenFile();
    int i,j;
    String p1 = "", p2 = "";
    for (i=0; i<AryFiles2.length; i++) {
        if (AryFiles2[i].contains("ADD VSBR")) {
            String[][] parts = this.LineParts();
            Scanner in = new Scanner(parts[i][0]).useDelimiter("[^0-9]+");
            int intst = in.nextInt();
            p1 = String.valueOf(intst);
            for (j=0; j<parts[1].length; j++) {
               if (parts[i][j].contains("MN")) {
                   Scanner inn = new Scanner(parts[i][j]).useDelimiter("[^0-9]+");
                   int intstr = inn.nextInt();
                   p2 = String.valueOf(intstr); 

               }
           }
       }
       if(p1 != null && p2 != null){
           stmt.setString(1, p1);
           stmt.setString(2,p2);
           rows = stmt.executeUpdate();
       }
       else {
           throw new SQLException("Null parameters");
       }
   }
}

这是我收到的错误消息。

  

java.sql.SQLIntegrityConstraintViolationException:语句已中止,因为它会导致唯一或主键约束或由&#39; SQL150827011836400&#39;标识的唯一索引中的重复键值。定义于&SUBSCRIBERBR&#39;。

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

您的subID变量似乎是重复的。 (表中有另一个具有相同子ID的记录)

可能的原因是:

  1. 您的文件读取方法有问题,最终导致输入文件读错。

  2. 您的输入文件已包含重复的密钥。

  3. 一切正常,但是您尝试在不先清理它的情况下针对同一个数据库运行代码,因此您最终会找到上次运行时使用此子ID的记录。

答案 1 :(得分:0)

您从未将p1p2设置为null,因此如果第一次迭代时if语句为false,则插入"", "",如果{{1}在后续迭代中,如果语句为false,则插入与前一次迭代相同的相同的值。

答案 2 :(得分:0)

我认为你读错了int,所以你最终得到了错误的值并生成了重复的键,这违反了约束。

您的主要密钥来自parts[i][0]i从0开始)行:

Scanner in = new Scanner(parts[i][0]).useDelimiter("[^0-9]+");

但为什么你的第二个sql参数使用相同的值? p2在行

处设置为parts[i][j]
Scanner inn = new Scanner(parts[i][j]).useDelimiter("[^0-9]+");

(记住:j也以0开头)见

for (j=0; j<parts[1].length; j++) {

所以你读了parts[i][0]两次。

第二个问题可能是for循环变量j的上限:你将它设置为parts[1].length。不应该这部分[i] .length?

你怎么解决?查看您的值p1p2,也许您可​​以记录它。这些是您所期望的价值吗? 你有哪些限制?只有主键或boardno是否也有约束或唯一索引(参见错误消息)?

您可以尝试这样的事情:

try {
   rows = stmt.executeUpdate();
} catch (Exception e) {
   logger.error("p1="+p1+" p2="+p2+" catched="+e);
}