您的位置:首页 > 编程语言 > Java开发

存储过程,使用二维数组参数【简单整理】

2017-08-03 16:58 357 查看
业务场景:能过API获取某系统数据,将数据同步到别的数据库表格中。已存在的数据更新操作,不存在的新增。每天都要同步,且数据量较大。使用 JAVA + JDBC

分析:若单条数据进行处理,需循环、频繁的与数据库进行交互。故使用存储过程,按自定义打包数据,比如1000条 调用一次存储过程(下面创建type时会指定,java代码调用存储过程时1000/次)。

Table:

假设有表 tab1 ,字段 id 、name 、 num,类型varchar2(50)

sql:

 1.创建Type(如需在java中调用存储过程,type需独立定义,在package中定义的会提示错误、无法找到)

 --** 创建对象类型,属性名称自定义,属性个数与需同步的参数保持一致即可

   create or replace  type type_xx_obj as object 
  (
    id   varchar2(50),
    name   varchar2(50),

num varchar2(50)

  );

-- ** 创建type_xx_obj对象的二维数组,最大容量1000

   create or replace  type  type_xx_array as VARRAY(1000) of type_agilesyncdata_obj;

2. 新建package及body (procedure


  create or replace package pkg_agilesyncdata is

  procedure pro_syncdata(v_array_2din in type_xx_array,  v_out     out varchar2);

  end pkg_agilesyncdata;

 

 create or replace package body pkg_syncdata is

    flag integer;

    procedure pro_agilesyncdata(v_array_2din in type_xx_array,  v_out   out varchar2)  is

    begin

  

          for i in v_array_2din.first .. v_array_2din.last loop  

              begin

--检查数据是否存在

                 select count(1) into flag  from tab1 where id = v_array_2din(i).id; 

                  if(flag =1) then

                          update tab1 t set t.name = v_array_2din(i).name ,t.num=v_array_2din(i).num   where  t.id=v_array_2din(i).id ;

                   else 

                          insert into ....<omit>.....;

                  end if;                 

                exception

--对遍历过程中的 每次异常进行信息收集

                   when others then

                         v_out := v_out || ' id['  ||  v_array_2din(i).id || '],' || SQLERRM || ';' ;

               end;   

           end loop;

 

      commit;

      exception

        when others then

          v_out :='异常  : '||SQLERRM;

        

    --return(<Result>);

    

  end;

--begin

  -- Initialization

  --<Statement>;

end pkg_syncdata;

3. procedure测试(如何定义并初始化测试时需要的二维参数)



4. java代码中调用二维数组入参的存储过程(个人使用的ojdbc6.jar)

用到的类声明:

import oracle.jdbc.OracleCallableStatement;

import oracle.jdbc.internal.OracleTypes;

import oracle.sql.ARRAY;

import oracle.sql.ArrayDescriptor;

import oracle.sql.STRUCT;

import oracle.sql.StructDescriptor;

核心代码示意:

conn=DBAccess.getConnectionForWindchill();
callStmt = (OracleCallableStatement) conn.prepareCall("{call pkg_syncdata.pro_syncdata(?,?)}"); 
callStmt.registerOutParameter(2, OracleTypes.VARCHAR);  
StructDescriptor structdesc = new StructDescriptor("数据库用户名.TYPE_xx_OBJ", conn);
 

//假设已有数据源list<bean> 且符合设置的1000条要求(若不符合,自行拆分或将1000调大) , 此处根据个人实际情况进行数据填充,明白填充机制即可

STRUCT[] structs = new STRUCT[list.size()];  

Object[] obj = new Object[3];   // 与参数个数匹配

// 遍历 list 并将单条数据放到obj中,将obj添加到structs

for(int i=0;i<length;i++){

bean = list.get(i);

// 注意顺序与 定义的type obj对象对应

obj[0] = bean.getid();

obj[1] = bean.getname();

obj[2] = bean.getnum();

// 组装 structs

 structs[i] = new STRUCT(structdesc, conn, obj); 

}

ArrayDescriptor des=ArrayDescriptor.createDescriptor("数据库用户名.TYPE_xx_ARRAY",conn); 
ARRAY array_to_pass = new ARRAY(des,conn,structs);   
callStmt.setObject(1, array_to_pass);  

callStmt.execute();
String  rsStr = callStmt.getString(2);

if(rsStr!=null){

//TODO   处理返回值
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息