文章描述:其实我也没想到我会写第二篇关于Oracle批量写入数据的文章,更没想到的是这两篇时间相距是如此的接近。 其实在写上一篇之前,我是不知道有这个方式的,也算是机缘巧合之下学到了(原谅我的无知),这里稍微介绍下这个方式的优缺点。 首先这里跟之前的方式不太一样,没有进行任何的第三方调用或者利用dll给c#提供的方法进行批量提交,而是运用了Oracle本身的一个批量Sql语句提交。稍微做了一下简单的测试: 在速度方面的话,尚可,比OracleBulkCopy 和ArrayBindCount 的方式要慢很多,但是肯定要比一条条提交或者使用OracleDataAdapter.Update(DataTable dataTable) 方式快,至于详细的时间效率比较,我没有测试,有兴趣的话可以自己尝试。 同样的,这个方式也有缺点:不能大批量的进行数据提交,否则会超过Oracle Sql的一个长度限制,所以就需要对数据进行分批处理。即处理5万数据的话,可能需要分10批,每次提交5000条(这只是举个例子,实际的数量可能跟数据列、数据值等有一定关系)。但即便如此,这个方式也不失为一个不错的选择。因为一般情况下的数据量也足够了
![](http://image109.360doc.com/DownloadImg/2023/10/2909/274545951_1_20231029091237867_wm.png)
开发环境:.NET Framework版本:4.5 开发工具: Visual Studio 2019 实现代码: public class InsertAll { public static int BulkCopy(DataTable dataTable) { int result = 0;
List<string> sql_column = new List<string>(); List<string> sql_para = new List<string>(); StringBuilder sqls = new StringBuilder();
List<OracleParameter> paras = new List<OracleParameter>();
foreach(DataColumn column in dataTable.Columns) { sql_column.Add(column.ColumnName); }
int index = 0; foreach(DataRow row in dataTable.Rows) { sql_para.Clear(); index++; foreach(DataColumn column in dataTable.Columns) { string paraName = $"{ column.ColumnName}_{index}"; sql_para.Add(":" + paraName); OracleParameter para = new OracleParameter(paraName, row[column]); paras.Add(para); } sqls.AppendLine($"into {dataTable.TableName}({string.Join(", ", sql_column)}) values ({string.Join(", ", sql_para)}) "); } using(OracleConnection conn = new OracleConnection(ConfigurationManager.ConnectionStrings["default"].ConnectionString)) { conn.Open(); string sql = "insert all " + sqls.ToString()+ " SELECT 1 FROM DUAL"; OracleCommand cmd = new OracleCommand(sql, conn); cmd.Parameters.AddRange(paras.ToArray()); result = cmd.ExecuteNonQuery(); conn.Close(); } return result; } }
Stopwatch sw = new Stopwatch(); sw.Start(); int result = InsertAll.BulkCopy(dt); sw.Stop(); Console.WriteLine("InsertAll time:" + sw.ElapsedMilliseconds + "ms,count:" + result);
代码解析:主要是用到一句很关键的sql语句:insert all into ,然后后面一定要加上SELECT 1 FROM DUAL 语句。 所有源代码均会上传并持续更新,如有需要
|