【问题标题】:UpdateString not implemented by SQLite JDBC driverSQLite JDBC 驱动程序未实现 UpdateString
【发布时间】:2016-01-01 05:04:26
【问题描述】:

我有一个表 PERSON 超过 500 万行,我需要根据同一表中的字段 NAME 更新每个表的字段 NICKNAME

ResultSet rs = statement.executeQuery("select NAME from PERSON");
while(rs.next())
{
    // some parsing function like:
    // Nickname = myparsingfunction(rs.getString("NAME"));
    rs.updateString( "NICKNAME", Nickname );
    rs.updateRow();
}

但是我收到了这个错误:

SQLite JDBC 驱动没有实现

我正在使用在 https://bitbucket.org/xerial/sqlite-jdbc/downloads 下载的 sqlite-jdbc-3.8.11.2.jar。

我知道我可以使用以下 SQL 查询:

statement.executeUpdate("update PERSONS set NICKNAME = Nickname where ID = Id");

但这需要很长时间,我知道更新ResultSet 会更快。那么我必须以最快的方式更新表格吗?有其他可用的驱动程序吗?我应该离开 Java 吗?

更新

我能够使用以下语法找到一个快速的解决方案。 CASEEND 之间的块是我在执行 SQL 查询之前构建的连接字符串,因此我可以一次发送所有更新。

update  PERSON
set     NICKNAME= case ID                        
                        when 173567 then 'blabla'
                        when 173568 then 'bleble'
                        ...
                        when 173569 then 'blublu'
                    end
where ID in (173567, 173568, 173569)

【问题讨论】:

  • 也许考虑使用批处理:stackoverflow.com/questions/14264953/…
  • 昵称解析可以用SQL而不是Java吗?那么更新语句会快很多。
  • 你为什么说“那将永远需要”?你认为updateRow() 做了什么(在支持它的 JDBC 驱动程序上)?两者都会向服务器发送UPDATE SQL 语句。准备UPDATE 语句并将它们批处理实际上会更好 提高性能,因为updateRow() 没有 批处理。

标签: java sqlite jdbc


【解决方案1】:

如您所见,SQLite JDBC 驱动程序目前不支持updateString 操作。这可以在此驱动程序的the source code 中看到。

我能想到三个选项:

  1. 正如您在问题中所述,您可以选择此人的姓名和 ID,然后通过其 ID 更新此人。这些更新可以批量完成(使用PreparedStatement.addBatch())以提高性能(tutorial)。
  2. 在纯SQL中实现myparsingfunction方法,这样查询就可以变成UPDATE PERSONS SET NICKNAME = some_function(NAME)
  3. 创建一个用户定义的函数(使用org.sqlite.Function),用Java 实现,并在SQL 中调用它。示例,取自this answer

    Function.create(db.getConnection(), "getNickName", new Function() {
        protected void xFunc() throws SQLException {
            String name = value_text(0);
            String nickName = ...; // implement myparsingfunction here
            result(nickName);
        }
    });
    

    并像这样使用它:UPDATE PERSONS SET NICKNAME = getNickName(NAME);

SQLite does not support stored procedures 所以该选项不在表中。

我不确定这些选项中的哪一个会提供最佳性能(当然使用纯 SQL 会更快,但这可能不是一个可行的解决方案)。您应该对每个解决方案进行基准测试,以找到适合您的解决方案。

【讨论】:

    猜你喜欢
    • 2017-11-13
    • 2016-08-18
    • 2019-09-17
    • 2014-07-30
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 2014-09-11
    相关资源
    最近更新 更多