使用存储过程将java数组blob数据插入到oracle数据库(无法转换为内部表示:错误)

使用存储过程将java数组blob数据插入到oracle数据库(无法转换为内部表示:错误),java,arrays,oracle,blob,Java,Arrays,Oracle,Blob,我想使用存储过程将BLOB数据数组保存到Oracle DB。 (引用自此:) 但我已经向struct添加了BLOB列。 这是我的db脚本和java代码 --数据库代码-- 创建表项目类型( 项目id VARCHAR2(10), 项目名称VARCHAR2(10), 项目数据块 ); / 我已将BLOB数据列添加到项目类型表和项目类型表中, 严格的程序 --Table-- proj_data BLOB -- TYPE-- proj_data BLOB --StruedProcedure-- p_

我想使用存储过程将BLOB数据数组保存到Oracle DB。 (引用自此:)

但我已经向struct添加了BLOB列。 这是我的db脚本和java代码

--数据库代码-- 创建表项目类型( 项目id VARCHAR2(10), 项目名称VARCHAR2(10), 项目数据块 ); /

我已将BLOB数据列添加到项目类型表和项目类型表中, 严格的程序

--Table--
proj_data BLOB

-- TYPE--
proj_data BLOB

--StruedProcedure--
p_projects_array(v_i).proj_data
--Java代码--

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();
 }    

}
--错误代码--

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();
 }    

}
//尝试将BLOB数据插入数据库时出错//

Object[]project1=新对象[]{“1”,“Title 1”,blob1}

Object[]project2=新对象[]{“2”,“Title 2”,blob2}

java.sql.SQLException:无法转换为内部
表示:位于的oracle.jdbc.oracore.OracleTypeBLOB.toDatum(OracleTypeBLOB.java:69)处出错 oracle.jdbc.oracore.OracleType.toDatumInternal(OracleType.java:142)位于 toOracleArray(StructDescriptor.java:741) 位于oracle.sql.StructDescriptor.toArray(StructDescriptor.java:1322) oracle.sql.STRUCT.(STRUCT.java:136)位于 oracle.jdbc.driver.PhysicalConnection.createStruct(PhysicalConnection.java:8733)

--尝试使用空数据时没有错误--

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();
 }    

}
Object[]project1=新对象[]{“1”,“Title 1”,null}

Object[]project2=新对象[]{“2”,“Title 2”,null}

请告诉我如何解决这个问题

谢谢。

换衣服

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

其中
BLOB
import oracle.sql.BLOB

剩下的代码应该没问题

变化

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

其中
BLOB
import oracle.sql.BLOB


剩下的代码应该没问题

我想我会发布一个答案,因为我为此挣扎了一段时间。我有一个类似于@Arkadiusz-answer的方法,但它已被弃用

我不知道你为什么会犯这个错误,但也许可以试试这个方法

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;
    }
}

我将使用类似这样的方式向Oracle中的blob字段发送一个对象。我还没有测试过这个,所以希望它能工作。

我想我会发布一个答案,因为我已经为此挣扎了一段时间。我有一个类似于@Arkadiusz-answer的方法,但它已被弃用

我不知道你为什么会犯这个错误,但也许可以试试这个方法

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;
    }
}

我将使用类似这样的方式向Oracle中的blob字段发送一个对象。我还没有测试过它,所以希望它能工作。

此方法已被弃用。请必须使用
import java.sql.Blob
而不是
导入oracle.sql.BLOB是的,这是真的,适用于oracle 12c驱动程序。此方法已被弃用。请必须使用
import java.sql.Blob
而不是
导入oracle.sql.BLOB是的,这是真的,适用于oracle 12c驱动程序。