Newsgroup: it.comp.java
Titolo: Java e i BLOB di Oracle. Limite dei 4k

Ciao a tutti.
Sto tentando di inserire dei file come BLOB in Oracle 8.1
Dopo vari smadonnamenti sono riuscito a trovare qualcosa che funzioni,
l'unico problema è il limite di 4k
Infatti per file inferiori a tale limite l'inserimento va liscissimo, oltre
ho una eccezione di oracle,
01461, 00000, "can bind a LONG value only for insert into a LONG column"
Ho provato anche a memorizzare i file dentro un campo LONG al posto di un
BLOB, il problema permane.
Spulciando qua e là ho visto che sarebbe opportuno utilizzare le librerie di
Oracle per fare questa operazione, usando appunto gli oggetti Blob di
Oracle... ma non voglio usare queste librerie perchè legherei troppo il
codice al DB usato, soluzione che non mi piace eccessivamente.
Vi allego il codice di scrittura del blob
    public boolean writeBlob(Connection con, String Row, byte[] inBuff)
    {
        //preparazione alla scrittura del blob
        String sql="";
        boolean returndata=false;
        try
        {
            con.setAutoCommit(false);
            int inBytes = inBuff.length;
            System.out.println("-->BLOB| Bytes da scrivere nel BLOB:
"+inBytes);
            //preparazione alla scrittura
            ByteArrayInputStream bais = new ByteArrayInputStream(inBuff);
            sql = "INSERT INTO "+SQL_Table+" (
"+SQL_BlobColumn+","+SQL_KeyColumn+" ) VALUES ( ?, ? )";
            PreparedStatement ps = con.prepareStatement(sql);
            ps.setBinaryStream(1,bais,inBytes);
            ps.setString(2,Row);
            //Esecuzione scrittura:
            ps.executeUpdate();
            ps.close();
            con.commit();
            System.out.println("Eseguita scrittura su DB con SUCCESSO");
            returndata=true;
        }
        catch (Exception e)
        {
             System.out.println("[writeBlob] <!> Eccezione nella procedura
di test "+e);
             returndata=false;
        }
        finally
        {
            return returndata;
        }
    }
Se qualcuno avesse delle dritte da darmi, ringrazio sin d'ora.
Stefano

codice al DB usato, soluzione che non mi piace eccessivamente.
Ti consiglio di approfondire il pattern j2ee "DAO". Dovrebbe afre al caso
tuo.
ciao
carlo

 ha scritto nel messaggio
news:ac04l7$9b...@intra09.infocamere.it...


Posta il codice SQL per creare una tabella contenente il BLOB che provo a scrivere un
test.
Ciao,
    Bruno.
---
| Bruno Bossola
| A Java Software Engineer :-)
| 
http://digilander.iol.it/bbossola

 ha scritto nel messaggio
news:3ce3b989...@news.inet.it...


In effetti usando JDBC 1 fallisce: lo trovo molto seccante! A che serve JDBC se poi devo
usare il driver specifico del database? Allego il mio spike con JDBC 1, domani provo con
JDBC 2
L'output del programma e' il seguente:
[connect]          Driver loaded!
[connect]          Connection opened! - oracle.jdbc.driver.OracleConnection@4cbe
[createTable]      Table created!
[test]             Bytes to write in blob: 2000
[test]             Ok - transaction committed!
[verify]           Record 1 found!
[test]             Bytes to write in blob: 4000
[test]             Ok - transaction committed!
[verify]           Record 2 found!
[test]             Bytes to write in blob: 6000
[test]             Error - transaction rollback!
[destroyTable]     Table destroyed
[disconnect]       Connection closed!
java.sql.SQLException: ORA-01461: si può eseguire 'bind' di valore LONG solo per inserirlo
in una colonna LONG
	java.lang.Throwable(java.lang.String)
	java.lang.Exception(java.lang.String)
	java.sql.SQLException(java.lang.String, java.lang.String, int)
	void oracle.jdbc.dbaccess.DBError.throwSqlException(java.lang.String,
java.lang.String, int)
	void oracle.jdbc.ttc7.TTIoer.processError()
	void oracle.jdbc.ttc7.Oall7.receive()
	void oracle.jdbc.ttc7.TTC7Protocol.doOall7(byte, byte, int, byte [],
oracle.jdbc.dbaccess.DBType [], oracle.jdbc.dbaccess.DBData [], int,
oracle.jdbc.dbaccess.DBType [], oracle.jdbc.dbaccess.DBData [], int)
	int
oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(oracle.jdbc.dbaccess.DBStatement, byte,
byte [], oracle.jdbc.dbaccess.DBDataSet, int, oracle.jdbc.dbaccess.DBDataSet, int)
	void oracle.jdbc.driver.OracleStatement.executeNonQuery(boolean)
	void oracle.jdbc.driver.OracleStatement.doExecuteOther(boolean)
	void oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout()
	int oracle.jdbc.driver.OraclePreparedStatement.executeUpdate()
	void spike.oracle.Blob.write(java.sql.Connection, int, int)
	void spike.oracle.Blob.test(java.sql.Connection, int, int)
	void spike.oracle.Blob.run()
	void spike.oracle.Blob.main(java.lang.String [])
Ciao,
    Bruno.
 
package spike.oracle;
import java.io.*;
import java.sql.*;
public class Blob 
{
    private void run() throws SQLException
    {
        Connection conn = connect();
 
        try
        {
            destroyTable(conn);
            createTable(conn);
            emit();				
 
            test(conn, 1, 2000);
            test(conn, 2, 4000);
            test(conn, 3, 6000);
        }
        finally
        {
            try
            {
                destroyTable(conn);
            }
            finally
            {
                disconnect(conn);
                emit();
            }
        }
    }
    private void test(Connection conn, int index, int size) throws SQLException
    {
        try
        {
            write(conn, index, size);
            verify(conn, index);
        }
        finally
        {
            emit();
        }
    }
 
    private void write(Connection conn, int index, int size) throws SQLException 
    {
        byte[] buffer = new byte[size];
        for (int i=0; i<size; i++)
            buffer[i] = (byte)(i&0xff);
 
        boolean result = false;
        conn.setAutoCommit(false);
        try
        {
            emit("test", "Bytes to write in blob: "+buffer.length);
 
            String sql = "INSERT INTO BRUNO_TEST (CODE, IMAGE) VALUES (?, ?)";
            PreparedStatement ps = conn.prepareStatement(sql);
            try
            {
                ps.setInt(1, index);
                ps.setBinaryStream(2, new ByteArrayInputStream(buffer), buffer.length);
                ps.executeUpdate();
                result = true;
            }
            finally
            {
                ps.close();
            }
        }
        finally
        {
            if (result)
            {
                conn.commit();
                emit("test", "Ok - transaction committed!");
            }
            else
            {
                conn.rollback();
                emit("test", "Error - transaction rollback!");
            }
        }
    }
 
    private boolean verify(Connection conn, int index) throws SQLException 
    {
        boolean okay = false;
 
        Statement s = conn.createStatement();
        try
        {
            ResultSet r = s.executeQuery("select CODE, IMAGE from BRUNO_TEST");
            try
            {
                if (r.next())
                {
                    okay = true;
                }
            }
            finally
            {
                r.close();
            }
        }
        finally
        {
            s.close();
        }
 
        if (okay) emit("verify", "Record "+index+" found!");
 
        return okay;
    }
 
    private Connection connect() throws SQLException 
    {
        try
        {
            Class.forName("oracle.jdbc.driver.OracleDriver");
            emit("connect", "Driver loaded!");
        }
        catch (Exception ex)
        {
            throw new SQLException("Driver not found!");
        }
 
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@...", "...",
"...");
        emit("connect", "Connection opened! - "+conn);
        return conn;
    }
 
    private void createTable(Connection conn) throws SQLException
    {
        Statement stmt = conn.createStatement();
        try
        {
            stmt.execute("CREATE TABLE BRUNO_TEST (CODE INTEGER, IMAGE BLOB)");
            emit("createTable", "Table created!");
        }
        finally
        {  
            stmt.close();
        }
    }
 
    private void destroyTable(Connection conn) throws SQLException
    {
        Statement stmt = conn.createStatement();
        try
        {
            stmt.execute("DROP TABLE BRUNO_TEST CASCADE CONSTRAINTS");
            emit("destroyTable", "Table destroyed");
        }
        catch (SQLException ex)
        {
            // ignorata intenzionalmente!!!
        }
        finally
        {  
            stmt.close();
        }
    }
 
    private void disconnect(Connection conn) throws SQLException 
    {
        conn.close();
        emit("disconnect", "Connection closed!");
    }
 
    public void emit()
    {
        System.out.println();
    }
 
    public void emit(String id, String message)
    {
        System.out.print("[");
        System.out.print(id);
        System.out.print("] ");
 
        int i = 16-id.length();
        while(i-->0)
        System.out.print(' ');
 
        System.out.print(message);
        System.out.println();
    }
 
    public static void main(String args[])
    {
        try {new Blob().run();}
        catch (SQLException ex)
        {
            ex.printStackTrace();


Aggiornamento: per ora niente da fare, sto sbattendo contro il muro :-(
Sicuramente l'hai trovato pure tu, comunque lo posto per chi segue questo thread: ecco la
soluzione sporca (usando i driver Oracle) per risolvere il problema:
http://groups.google.it/groups?hl=it&lr=&ie=UTF8&oe=UTF8&selm=Pine.GSO.4.05.10001271244090.26685-100000%40nixon.reticular.com
Nel frattempo, a tempo perso, continuo ad indagare.
Ciao,
    Bruno.


 ha scritto nel messaggio
news:3ce4bc11...@news.inet.it...
