1

I want to array BLOB data save to Oracle DB using by stored procedure. (reference from this : Pass array from Java to Oracle: java.sql.SQLException: Fail to convert to internal representation:error)

But I have added BLOB column to struct. Here is my db script and java code.

--DB code-- CREATE TABLE project_types ( proj_id VARCHAR2(10), proj_title VARCHAR2(10), proj_data BLOB ); /

CREATE OR REPLACE TYPE project_type AS OBJECT ( 
proj_id VARCHAR2(10),
proj_title VARCHAR2(10),
proj_data BLOB
);
/

CREATE OR REPLACE TYPE my_array AS TABLE OF project_type;
/

CREATE OR REPLACE PROCEDURE add_projects(p_projects_array IN my_array)
AS
BEGIN
IF p_projects_array IS NOT NULL THEN
FOR v_i IN 1..p_projects_array.LAST
LOOP
INSERT INTO project_types
VALUES (p_projects_array(v_i).proj_id,
p_projects_array(v_i).proj_title,
p_projects_array(v_i).proj_data);
END LOOP;
END IF;
END;
/

I have added BLOB data column to project_types table and project_type TYPE, SturedProcedure.

--Table--
proj_data BLOB

-- TYPE--
proj_data BLOB

--StruedProcedure--
p_projects_array(v_i).proj_data

-- Java code --

import java.sql.Array;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Struct;

import javax.sql.rowset.serial.SerialBlob;

import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.driver.OracleConnection;

public class calMilisecond {

public static void main(String[] args) throws Exception {
String url = "jdbc:oracle:thin:@localhost:1521:orcl";
String user = "testuser";
String password = "testuser123456";
Connection conn = DriverManager.getConnection(url, user, password);;

OracleCallableStatement callStmt = null;
try {
  callStmt = (OracleCallableStatement)conn.prepareCall("{call add_projects(?)}");

  Blob blob1 = new SerialBlob(("test1").getBytes());
  Blob blob2 = new SerialBlob(("test2").getBytes());
  // create array holding values for ProjectType object's properties
  Object[] project1 = new Object[] {"1", "Title 1", blob1};
  Object[] project2 = new Object[] {"2", "Title 2", null};

  // each struct is one ProjectType object
  Struct structProject1 = conn.createStruct("PROJECT_TYPE", project1);
  Struct structProject2 = conn.createStruct("PROJECT_TYPE", project2);

  Struct[] structArrayOfProjects = {structProject1, structProject2};

  // array holding two ProjectType objects
  Array arrayOfProjects = ((OracleConnection) conn).createOracleArray("MY_ARRAY", structArrayOfProjects);

  callStmt.setArray(1, arrayOfProjects); 
  callStmt.execute();
  //conn.commit();

  System.out.println("Committed.");
} catch (Exception e) {
  if (conn != null) try { conn.rollback(); } catch (Exception ex) { System.out.println("Rollback failed."); }
  throw e;
} finally {
  callStmt.close();
  conn.close();
 }    

}

-- Error Code --

//Error occur when I try to insert blobs data to DB. //

Object[] project1 = new Object[] {"1", "Title 1", blob1};

Object[] project2 = new Object[] {"2", "Title 2", blob2};

java.sql.SQLException: Fail to convert to internal
representation:error at oracle.jdbc.oracore.OracleTypeBLOB.toDatum(OracleTypeBLOB.java:69) at oracle.jdbc.oracore.OracleType.toDatumInternal(OracleType.java:142) at oracle.sql.StructDescriptor.toOracleArray(StructDescriptor.java:741) at oracle.sql.StructDescriptor.toArray(StructDescriptor.java:1322) at oracle.sql.STRUCT.(STRUCT.java:136) at oracle.jdbc.driver.PhysicalConnection.createStruct(PhysicalConnection.java:8733)

-- No error when I try to use NULL data --

Object[] project1 = new Object[] {"1", "Title 1", null};

Object[] project2 = new Object[] {"2", "Title 2", null};

Please let me know how to solve this problem.

Thanks.

2 Answers 2

0

Change

Blob blob1 = new SerialBlob(("test1").getBytes());

to

  BLOB blob1 =  new BLOB((oracle.jdbc.OracleConnection)conn, ("test1").getBytes()); 

where BLOB is import oracle.sql.BLOB;

And the rest of your code should be OK.

Sign up to request clarification or add additional context in comments.

2 Comments

This method is deprecated. Please look at this. You must use import java.sql.Blob; instead of import oracle.sql.BLOB;
Yes, it's true, for oracle 12c driver.
0

I thought I would post an answer because I was struggling with this for a while. I had a method in place that worked that was similar to @Arkadiusz answer, but it is deprecated.

I am not sure why you are getting your that error, but maybe try this method.

import java.sql.Blob; 
...

public class MyClassDAO {   
    public static int sendBlobToDb(MyObject myObject) {
        CallableStatement cstmt = null;     
        OutputStream os = null;
        ObjectOutputStream oop = null;
        Blob blob = null;
        Connection conn = null;
        index = 0;
        int result = 0;

        String sql = "begin "
             + "insert into myTable "
             + "(ITEMID, SOME_TEXT, SOME_NUMBER, THE_BLOB_FIELD) values "
             + "(ITEMID_SEQ.nextval, ?, ?, empty_blob()) "
             + "return THE_BLOB_FIELD into ?; "
             + "end; ";

        try {
            conn = DriverManager.getConnection(url, user, password);
            conn.setAutoCommit(false);
            cstmt = conn.prepareCall(sql);

            cstmt.setString(++index, myObject.getSomeText());
            cstmt.setLong(++index, myObject.getSomeNumber());
            cstmt.registerOutParameter(++index, java.sql.Types.BLOB);
            cstmt.executeUpdate();

            blob = (Blob) cstmt.getBlob(index);
            os = blob.setBinaryStream(1L);
            oop = new ObjectOutputStream(os); 
            oop.writeObject(myObject.getListData());
        } catch(SQLException se) {
            result = -1;
            //log exception
            try {
                if(conn != null) {
                    conn.rollback();
                }
            } catch(SQLException se2) {
                //log exception
            }
        } catch(Exception e) {
            result = -1;
            //log exception
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
                if (oop != null) {
                    oop.flush();
                    oop.close();
                }
                if (os != null) {
                    os.close();
                }
                if (cstmt != null) {
                    cstmt.close();
                }
            } catch(SQLException se) {
                result = -1;
                //log exception
            } catch (Exception e) {
                result = -1;
                //log exception
            }
        }

    return result;
    }
}

I would send an object to a blob field in Oracle using something like this. I have not tested this yet so hopefully it works.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.