浅谈OracleBulkCopy的使用

考虑到前端应用往数据库里面插入数据,可以采用三种方式。

第一种:

        直接在程序代码里面写入SQL,这种方式处理简单,然后这种方式的效率很低,因为应用程序每次都需要把SQL传递给数据库服务器,

 然后数据库服务器解析,如果在一个循环内部不断的使用SQL访问数据库,那么需要不断的解析,因此会消耗很长的时间,同时,使用拼接SQL语句方式实现数据写入时,

 由于SQL语句是动态执行的,所以恶意用户可以通过拼接SQL的方式实施SQL注入攻击。 

第二种方法: 存储过程 
  优点:与SQL语句相比,存储过程存在很多优势。存储过程允许标准组件式编程,能够实现较快的执行速度,能够减少网络流量,而且可被作为一种安全机制来充分利用,存储过程由于在服务端编译过了,相比较直接使用SQL的方式,省去了SQL的解析过程,因此有很高的时间效率。
  缺点:由于其实现方式是利用数据库访问类调用存储过程,利用循环逐条插入,所以这种方式的效率不高。还有两个方面是他的可移植性和可扩展性,因为一般大型的Web应用程序都是多Web服务器,然后用双数据库服务器做双机热备,其中一台开机,但是是闲置的。这里只是解决单点故障的问题,但形成了多Web应用服务器,单数据库服务器的情况。如果所有的运算都用存储过程实现,那么会造成数据库服务器负担过重。而Web服务器负荷不足的情况,扩展数据库服务器的话就会非常的麻烦,而且投资较大,程序也需要改。 
第三种方式,使用OracleBulkCopy 
  OracleBulkCopy是ODP.NET中的一个类,是ODP.NET才有的功能。 
  优点:调用WriteToServer方法,可以快速有效的实现大数据量导入数据库。OracleBulkCopy支持超大文本的导入,支持从数据中的某一行开始导入,可以决定是否保存数据行号,列映射不区分大小写,支持导入常量列,支持源列自动检测,当相同源列导入多目标列时,只分配一次内存,更加节约内存。 
   OracleBulkCopy使用方法也非常简单

1.  构造数据表     DataTable dt = new DataTable();

2.  为数据表添加列:

   dt.Columns.Add(Mappings.Fields.period_name, typeof(string));    --Mapping.Fields当中记录了要插入数据表的字段名称,这里取和数据库表的名称一致(不是必要的,以后后面还需要一个DataTable和数据库表的列名映射)

       dt.Columns.Add(Mappings.Fields.ledger_id, typeof(int));

      这里需要注意的地方是,一定要加入列的类型,如后面的typeof(int),如果不加入的话,默认列的类型是string,会导致批量插入数据出错。

3.  为数据表填充数据

foreach (PSGLGEArg rec in records.ApplyRecord)
{

  DataRow dr = dt.NewRow();
  dr[Mappings.Fields.period_name] = rec.period_name;
  dr[Mappings.Fields.ledger_id] = rec.ledger_id;
  dt.Rows.Add(dr);
}

4. 构造一个 OracleBulkCopy对象。

   OracleBulkCopy bulkCopy = new OracleBulkCopy(connStr, OracleBulkCopyOptions.UseInternalTransaction);     

   这里需要注意的地方是,connStr是连接字符串,OracleBulkCopy 的连接字符串和普通的Oracle连接字符串之间存在区别。比如不支持:unicode=true.

   连接字符串例子: "data source=dev;User Id=dyc;Password=1234;Max Pool Size=100;Min Pool Size=5;"

   第二个参数是使用OracleBulkCopy内部的事务,保证数据插入的一致性。

5. 填充OracleBulkCopy对应的表名,和DataTable与数据库表列的映射关系。  

foreach (DataColumn col in dt.Columns)
{
bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
}

7. 最后一步,把构造的数据表当中的数据写入到数据库中。

    bulkCopy.WriteToServer(dt);
    bulkCopy.Dispose();

 

posted on 2014-10-31 17:48 dyc0113 阅读(...) 评论(...) 编辑 收藏

导航

公告

统计