【问题标题】:Pass array from Java to Oracle: java.sql.SQLException: Fail to convert to internal representation:error将数组从 Java 传递到 Oracle:java.sql.SQLException:无法转换为内部表示:错误
【发布时间】:2013-11-22 04:51:00
【问题描述】:

我在 DAO 中有以下内容,当我执行时,我得到了

java.sql.SQLException: 无法转换为内部表示:test.Project@843

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

我该如何解决这个问题?

编辑 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;

【问题讨论】:

标签: java oracle jdbc oracle10g


【解决方案1】:

不幸的是,这比人们想象的要复杂。您必须使用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;
  }
}

主类执行后检查project_types表的内容:

SELECT * FROM project_types;

输出:

PROJ_ID PROJ_TITLE
---------- ----------
1 标题 1
2 标题 2

【讨论】:

  • 谢谢你,我想知道 ProjectType 类在哪里被引用?它是否在任何其他课程中被调用?那么它对 PROJECT_TYPE 有什么帮助呢?
  • @Polppan 好吧,考虑到我的做法,ProjectType 课程似乎并不真正需要任何东西......将编辑我的答案。
  • 是的,这很好用。我有一个问题,如何使用 List 或 ArrayList 并将其映射到 Object[] 或者我可以直接使用 List 吗?
  • 我忘记了,为您的解决方案+1
  • @Polppan 我不知道如何只传递一些对象并让 Java 和 JDBC 将其映射到数据库对象类型。您必须从列表中获取每个对象并创建一个数组,该数组将保存该对象的每个字段的值,然后从该数组创建一个STRUCT。所以,如果你有一个ArrayList&lt;ProjectType&gt; 类型的列表,你必须遍历它,并创建一个数组:Object[] projectFields = new Object[]{currentElementFromTheList.getId(), currentElementFromTheList.getType()}; 然后在该数组上创建一个STRUCT 对象,最后将所有STRUCT 对象放入@ 987654333@ 数组(见我的代码)。
【解决方案2】:

谢谢,@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;
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    相关资源
    最近更新 更多