简体   繁体   中英

java.sql.SQLException: column id is not unique

I have a program written in Java which parses a set of files and places information about them inside a database using sqlite. The code seems to work fine for a while until one day I get this Exception:

Exception in thread "main" java.sql.SQLException: column id is not unique
at org.sqlite.DB.throwex(DB.java:370)
at org.sqlite.DB.executeBatch(DB.java:302)
at org.sqlite.PrepStmt.executeBatch(PrepStmt.java:93)
at DatabaseTest.main(DatabaseTest.java:43)

As it turned out, two of the files were somehow interfering with each other in my code. I have constructed a smaller program which still gives the same problem.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

public class DatabaseTest {

public static void main(String[] args) throws SQLException {
    System.out.println(new org.sqlite.JDBC().toString());
    Connection conn = DriverManager.getConnection("jdbc:sqlite:my_file.sqlite");
    Statement stat = conn.createStatement();
    try {
        stat.executeUpdate("drop table if exists my_table;");
        stat.executeUpdate("create table my_table (id STRING UNIQUE, content STRING);");

        PreparedStatement prep = conn.prepareStatement("insert into my_table values (?, ?);");

        prep.setString(1, "0325E498"); // I keep this value same for all tests
        prep.setString(2, "test1");
        prep.addBatch();

        //prep.setString(1, "0336E810"); // Gives error
        //prep.setString(1, "0336E8100"); // Gives error
        //prep.setString(1, "0336E8100000"); // Gives error
        //prep.setString(1, "0336E8111111"); // Gives error
        //prep.setString(1, "1336E811"); // Gives error
        //prep.setString(1, "9336E811"); // Gives error
        //prep.setString(1, "A336E811"); // OK!
        //prep.setString(1, "111111111E811"); // Gives error
        prep.setString(1, "111111111E311"); // Gives error
        //prep.setString(1, "111111111E211"); // OK!
        prep.setString(2, "test2");
        prep.addBatch();

        conn.setAutoCommit(false);
        prep.executeBatch();  // Exception thrown here
        conn.setAutoCommit(true);
    } finally {
        stat.close();
        conn.close();
    }
}

My current maven dependency information.

<dependency>
    <groupId>org.xerial</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>3.7.2</version>
</dependency>

So am I doing something wrong and why does this work for most strings but not all? Is the uniqueness calculated in a non straightforward manner?

既然你已经应用UNIQUE的ID列约束,如果你尝试插入列ID的任何现有值,它会给错误

It seems like the issue was related to using the wrong datatype, it should have been TEXT instead of STRING. From sqlite documentation :

Note that a declared type of "FLOATING POINT" would give INTEGER affinity, not REAL affinity, due to the "INT" at the end of "POINT". And the declared type of "STRING" has an affinity of NUMERIC, not TEXT.

So the string "111111111E311" will be considered an OK number but is too large and what's put in the entry is NaN. The string "111111111E211" is slightly smaller and can be stored as it is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM