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