Oracle中lang raw字段的迁移以及ResultSet结果集中存在大数据块字段lang Raw的处理

来源:互联网 发布:最优化算法第二版答案 编辑:程序博客网 时间:2024/04/30 15:45

同事在迁移数据库时候遇到了一个这样的问题。lang raw字段无法直接从oracle底层进行迁移。我第一次真正见这样的字段。网上搜索一番后,得出了这样的结论。需要通过流处理来从一张表中读取,然后插入另一张表。

起初我尝试了ResultSet.getBinaryStream,ResultSet.getNCharacterStream,这样在插入另一张表的时候如何都不行,最后我尝试了byte数据来获取langRaw字段,最没有希望的尝试竟然成功了。代码如下:

while(rs.next()){
   jh=rs.getString("jh");
   //is=rs.getBinaryStream("tx");
   //Reader reader=rs.getNCharacterStream("tx");
   //Reader reader=new InputStreamReader(is);
  byte[] b=rs.getBytes("tx");
   if(b!=null){
    //System.out.println(b);
    String sql1="insert into jskg_bak t values(?,?)";    
    pstmt=conn.prepareStatement(sql1); 
    pstmt.setString(1, jh);
    //pstmt.setCharacterStream(2, reader);
    pstmt.setBytes(2, b);
    pstmt.executeUpdate();
    System.out.println("成功插入一条");
    //conn.commit();
   }else{
    System.out.println("=================="+jh);
    String sql1="insert into jskg_bak (jh) values (?)";
    pstmt=conn.prepareStatement(sql1);
    pstmt.setString(1, jh);
    pstmt.executeUpdate();
    System.out.println("成功插入一条xxxx");
    //conn.commit();
   }
   if(pstmt!=null){
    pstmt.close();
   } 
  }

虽然这样能够取出来,能够插进去,但是我这里有很多张表格,个字段,我不能每个表格做一个程序不是?于是用了下面两个视图。

user_tab_columns从此时图中查询表的列。

user_cons_columns从此时图中查询表的主键。

从这两个视图中查询出我sql需要的东西,于是有了下面的程序,可以自动运行多个表格:

package langraw;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class LangRaw {

 /**
  * @param args
  */
 public static void main(String[] args) {
  DBUtil db=new DBUtil();
  try {
   Connection conn=db.getConnection();
   //"JSEA","JSEB","JSEC","JSTB","JSKF","JSZA"
   String[] tb={"JSTB"};
    for(int i=0;i<tb.length;i++){
     String tb_name=tb[i];
     getLangRaw(conn,tb_name);
    }
   System.out.println("==================完成=====================");
  } catch (Exception e) {
   e.printStackTrace();
  }finally{
   db.closeConnection();
  }

 }
 //读取字段
 public static void getLangRaw(Connection conn,String tb_name){
  String jh=null;
  String bz=null;
  Statement stmt=null;
  Statement stmt1=null;
  PreparedStatement pstmt=null;
  ResultSet rs=null;
  ResultSet rs1=null;
  try{
  stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
                ResultSet.CONCUR_UPDATABLE);
  stmt1=conn.createStatement();
  List<String> listKey=new ArrayList<String>();//表的主键
  List<List> listCol=new ArrayList<List>();//表的所有字段
  //String sql="select jh,JSZJ from JSYA_OLD t  where t.jh not in(select jh from jsya) ";
  listKey=getKey(conn, tb_name);
  listCol=getCol(conn, tb_name);
  String sql="select ";
  String str1="";
  String str2="";
  for(int i=0;i<listCol.size();i++){
   if(i!=listCol.size()-1){
    str1=str1+listCol.get(i).get(0)+",";
   }else if(i==listCol.size()-1){
    str1=str1+listCol.get(i).get(0)+" from "+tb_name+"_OLD ";
   }
   
  }
  String str3="";
  for(int j=0;j<listKey.size();j++){
   if(listKey.size()==1){
    str2="where "+listKey.get(j)+" not in(select "+listKey.get(j)+" from "+tb_name+")";
    System.out.println(str2);
   }else if(listKey.size()>1){
    
    if(j<listKey.size()-1){
     str3=str3+listKey.get(j)+"||";
    }else if(j==listKey.size()-1){
     str3="where "+str3+listKey.get(j)+" not in (select "+str3+listKey.get(j)+" from "+tb_name+" )";
     
    }
    str2=str3;
   }
   
  }
  
  //sql=sql+str1+str2+" where JH not in(select JH from "+tb_name+")";
  String sql4="SELECT A.*, ROWNUM RN FROM (";
  String sql5=") A WHERE ROWNUM <= 100";
  sql=sql4+sql+str1+str2+sql5;
  String sql0="select count(*) as num from ("+sql+str1+str2+")";
  System.out.println(sql);
  
  rs1=stmt1.executeQuery(sql0);
  int num=0;
  while(rs1.next()){
   num=rs.getInt("num");
  }
  if(num%100!=0){
   num=num/100+1;
  }
  
  
  for(int l=0;l<num;l++){  
  ///循环页
  rs=stmt.executeQuery(sql);
 // rs.setFetchSize(10);
  int o=0;
  while(rs.next()){
   o++;
   System.out.println(o);
   String sql1="insert into "+tb_name+" values(";
   String str="";
   for(int m=0;m<listCol.size();m++){
    
    if(m<listCol.size()-1){
     str=str+"?,";
    }else if(m==listCol.size()-1){
     str=str+"?)";
    }
   }
   sql1=sql1+str;
   pstmt=conn.prepareStatement(sql1);
   for(int n=0;n<listCol.size();n++){
    //System.out.println(listCol.get(n).get(0));
    //System.out.println(listCol.get(n).get(1));
    if(listCol.get(n).get(1).equals("LONG RAW")){
     
     byte[] b=rs.getBytes(listCol.get(n).get(0).toString());
     pstmt.setBytes(n+1,b);
     b=null;
    }else if(listCol.get(n).get(1).equals("DATE")){
     pstmt.setDate(n+1, rs.getDate(listCol.get(n).get(0).toString()));
    }else if(listCol.get(n).get(1).equals("NUMBER")){
     pstmt.setDouble(n+1, rs.getInt(listCol.get(n).get(0).toString()));
    }else{
     pstmt.setString(n+1, rs.getString(listCol.get(n).get(0).toString()));
    }
   }
   System.out.println(sql1);
   pstmt.executeUpdate();
   rs.moveToCurrentRow();
   //System.out.println("成功插入一条");
   conn.commit();
   
   
   
   //pstmt.clearParameters();
   //if(pstmt!=null){
    pstmt.close();
   //} 
  }}
  }catch(Exception e){
   e.printStackTrace();
  }finally{
   try{
   if(rs!=null){
    rs.close();
   }if(stmt!=null){
    stmt.close();
   }}catch(Exception e){
    e.printStackTrace();
   }
   }
 
 }
 
 //查询表的主键
 public static List<String> getKey(Connection conn,String tb_name){
  Statement stmt=null;
  ResultSet rs=null;
  List<String> listKey=new ArrayList<String>();
  
  String sql="select column_name from sys.user_cons_columns t where t.table_name='"+tb_name+"_OLD' and t.position is not null";
  try {
   stmt=conn.createStatement();
   rs=stmt.executeQuery(sql);
   while(rs.next()){
    listKey.add(rs.getString("column_name"));
   }
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }finally{
   try {
    if(rs!=null){
     rs.close();
     }
    if(stmt!=null){
     stmt.close();
    }
    }catch (SQLException e) {
     e.printStackTrace();
    }
   }
  return listKey;
 }
 //查询表的所有列
 public static List<List> getCol(Connection conn,String tb_name){
  Statement stmt=null;
  ResultSet rs=null;
  List<List> listCol=new ArrayList<List>();
  String sql="select COLUMN_NAME,DATA_TYPE from sys.user_tab_columns t where t.TABLE_NAME='"+tb_name+"_OLD' order by t.COLUMN_ID";
  try {
   stmt=conn.createStatement();
   rs=stmt.executeQuery(sql);
   while(rs.next()){
    List<String> listColNameType=new ArrayList<String>();
    listColNameType.add(rs.getString("COLUMN_NAME"));
    listColNameType.add(rs.getString("DATA_TYPE"));
    listCol.add(listColNameType);
   }
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }finally{
   try {
   if(rs!=null){
    rs.close();
    }
   if(stmt!=null){
    stmt.close();
   }
   }catch (SQLException e) {
    e.printStackTrace();
   }
  }
  return listCol;
 }
 

}

上面这个程序时分页查询,然后取的langraw字段。其实在这之前我陷入了下面这个误区:

运行这个程序的时候,问题又遇到了,那就是 ResultSet结果集实在时太大了,跑上几百条就内存溢出。

这时我也陷入了这个问题里面,总想找个方法,能够循环一行,释放一条rs,结果自然可以想到。呵呵

另外需要注意的是,ResultSet的next方法用的时候,你要明确怎么指向,上面程序里在new statement的时候指定了参数,至于参数的意思,网上很多介绍的。

 

原创粉丝点击