sqlite 准备语句完成 [英] sqlite preparedstatement finalized

查看:65
本文介绍了sqlite 准备语句完成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个错误
java.sql.SQLException: 准备好的语句已经完成
当我第二次调用同一个 prepareStatement 时会发生这种情况.我在一个方法中调用它.

I have an error of
java.sql.SQLException: The prepared statement has been finalized
which happens when I call the same preparedStatement a second time. I am calling it in a method.

这里是数据库Java类(相关部分)

Here is the database Java class (the relevant piece)

//create the charge table. (ps is PreparedStatement)
try{
   statement.executeUpdate("CREATE TABLE charge(username TEXT NOT NULL, date DATETIME DEFAULT CURRENT_TIMESTAMP, charge REAL, PRIMARY KEY(username, date));");
} catch (SQLException ex) {
   System.out.println("charge table creation failed. exception" + ex);
}

产生费用的方法:

 public void createCharge(String username, double amount){
    try {
        System.out.println(username + amount);

        ps = connection.prepareStatement("INSERT INTO charge VALUES(?, ?, ?);");
        ps.setString(1, username);
        ps.setDate(2, DateConvert.toSQLDate(Date.valueOf(LocalDate.MIN)));
        ps.setDouble(3, amount);
        ps.executeUpdate();
        ps.clearParameters();

        System.out.println("Complete");

    } catch (SQLException ex) {
        Logger.getLogger(MontsRentalDatabase.class.getName()).log(Level.SEVERE, null, ex);
    }
}

这是在创建电荷的类中:

This is in the class where the charge is created:

public void createCharge(String username, double amount){
    try {
        System.out.println(username + amount);

        ps = connection.prepareStatement("INSERT INTO charge VALUES(?, ?, ?);");
        ps.setString(1, username);
        ps.setDate(2, DateConvert.toSQLDate(Date.valueOf(LocalDate.MIN)));
        ps.setDouble(3, amount);
        ps.executeUpdate(); //Line 170
        ps.clearParameters();

        System.out.println("Complete");

    } catch (SQLException ex) {
        Logger.getLogger(MontsRentalDatabase.class.getName()).log(Level.SEVERE, null, ex);
    }
}

将普通日期转换为sqldate的类:公共类 DateConvert {

The class that converts a normal date to sqldate: public class DateConvert {

public static java.sql.Date toSQLDate(java.util.Date date){
    return new java.sql.Date(date.getTime());
}

public static java.util.Date toJavaDate(java.sql.Date date){
    return new java.util.Date(date.getTime());
}
}

错误在create charge的第170行,也就是ps.executeUpdate运行的时候.第一次运行成功,第二次失败.日志:

The error is in line 170 of create charge, which is when ps.executeUpdate runs. It runs successful the first time, fails on the second. Log:

450100.0
Complete
450150.0
SEVERE: null
java.sql.SQLException: The prepared statement has been finalized
    at org.sqlite.core.NativeDB.throwex(NativeDB.java:429)
    at org.sqlite.core.NativeDB.reset(Native Method)
    at org.sqlite.core.DB.executeUpdate(DB.java:878)
    at org.sqlite.jdbc3.JDBC3PreparedStatement.executeUpdate(JDBC3PreparedStatement.java:99)
at server.RentalDatabase.createCharge(RentalDatabase.java:170)

感谢您的帮助,J

推荐答案

我认为这是 SQLite JDBC 驱动程序 3.14.2.1 版本中的一个错误.

I believe that this is a bug in version 3.14.2.1 of the SQLite JDBC driver.

在我看来,您收到了一个独特的约束冲突异常,但 SQLite JDBC 驱动程序在尝试报告此异常时被自身绊倒,而引发了其他一些异常.

It seems to me that you're getting a unique constraint violation exception, but the SQLite JDBC driver is tripping over itself attempting to report this exception and some other exception is getting thrown instead.

如果我尝试多次插入相同的数据,我可以使用 sqlite-jdbc 版本 3.14.2.1 重现您的异常,例如通过重新运行您的代码.我将 SQLite JDBC 驱动程序降级到 3.8.11.2,运行您的代码后出现以下异常:

I was able to reproduce your exception using sqlite-jdbc version 3.14.2.1 if I tried to insert the same data multiple times, e.g. by re-running your code. I downgraded the SQLite JDBC driver to 3.8.11.2 and I got the following exception after running your code:

java.sql.SQLException: [SQLITE_CONSTRAINT]  Abort due to constraint violation (UNIQUE constraint failed: charge.username, charge.date)
    at org.sqlite.core.DB.newSQLException(DB.java:890)
    at org.sqlite.core.DB.newSQLException(DB.java:901)
    at org.sqlite.core.DB.execute(DB.java:810)
    at org.sqlite.core.DB.executeUpdate(DB.java:847)
    at org.sqlite.jdbc3.JDBC3PreparedStatement.executeUpdate(JDBC3PreparedStatement.java:86)
    at com.example.MontsRentalDatabase.createCharge(MontsRentalDatabase.java:40)
    at com.example.Main.main(Main.java:17)

当然,当重新运行程序时,我尝试插入的数据已经在表中了.因此,唯一的约束违反是可以预料的.

Of course, when re-running the program, the data I'm trying to insert is in the table already. So a unique constraint violation is to be expected.

然后我添加了该行

        statement.execute("DROP TABLE IF EXISTS charge");

createChargeTable(),位于创建表格的行上方.然后代码使用任一版本的 SQLite JDBC 驱动程序成功运行了多次.

to createChargeTable(), above the line that creates the table. The code then ran successfully multiple times using either version of the SQLite JDBC driver.

此错误现已在 sqlite-jdbc 3.15.1 版中修复,因此修复是升级到此版本或更高版本.

This bug has now been fixed in sqlite-jdbc version 3.15.1, so the fix is therefore to upgrade to this version or later.

这篇关于sqlite 准备语句完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆