Использование WHERE NOT EXISTS с фиктивной таблицей, не работающей в базе данных Apache Derby - PullRequest
2 голосов
/ 09 января 2012

Поэтому я использую Java с Apache Derby и пытаюсь вставить запись, но только если запись с таким же ключом еще не существует, потому что все значения, которые я хочу, существуют в моем коде, а не вбаза данных, в которой я использую фиктивную таблицу derbys (аналог DUAL для db2), это запрос, который я использую (md5 - это первичный ключ)

PreparedStatement stmt = conn.prepareStatement("INSERT INTO artwork (md5,image) " +
               "SELECT ?,?" +
               "FROM SYSIBM.SYSDUMMY1 " +
               "WHERE NOT EXISTS ( SELECT 1 FROM artwork WHERE md5=?)");

    stmt.setString(1, key);
    stmt.setBinaryStream(2, new ByteArrayInputStream(imageData), imageData.length);
    stmt.setString(3, key);

, и, похоже, он работает, когда яПоток кода, чтобы два потока могли пытаться вставить одну и ту же иллюстрацию, я получаю ошибки get при вводе повторяющегося значения в индекс.

Если я синхронизирую метод так, чтобы только один поток мог вызывать метод одновременно, то я не получаю таких ошибок, но это сводит на нет цель добавления значения WHERE NOT EXISTS в первую очередь.

Значит, мой запрос не выполняет то, что я думаю, или я неправильно понимаю общую концепцию?

1 Ответ

0 голосов
/ 09 января 2012

ИНФОРМАЦИЯ: Это решение не работает. Смотрите комментарии для деталей. Я оставил это здесь, так что, кто бы ни ищет решение, не должно также попробовать это.

У меня еще не было этой проблемы, но я думаю, вы могли бы обойти ее, если бы оптимизировали подзапрос из нее. Вот так (я не проверял, может быть, это нуждается в улучшении):

PreparedStatement stmt = conn.prepareStatement("INSERT INTO artwork (md5,image) " +
           "SELECT ?,?" +
           "FROM SYSIBM.SYSDUMMY1 left join artwork exi on ? = md5" +
           "WHERE exi.md5 IS NULL");

stmt.setString(1, key);
stmt.setBinaryStream(2, new ByteArrayInputStream(imageData), imageData.length);
stmt.setString(3, key);
...