Windows上的SQLite异常,而不是Mac OSX

时间:2012-06-04 13:48:04

标签: sqlite jdbc windows-vista

我正在从Mac OS X开发一个使用JDBC驱动程序的SQLite数据库的Java应用程序。

代码在mac上工作得非常好,但我不能在我的Windows机器上使用PreparedStatement s批量插入。

编辑:这也不适用于包含单Statement条指令的简单INSERT INTOCREATE TABLE正常工作)。

我的代码基本上是:

创建表:

    final String sql = "CREATE VIRTUAL TABLE " + TABLE_NAME + " USING fts3("
            + KEY_NOM + ", "
            + KEY_PRENOM + ", "
            + KEY_ADRESSE + ", "
            + KEY_ADRESSE2 + ", "
            + KEY_ADRESSE3 + ");";

    try {
        final Statement s = mConnection.createStatement();
        s.execute(sql);
    } catch (final SQLException e) {
        L.e("Unable to create table: "+sql+"! "+e);
    }

PreparedStatement创作:

    String sql =
            "INSERT INTO "+TABLE_NAME
                    +" ("
                    + KEY_NOM + ", "
                    + KEY_PRENOM + ", "
                    + KEY_ADRESSE + ", "
                    + KEY_ADRESSE2 + ", "
                    + KEY_ADRESSE3 + ") "
                    + " VALUES (?, ?, ?, ?, ?)";

    mConnection.setAutoCommit(false);
    final PreparedStatement prep = mConnection.prepareStatement(sql);

然后有一个解析CSV文件的循环,并在每一行调用以下代码:

        int i = 1;
        prep.setString(i++, ""+lawyer.nom);
        prep.setString(i++, ""+lawyer.prenom);
        prep.setString(i++, ""+lawyer.adresse);
        prep.setString(i++, ""+lawyer.adresse2);
        prep.setString(i++, ""+lawyer.adresse3);
        prep.addBatch();

当CSV文件的解析结束时,执行以下操作:

        final int[] res = prep.executeBatch();
        mConnection.setAutoCommit(true);
        for (int r: res) {
            if (r != 1) {
                L.e("Error adding entry!");
            }
        }

当我调用mConnection.setAutoCommit(true);时,INSERT语句在引发以下异常时执行:

java.sql.SQLException: SQL logic error or missing database
at org.sqlite.DB.throwex(DB.java:288)
at org.sqlite.DB.exec(DB.java:68)
at org.sqlite.Conn.setAutoCommit(Conn.java:166)

经过测试的环境:

  • MacBookAir - Mac OS 10.6 - x64 - Java 1.6.31 - 正常(我的开发站)
  • 笔记本电脑 - Windows 7 - x64 - Java 1.6.30 - 正常工作
  • MacBook - Mac OS 10.5 - x64 - Java 1.6.26 - 正常工作
  • 桌面 - Windows Vista - x86 - Java 1.? - 无效
  • 服务器 - Windows Server 2003 - 未知的arch,x86猜测 - Java 1.7 - 不起作用
  • 桌面 - Windows 7 - x86 - Java 1.7 - 不起作用
  • 桌面 - Windows XP - x86 - Java 1.6.31 - 不起作用

似乎只有x64主机才能使其正常工作。使用以下罐子:

  • swt:在x64主机上包含x64版本,在x86主机上包含x86版本
  • sqlitejdbc-v056:显然这是x86和x64兼容的
  • opencsv:这不包含本机代码
  • iText-2.1.7和iTextRTF:这不包含本机代码

因此,JDBC SQLite驱动程序可能不完全兼容x86。我会尝试进一步调查。

1 个答案:

答案 0 :(得分:2)

TL; DR
我的SQLite JDBC驱动程序使用本机代码,并不完全兼容32位处理器。

两种可能的修复方法:

  • 使用Xerial,一个可在Mac OS X 64位和Windows 32位上正常运行的本机SQLite JDBC驱动程序
  • 使用纯java实现修复了该问题,但代价是性能。

解释

过去3天我花了很多时间用SQLite异常说“SQL逻辑错误或缺少数据库”。我不会评论包含两个可能的不同的错误的异常文本,而不说哪个可能是原因。我不会评论异常文本中提到的两个错误都不是导致问题的原因。

事实:

  • SQLite异常声明“ SQL逻辑错误或缺少数据库
  • 使用jsqlitejdbc v056
  • 驱动程序可以创建表格
  • 驱动程序可以从表中选择信息
  • 数据库文件未损坏,即。可以使用sqlite客户端打开它并将数据插入表
  • 驱动程序无法将数据插入表格

解决了我的问题的是替换sqlitejdbc-v056.jar,其中包含sqlitejdbc-v056-pure.jar本机代码,这是一个纯java实现。

我希望所有遇到此问题的用户都能快速看到这一点,并且不会因此而失去3天。