我有一个用Java编写的程序,它解析一组文件,并使用sqlite在数据库中放置有关它们的信息。代码似乎工作正常一段时间,直到有一天我得到这个例外:
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)
事实证明,其中两个文件在我的代码中以某种方式相互干扰。我已经构建了一个较小的程序,仍然会出现同样的问题。
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();
}
}
我当前的maven依赖信息。
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.7.2</version>
</dependency>
所以我做错了什么,为什么这对大多数字符串有效但不是全部?唯一性是否以非直接的方式计算?
答案 0 :(得分:2)
由于您已在id列上应用UNIQUE
约束,因此如果您尝试在 id 列中插入任何现有值,则会出错
答案 1 :(得分:0)
似乎问题与使用错误的数据类型有关,它应该是TEXT而不是STRING。来自sqlite documentation:
请注意,由于“POINT”末尾的“INT”,声明的“FLOATING POINT”类型将赋予INTEGER亲和力,而不是REAL亲和力。声明的“STRING”类型具有NUMERIC的亲和力,而不是TEXT。
因此字符串“111111111E311”将被视为OK数字但是太大而且条目中的内容是NaN。字符串“111111111E211”略小,可以按原样存储。