用户操作
[即时聊天] [发私信] [加为好友]
新鲜鱼排
新鲜鱼排的公告
Welcome, friends. :)
最近评论
dutguoyi:这个我不是很清楚,应该不是。
如果数据插入没有覆盖的情况,而且可以插入数据那就应该没有问题。看看细节有没有类型定义的错误。
quietsnow_80:和你定义的一样。请问你的ArrayDescriptor,STRUCT等用的都是classes12.jar中的么?
dutguoyi:是不是数据表建立的问题?
department_type, dept_array和我用相同的定义方法么?
quietsnow_80:我又试了一下,如果将department_typ对象中的名字改成number类型,也能插进去了,为什么varchar2类型的插不进去呢?
quietsnow_80:duiguoyi你好,没有出现任何错误,代码如下:
Connection con = null;
PreparedStatement pstmt = null;
OracleCallableStatement callStatement = null;
// CallableStatement ……
文章分类
收藏
    相册
    Excellent pictures from my best friend
    博客收藏
    zjcxc(邹建)的专栏(RSS)
    圈子收藏
    数据库艺术(RSS)
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 如何在JAVA程序中使用Struct一次传入多条数据给Oracle的存储过程。收藏

    新一篇: 如何在Oracle中修改Collection类型的变量。 | 旧一篇: Javascript获取字符串字节数的方法

    为了减少连接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

    发表于 @ 2007年11月11日 22:30:00|评论(loading...)|编辑

    新一篇: 如何在Oracle中修改Collection类型的变量。 | 旧一篇: Javascript获取字符串字节数的方法

    评论

    #quietsnow_80 发表于2008-06-05 17:35:35  IP: 124.254.12.*
    我做了这个测试,怎么只有第一列插进去了
    #dutguoyi 发表于2008-06-06 12:49:08  IP: 210.146.21.*
    To quietsnow_80:
    注意后面赋值时不要把前面的给覆盖了。
    #quietsnow_80 发表于2008-06-06 15:22:35  IP: 124.254.12.*
    dutguoyi你好,“后面赋值时不要把前面的给覆盖了”是什么意思?我没有覆盖呀,这两天被这个问题给难住了,真希望你能帮助我,谢谢!
    #dutguoyi 发表于2008-06-07 08:47:45  IP: 221.201.153.*
    执行过程中有没有错误,比如主键冲突没有插入到数据库中等原因。
    要不把你的代码发给我看看。
    #quietsnow_80 发表于2008-06-10 14:01:46  IP: 124.254.12.*
    duiguoyi你好,没有出现任何错误,代码如下:
    Connection con = null;
    PreparedStatement pstmt = null;
    OracleCallableStatement callStatement = null;
    // CallableStatement cstmt = null;
    try {
    Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
    con = DriverManager.getConnection(
    "jdbc:oracle:thin:@172.30.11.13:1521:jhtest", "hgjks",
    "hgjks");


    Object[] so1 = new Object[] {"88", "Accounts", "LHR"};
    Object[] so2 = new Object[] {"20", "HR", "ISB"};


    StructDescriptor st = new StructDescriptor("DEPARTMENT_TYPE", con);
    STRUCT s1 = new STRUCT(st, con, so1);
    STRUCT s2 = new STRUCT(st, con, so2);
    STRUCT[] deptArray = {s1, s2};
    // Integer[] d={new Integer(1),new Integer(2)};
    ArrayDescriptor arrayDept = ArrayDescriptor.createDescriptor(
    "DEPT_ARRAY", con);
    ARRAY deptArrayObject = new ARRAY(arrayDept, con, deptArray);
    callStatement = (OracleCallableStatement) con.prepareCall(
    "{?=call f_test_array(?)}");
    ((OracleCallableStatement) callStatement).registerOutParameter(1,
    java.sql.Types.INTEGER);
    ((OracleCallableStatement) callStatement).setARRAY(2
    #quietsnow_80 发表于2008-06-10 14:58:43  IP: 124.254.12.*
    我又试了一下,如果将department_typ对象中的名字改成number类型,也能插进去了,为什么varchar2类型的插不进去呢?
    #dutguoyi 发表于2008-06-11 10:52:54  IP: 210.146.21.*
    是不是数据表建立的问题?
    department_type, dept_array和我用相同的定义方法么?
    #quietsnow_80 发表于2008-06-12 14:34:22  IP: 124.254.12.*
    和你定义的一样。请问你的ArrayDescriptor,STRUCT等用的都是classes12.jar中的么?
    #dutguoyi 发表于2008-06-13 08:56:26  IP: 210.146.21.*
    这个我不是很清楚,应该不是。
    如果数据插入没有覆盖的情况,而且可以插入数据那就应该没有问题。看看细节有没有类型定义的错误。
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 新鲜鱼排