首页 > 代码库 > 用程序实现SQL的表导出

用程序实现SQL的表导出


公司里面对公用数据库的访问有很多限制,因为涉及到性能问题。一般程序用到的就只有几张表。为了更自由地访问数据,一般都需要作数据导出。


用程序实现数据导出,有以下几个问题:


1 数据丢失


用程序导数据,特别是增量导数据,是容易丢失数据的。我的处理方法是利用数据库表的AddTime字段。每次增量导入时,从dest表中取得最大时间,如果不存在(空表),则指定人工指定一个时间点。导入的时间要比最大时间小几秒钟,我定义的是5秒。



2 数据插入冲突


数据插入冲突也是比较容易出现的问题,解决方法是Insert If Not Exist。 对应到sql语句是:

insert into table_name (id,name) select 2,‘a‘ where not exists (select 1 from table_name where id = 2)



3 导入数据的性能


为了提高性能,最好用增量的方式。Java代码如下:


while(rs.next()){
   ++queryCount;
   for(int i=1;i<=count;i++){
    destPs.setObject(i, rs.getObject(i));
   }
   destPs.setObject(count+1, rs.getObject(pk));
   destPs.addBatch();
   if(batchSize%100==0){
      destPs.executeBatch();
   }
}
destPs.executeBatch();


4、程序的通用性


一般导数据的逻辑都是一样的,只是表不一样而已。这样的话,在程序实现的时,通用性就显得很重要,不然冗余代码会很多,程序也不好维护。一般的作法是把sql语句抽象出来。Insert语句由表结构生成。生成的Insert语句代码如下:



/*
 * 生成插入语句
 * @param tag 对于设置了主键自动增长的表,需要
 * set identity_insert "+tableName+" ON
 * */
public String sqlGenerate(int count,ResultSetMetaData rsd,String tableName,String pk,boolean tag) throws SQLException{
    String sql="";
    if(tag){
        sql="set identity_insert "+tableName+" ON;";
    }
    sql+=" insert into "+tableName;
    //columns
    sql+="("+rsd.getColumnName(1);
    for(int i=2;i<=count;i++){
        sql+=‘,‘;
        sql+=rsd.getColumnName(i);
    }
    sql+=")";
    //values
    sql+="select ?";
    for(int i=2;i<=count;i++){
        sql+=",?";
    }
    sql+=" where not exists (select 1 from "+tableName+" where "+pk+" = ? )";
    return sql;
}


这样的话,整个程序就变得很简洁。其实第四点是根据第二点的结构生成的。



本文出自 “每天进步一点点” 博客,请务必保留此出处http://sbp810050504.blog.51cto.com/2799422/1410754