Creating Blob and Clob Data

How to store BLOB data in Oracle database and then how to get those data to my java program?

Answer:

In my opinion the hard part is creating the blob/clob and getting its handle. If you are at least on Oracle 10.2 and have Oracle 10g JDBC Driver, you could try this. (I've devised this technique from the Oracle JDBC Guide, which I strongly suggest for reading.) 

Let's have a table: 

create table mytable(id number(10,0) primary key, data blob);  
create table mytable(id number(10,0) primary key, data blob);
 
Inserting a blob then could look like: 

    public void insertData(Connection conn, int id, byte[] data)   
    {   
        String sql =    
                "insert into mytable(id, data) " +   
                "values(?, empty_blob()) returning data into ?";   
  
        PreparedStatement ps = null;   
        ResultSet rs = null;   
  
        try {   
            ps = conn.prepareStatement(sql);   
  
            ps.setInt(1, id);   
            OraclePreparedStatement oraps = (OraclePreparedStatement) insert;   
            oraps.registerReturnParameter(2, OracleTypes.BLOB);   
            ps.executeUpdate();   
  
            rs = oraps.getReturnResultSet();   
            if (!rs.next())   
                throw new RuntimeException("Could not locate clob");   
  
            Blob blob = rs.getBlob(1);   
            blob.setBytes(1, data);   
        }   
        catch (SQLException ex) {   
            ... Handle the exception as you like   
        }   
        finally {   
            if (rs != null) rs.close();   
            if (ps != null) ps.close();   
        }   
    }  
    public void insertData(Connection conn, int id, byte[] data)
    {
        String sql = 
                "insert into mytable(id, data) " +
                "values(?, empty_blob()) returning data into ?";

        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            ps = conn.prepareStatement(sql);

            ps.setInt(1, id);
            OraclePreparedStatement oraps = (OraclePreparedStatement) insert;
            oraps.registerReturnParameter(2, OracleTypes.BLOB);
            ps.executeUpdate();

            rs = oraps.getReturnResultSet();
            if (!rs.next())
                throw new RuntimeException("Could not locate clob");

            Blob blob = rs.getBlob(1);
            blob.setBytes(1, data);
        }
        catch (SQLException ex) {
            ... Handle the exception as you like
        }
        finally {
            if (rs != null) rs.close();
            if (ps != null) ps.close();
        }
    }
 
I have just taken part of my code and tried to remove my specific logic. 

A few additional notes: 

The technique described here works by creating an empty blob in the database "in the right place" and returning its handle. Although you can create a blob using other means, these techniques often cause a temporary blob to be created, which is then copied when you actually insert or update it. For really, really large data this overhead might be noticeable. 

Once you have the Blob, you can set its data using any of its methods you like or need, eg. using the setBinaryStream method, as mentioned above. 

Remember to process transactions correctly. I'd definitely advice to turn off autocommit and commit the transaction manually, I honestly don't know what would happen to the blob handle if the insert statement got commited. However, the transactional logic would be clearly broken if you allowed autocommit to happen. 

If you want to update a blob, you can either update its field to an empty_blob() value as shown here ("update mytable set data=empty_blob() where id=? returning data into ?"), or just read the blob handle (select data from mytable where id=?) without the need for Oracle-specific methods. 

I think you could hide the SQL statement with the returning into clause into a stored procedure which would return you the Blob and then use standard callable statement to get the handle, thus avoiding the need for Oracle-specific methods. However I personally haven't tried this. Maybe this way it could be made somehow database independent, though I'm definitely not sure of it. 

You can bind clob data directly as Strings, using PreparedStatement.setString() method. Assuming the data field was clob, not blob, you could use: 

    String sql = "insert into mytable(id, data) values(?, ?);"  
    ...   
    ps.setInt(1, id);   
    ps.setString(2, data);   
    ps.executeUpdate();  
    String sql = "insert into mytable(id, data) values(?, ?);"
    ...
    ps.setInt(1, id);
    ps.setString(2, data);
    ps.executeUpdate();
 
The default String length limit for this is 32 KB.

Do you have a Java Problem?
Ask It in The Java Forum

Java Books
Java Certification, Programming, JavaBean and Object Oriented Reference Books

Return to : Java Programming Hints and Tips

All the site contents are Copyright © www.erpgreat.com and the content authors. All rights reserved.
All product names are trademarks of their respective companies.
The site www.erpgreat.com is not affiliated with or endorsed by any company listed at this site.
Every effort is made to ensure the content integrity.  Information used on this site is at your own risk.
 The content on this site may not be reproduced or redistributed without the express written permission of
www.erpgreat.com or the content authors.