2015-10-04 2 views
4

У меня есть таблица PERSON с более чем 5 миллионами строк, и мне нужно обновить поле NICKNAME на каждом из них на основе поля NAME внутри той же таблицы.UpdateString не реализован драйвером SQLite JDBC

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(); 
} 

Но я получил эту ошибку:

not implemented by SQLite JDBC driver

Я использую SQLite-JDBC-3.8.11.2.jar загруженный на https://bitbucket.org/xerial/sqlite-jdbc/downloads.

Я знаю, что я мог бы использовать следующий SQL-запрос:

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

Но это будет длиться вечно, и я понимаю, обновление ResultSet будет быстрее. Итак, какие параметры мне нужно обновить по самым быстрым способом? Доступен любой другой драйвер? Должен ли я покинуть Java?

UPDATE

Я был в состоянии найти быстрое решение, используя ниже синтаксисом. Блок между CASE и END был конкатенированной строкой, которую я создал перед выполнением 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) 
+0

Возможно, посмотрите на использование пакета: http://stackoverflow.com/questions/14264953/how-is-jdbc-batch-update-helpful – tim

+1

Возможно ли, что прокси-псевдоним может выполняться в SQL, а не в Java? Тогда инструкция обновления будет намного быстрее. – RealSkeptic

+1

Почему вы говорите «что бы навсегда»? Как вы думаете, 'updateRow()' делает (на драйверах JDBC, которые его поддерживают)? Оба отправили бы SQL-запрос 'UPDATE' SQL на сервер.Подготовка инструкции 'UPDATE' и ее пакетная обработка на самом деле будет * лучше * для производительности, потому что' updateRow() 'is * not * пакет. – Andreas

ответ

3

Как вы столкнулись, драйвер JDBC SQLite в настоящее время не поддерживает updateString операцию. Это можно увидеть в the source code для этого драйвера.

я могу думать о трех вариантах:

  1. Как указано в вашем вопросе, вы можете выбрать имя и идентификатор человека, а затем обновить лицо по его ID. Эти обновления могут быть сделаны в пакете (с использованием PreparedStatement.addBatch()) для повышения производительности (tutorial).
  2. Внесите метод myparsingfunction в чистый SQL, чтобы запрос мог стать 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 будет быстрее, но это не может быть жизнеспособным решением). Вы должны проверить каждое решение, чтобы найти тот, который вам подходит.

Смежные вопросы