Oracle
 sql >> Baza danych >  >> RDS >> Oracle

JdbcTemplate — wstaw lub zaktualizuj Oracle BLOB za pomocą SQL MERGE

Rozwiązałem problem dzięki odpowiedzi @gvenzi, ale postanowiłem opublikować własną odpowiedź, ponieważ mam kilka dodatkowych komentarzy.

A więc tak, OracleLobHandler rozwiązuje problem. Ale w rzeczywistości nie jesteśmy zmuszeni do używania przestarzałej klasy. W OracleLobHandler dokumentacja Znalazłem

Przetestowałem to i działa.

Ale miałem inny problem z użyciem SqlLobValue razem z OracleTypes.BLOB w PreparedStatementSetter (jest to opisane tutaj ClassCastException:SqlLobValue nie można rzutować na oracle.sql.BLOB przy użyciu PreparedStatementSetter )

Mój ostateczny działający kod wygląda następująco:

public void saveThumbnails(List<Thumbnail> fileList) throws SQLException, IOException {

    BatchPreparedStatementSetter b = new BatchPreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
            Thumbnail thumbnail = fileList.get(i);
            byte[] thumbnailBytes = thumbnail.getThumbnail();
            ps.setObject(1, thumbnail.getFileCId(), OracleTypes.NUMBER);
            ps.setObject(2, thumbnail.getType().toString(), OracleTypes.VARCHAR);
            DefaultLobHandler lobHandler = new DefaultLobHandler();
            lobHandler.setCreateTemporaryLob(true);
            lobHandler.getLobCreator().setBlobAsBytes(ps, 3, thumbnailBytes);
        }

        @Override
        public int getBatchSize() {
            return fileList.size();
        }
    };
    jdbcTemplate.batchUpdate(getSaveThumbnailSql(), b);
}

private String getSaveThumbnailSql() {
    // @formatter:off
    String sql = ""
            + "MERGE INTO file_thumbnails "
            + "     USING (SELECT ? as file_c_id, ? as thumbnail_type, ? AS thumbnail_image FROM DUAL) tmp "
            + "        ON (file_thumbnails.file_c_id = tmp.file_c_id AND "
            + "            file_thumbnails.thumbnail_type = tmp.thumbnail_type) "
            + "      WHEN MATCHED THEN "
            + "        UPDATE "
            + "           SET thumbnail_image = tmp.thumbnail_image"
            + "              ,thumbnail_date = SYSDATE "
            + "      WHEN NOT MATCHED THEN "
            + "        INSERT (c_id, file_c_id, thumbnail_type, thumbnail_image, thumbnail_date) "
            + "        VALUES (cedar_c_id_seq.nextval, tmp.file_c_id, tmp.thumbnail_type, tmp.thumbnail_image , SYSDATE)";
    //@formatter:on
    return sql;
}


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Numer wiersza w serwerze sql, taki jak LINE w USER_SOURCE oracle

  2. Jak używać parametrów w klauzuli „where value in...”?

  3. Jak zsynchronizować i zoptymalizować indeks Oracle Text?

  4. ORA-01031:niewystarczające uprawnienia podczas wybierania widoku

  5. nie można zapisać danych o dużym rozmiarze za pomocą UTL_FILE.PUT_LINE