将数组从 Java 传递到 Oracle:java.sql.SQLException:无法转换为内部表示:错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19888520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pass array from Java to Oracle: java.sql.SQLException: Fail to convert to internal representation:error
提问by J?cob
I have the following in DAO and when I execute, I am getting
我在 DAO 中有以下内容,当我执行时,我得到
java.sql.SQLException: Fail to convert to internal representation: test.Project@843
java.sql.SQLException:无法转换为内部表示:test.Project@843
DAO Code
DAO代码
List projectList = new LinkedList();
public void saveRecord(List<Project> project)
throws DatabaseException,SQLException {
for (Project items: project) {
insertRecord(items);
}
}
private void insertRecord(Project project) throws SQLException {
projectList.add(project);
try{
ArrayDescriptor desc =
ArrayDescriptor.createDescriptor("MY_ARRAY", dbConn);
// execpetion in this line
ARRAY arr = new ARRAY(desc, dbConn, (Object[])projectList.toArray());
How can I resolve this issue?
我该如何解决这个问题?
Edit 1
编辑 1
CREATE OR REPLACE TYPE project_type as object(
proj_id varchar2 (10),
proj_title varchar2 (10));
create or replace type my_array as Table of project_type;
采纳答案by Przemyslaw Kruglej
Unfortunately, this is more complicated than one might expect. You have to use STRUCT
objects, descriptors and, finally, ARRAY
. Below is a working example.
不幸的是,这比人们想象的要复杂。您必须使用STRUCT
对象、描述符,最后使用ARRAY
. 下面是一个工作示例。
-- Database code --
CREATE TABLE project_types (
proj_id VARCHAR2(10),
proj_title VARCHAR2(10)
);
/
CREATE OR REPLACE TYPE project_type AS OBJECT (
proj_id VARCHAR2(10),
proj_title VARCHAR2(10)
);
/
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);
END LOOP;
END IF;
END;
/
// Java code - main class
import java.sql.Connection;
import java.sql.DriverManager;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleConnection;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;
public class ArrayExampleMain {
public static void main(String[] args) throws Exception {
OracleConnection conn = getOracleConnection().unwrap(OracleConnection.class);
System.out.println("Got Connection.");
OracleCallableStatement callStmt = null;
try {
callStmt = (OracleCallableStatement)conn.prepareCall("{call add_projects(?)}");
// create array holding values for ProjectType object's properties
Object[] project1 = new Object[] {"1", "Title 1"};
Object[] project2 = new Object[] {"2", "Title 2"};
// descriptor for OBJECT type defined in database
StructDescriptor projectTypeDesc = StructDescriptor.createDescriptor("PROJECT_TYPE", conn);
// each struct is one ProjectType object
STRUCT structProject1 = new STRUCT(projectTypeDesc, conn, project1);
STRUCT structProject2 = new STRUCT(projectTypeDesc, conn, project2);
STRUCT[] structArrayOfProjects = {structProject1, structProject2};
// descriptor of TABLE type defined in database
ArrayDescriptor projectTypeArrayDesc = ArrayDescriptor.createDescriptor("MY_ARRAY", conn);
// array holding two ProjectType objects
ARRAY arrayOfProjects = new ARRAY(projectTypeArrayDesc, conn, 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();
}
}
public static Connection getOracleConnection() throws Exception {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@YOUR_HOST:orcl";
String username = "hr";
String password = "password";
Class.forName(driver); // load Oracle driver
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
}
Checking content of the project_types
table after execution of main class:
project_types
执行主类后检查表的内容:
SELECT * FROM project_types;
Output:
输出:
PROJ_ID PROJ_TITLE ---------- ---------- 1 Title 1 2 Title 2
回答by Acroyear
Thanks, @PrzemyslawKruglej. I took the liberty of cleaning up the deprecated classes.
谢谢,@PrzemyslawKruglej。我冒昧地清理了已弃用的类。
import java.sql.Array;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Struct;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleConnection;
public class ArrayExampleMain {
public static void main(String[] args) throws Exception {
OracleConnection conn = getOracleConnection().unwrap(OracleConnection.class);
System.out.println("Got Connection.");
OracleCallableStatement callStmt = null;
try {
callStmt = (OracleCallableStatement)conn.prepareCall("{call add_projects(?)}");
// create array holding values for ProjectType object's properties
Object[] project1 = new Object[] {"1", "Title 1"};
Object[] project2 = new Object[] {"2", "Title 2"};
// 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 = 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();
}
}
public static Connection getOracleConnection() throws Exception {
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@YOUR_HOST:orcl";
String username = "hr";
String password = "password";
Class.forName(driver); // load Oracle driver
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
}