SQLITE JDBC 驱动程序准备好的语句失败(内部指针 0)

Posted

技术标签:

【中文标题】SQLITE JDBC 驱动程序准备好的语句失败(内部指针 0)【英文标题】:SQLITE JDBC driver prepared statement fails (internal pointer 0) 【发布时间】:2018-01-25 21:13:07 【问题描述】:

SQLite JDBC 驱动程序版本 3.21.0(最新)。

总结

为一个表上的多个插入操作打开了一个准备好的语句,但无法在违反主键的情况下存活。

如果由于违反主键而导致一次“坏”插入失败,则准备好的语句无法处理后续“好”插入。调用 pstmt.setString() 时引发异常“语句未执行”。

将错误跟踪到 org.Sqlite.core.CorePreparedStatement 调用在 checkOpen() 指针==0 中失败。

示例如下。

有人知道为什么会这样吗?我看到一个类似的bug report 被提出但据说是固定的。

Connection conn = DriverManager.getConnection("jdbc:sqlite:./test.db");
String createtable = "CREATE TABLE dummy(ID text, VAL text, PRIMARY KEY(ID) )";
String psSQL       = "INSERT INTO dummy (ID, VAL) VALUES (?,?)";
String id = "123456789";
String val = "FooBar";
String id2 = "123456789";
String val2 = "FooBar2";
String id3 = "345678901";
String val3 = "FooBar3";

try 
    Statement st= conn.createStatement();
    st.executeUpdate(createtable);
    PreparedStatement pst = conn.prepareStatement(psSQL);

    // 1 insert good entry
    pst.setString(1, id);
    pst.setString(2, val);
    pst.executeUpdate();
    System.out.println("1st insert OK for " + id);

    // 2. try to insert bad duplicate entry with pkey violation
    try 
        pst.setString(1, id);
        pst.setString(2, val);
        pst.executeUpdate();
        System.out.println("2nd insert OK for " + id);
     catch (SQLException e) 
        System.out.println("2nd insert Failed for " + id);
        e.printStackTrace();
    

    // 3. try to insert 3rd good value
    try 
        pst.setString(1, id3);      // exception raised here
        pst.setString(2, val3);
        pst.executeUpdate();
        System.out.println("3 insert OK for " + id3);
     catch (SQLException e) 
        System.out.println("3 insert Failed for " + id3);
        e.printStackTrace();
    

    pst.close();
    st.executeUpdate(droptable);

 catch (SQLException e) 
    e.printStackTrace();
 

【问题讨论】:

为什么要问这个问题而不是提交错误报告? 错误报告添加到已知问题 #74 github.com/xerial/sqlite-jdbc/issues/74 【参考方案1】:

此错误已在 sqlite-jdbc 版本 3.25.2修复,请参阅 https://github.com/xerial/sqlite-jdbc#news。

【讨论】:

以上是关于SQLITE JDBC 驱动程序准备好的语句失败(内部指针 0)的主要内容,如果未能解决你的问题,请参考以下文章

JDBC驱动程序为准备好的语句转义参数?

mssql-jdbc MS SQL Server JDBC 驱动程序准备好的语句缓存性能问题与 Hikari CP

通过 jdbc 通过准备好的语句传递 SQL 命令时出错

更新语句的 JDBC 占位符限制的解决方法失败

如何在 Android sqlite 中使用准备好的语句? [复制]

使用 neo4j jdbc 驱动程序和 neo4j 4 准备好的语句中的密码查询参数的语法是啥?