为了减少连接Oracle数据库的数量,需要将多条数据作为变量一次传入Oracle的存储过程中。方法如下:步骤一:定义对象类型。 CREATE TYPE department_type AS OBJECT (
DNO NUMBER (10),
NAME VARCHAR2 (50),
LOCATION VARCHAR2 (50)
);步骤二:定义一个对象类型的数组对象。
CREATE TYPE dept_array AS TABLE OF department_type;步骤三:定义存储过程来插入数据。CREATE OR REPLACE PACKAGE objecttype AS
  PROCEDURE insert_object (d dept_array);
END objecttype;CREATE OR REPLACE PACKAGE BODY objecttype
AS
PROCEDURE insert_object (d dept_array)
AS
BEGIN
FOR i IN d.FIRST..d.LAST
LOOP
INSERT INTO department_teststruct
VALUES (d(i).dno,d(i).name,d(i).location);
END LOOP;
END insert_object; 
END objecttype;步骤四(可选步骤,即可以不做):定义一个Java class来映射对象中类型。步骤五:定义Java方法来调用存储过程。 import java.sql.Connection; 
import java.sql.DriverManager;
import oracle.jdbc.OracleCallableStatement;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;public class TestStruct ...{
    public static void main(String[] args)
    ...{
            sendStruct();
    }
    public static void sendStruct() 
    ...{
        Connection dbConn = null;
        try...{    
            Object[] so1 = ...{"10","Accounts","LHR"}; 
            Object[] so2 = ...{"20","HR","ISB"}; 
            OracleCallableStatement callStatement = null; 
            Class.forName("oracle.jdbc.driver.OracleDriver");
            dbConn = DriverManager.getConnection("jdbc:oracle:thin:@ServerName:Port:ORa", "UserName", "Password");
            StructDescriptor st = new StructDescriptor("DEPARTMENT_TYPE",dbConn);
            STRUCT s1 = new STRUCT(st,dbConn,so1);
            STRUCT s2 = new STRUCT(st,dbConn,so2);
            STRUCT[] deptArray = ...{s1,s2};
            ArrayDescriptor arrayDept = ArrayDescriptor.createDescriptor("DEPT_ARRAY", dbConn);
            ARRAY deptArrayObject = new ARRAY(arrayDept, dbConn, deptArray); 
            callStatement = (OracleCallableStatement)dbConn.prepareCall("{call insert_object(?)}");
            ((OracleCallableStatement)callStatement).setArray(1, deptArrayObject);
            callStatement.executeUpdate(); 
            dbConn.commit();
            callStatement.close(); 
        } 
        catch(Exception e)...{ 
            System.out.println(e.toString());
        }
    }
}jdbc:oracle:thin:            --Oracle数据库驱动标识
ServerName:                 --Oracle数据库所有机器名或IP地址
1521:                           --数据库所使用的端口号
ORa                             --Oracle服务名     注意事项:
1. 首先一个操作是手动连接Oracle建立对象,接下来的操作是通过JAVA程序建立数据库连接来使用对象。如果两个操作使用同一个用户就没有问题,如果是不同的用户那么要确保第二个操作(即通过Java程序)的用户有权限来操作第一个用户建立的对象。第一个用户为它添加权限的方法是:在每个对象中大家可以找到权限一项,找到对应用户添加执行权限即可。而在程序中就需要做一些修改。存储过程同理。
   StructDescriptor st = new StructDescriptor("第一个UserName.DEPARTMENT_TYPE",dbConn);
      ArrayDescriptor arrayDept = ArrayDescriptor.createDescriptor("第一个UserName.DEPT_ARRAY", dbConn);
      callStatement = (OracleCallableStatement)dbConn.prepareCall("{call 第一个UserName.insert_object(?)}");结果是Java中虽然只是一次执行连接数据库,但是却一次插入两条数据。希望能够给寻找类似解决方案的兄弟姐妹提供一点帮助。有什么建议或者意见尽管留言,谢谢。参考资料:
1. 大家可以在下面的链接中找到javadoc文件来进行下载,这是一个非常有用的说明文档,这次我主要用到了DriverManager.getConnection的定义方法。 
http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc101020.html
我把一些相关的内容写了下来希望对大家有帮助。
1. 如何在JAVA程序中使用Struct一次传入多条数据给Oracle的存储过程
2. 如何在Oracle中修改Collection类型的变量。
3. 如何在Oracle中向Collection类型的变量中逐条插入数据。
4. 如何以Collection变量作为数据源来向数据表中插入数据,或者更新数据。在开发的过程中大家可能会遇到这两类问题。
1. 出现java.io.NotSerializableException错误。
2. 出现“executeUpdate, Exception = null”这样的错误

解决方案 »

  1.   

    http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=123&threadID=44925&tstart=0
      

  2.   

    To figoren:
    谢谢。:)
    为什么大家分享经验的热情不高哪?我知道原因了。 
      

  3.   

    Struct + Array的组合可以在存储过程中作为一个方便的临时表。
      

  4.   

    PROCEDURE insert_object (d dept_array) 中使用批量插入(for all)效率会高一些。
     
      

  5.   


    但是如果在循环中需要进行比较复杂的操作的话,ForAll就不好用了。对吧?
      

  6.   

    你的 例子好像 不能 插入 Accounts,LHR 这些值啊数值类型的还行