我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C#实现Oracle批量写入数据的方法详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C#实现Oracle批量写入数据的方法详解

文章描述

往数据库批量写入数据,这个功能使用频率相对还是比较高的,特别是在做一些导入等功能的时候。net的程序大部分都是使用的sqlserver或者mysql数据库,oracle相对少一些。不过说到Oracle批量写入数据,我只想吐槽一句: .Net苦Oracle久矣。

由于一直使用的是.Net Framework,所以我感觉Oracle在批量写入这一块很不友好。之前有使用过两种方式,但是弊端太明显。分别是: OracleDataAdapter.Update(DataTable dataTable)Oracle.DataAccess.Client下的OracleBulkCopy,以下简单说下:

第一种感觉就是只是提供了一个批量提交的方式,在效率方面,并没有什么提升;

第二种对Oracle环境配置的什么的有要求,所以我在使用的时候,把类似精简oracle的一些文件放了进去(可能是这个原因),在初始化和Open的时候依然会卡顿一下。即便如此,这个方法依然很快。但是弊端基本无解,如非无奈,尽量不要使用(但是我们确实是无奈之举,所以依然使用了一段时间,并采用了以下方式尽量避免这个问题,采用的方式是:批量写入一个无主键的临时表,然后把这个临时表在业务、事务中使用)。

弊端1:没有事务,只有一个内部事务(UseInternalTransaction),单纯的用来保证此次提交数据的一次性而已。

弊端2:会破坏主键,即便数据主键重复依然可以写入成功。导致表结构混乱,引发一系列问题!!!

之前有在SqlSugar中看到Oracle的批量提交,他在备注有表明以上弊端,但是奇怪的是他同时标注了只支持.Net Core,但其实.Net Framework也是可以用。而且我没明白既然只支持.Net Core,为什么不用我下面要写的第三种方式

再然后偶尔在网上发现了第三种方式: .Net Core下,基于Oracle.ManagedDataAccess.Client中的ArrayBindCount,测试后发现,无上述弊端,效率比OracleBulkCopy更优秀。但是如果要继承到老项目中的话,建议写个插件或者Web Api来处理

开发环境

.NET Framework4.5、.NET Core 3.1

开发工具

Visual Studio 2019

实现代码

//OracleDataAdapter.Update(DataTable dataTable)方式
using System.Data.OracleClient;
public static int BulkCopy(DataTable dataTable) {
            int result = 0;


            List<string> sql_column = new List<string>();
            List<string> sql_para = new List<string>();

            List<OracleParameter> paras = new List<OracleParameter>();
            foreach(DataColumn column in dataTable.Columns) {
                sql_column.Add(column.ColumnName);
                sql_para.Add(":" + column.ColumnName);

                OracleParameter para = new OracleParameter(column.ColumnName, ConvertOracleDbType(column.DataType));
                para.SourceColumn = column.ColumnName;
                paras.Add(para);
            }

            using(OracleConnection conn = new OracleConnection(ConfigurationManager.ConnectionStrings["default"].ConnectionString)) {
                conn.Open();
                string sql = $"insert into {dataTable.TableName}({string.Join(",", sql_column)}) values ({string.Join(",", sql_para)})";
                OracleCommand cmd = new OracleCommand(sql, conn);
                cmd.Parameters.AddRange(paras.ToArray());
                OracleDataAdapter adapter = new OracleDataAdapter();
                adapter.InsertCommand = cmd;
                result = adapter.Update(dataTable);
                conn.Close();
            }
            return result;
        }

        public static OracleType ConvertOracleDbType(Type type) {
            switch(type.Name.ToLower()) {
                case "decimal":
                return OracleType.Number;
                case "string":
                return OracleType.VarChar;
                case "datetime":
                return OracleType.DateTime;
                default:
                return OracleType.VarChar;
            }
        }
//OracleBulkCopy
using Oracle.DataAccess.Client;
public static int BulkCopy(DataTable dataTable) {

            int result = 0;

            using(OracleConnection conn = new OracleConnection(ConfigurationManager.ConnectionStrings["default"].ConnectionString)) {
                conn.Open();
                OracleBulkCopy oracleBulkCopy = new OracleBulkCopy(conn, OracleBulkCopyOptions.UseInternalTransaction);
                oracleBulkCopy.DestinationTableName = dataTable.TableName;

                foreach(DataColumn column in dataTable.Columns) {
                    oracleBulkCopy.ColumnMappings.Add(new OracleBulkCopyColumnMapping(column.ColumnName, column.ColumnName));
                }

                oracleBulkCopy.WriteToServer(dataTable);
                conn.Close();
            }
            return result;
        }
//ArrayBindCount
using Oracle.ManagedDataAccess.Client;
   public static OracleDbType ConvertOracleDbType(Type type) {
            switch(type.Name.ToLower()) {
                case "decimal":
                return OracleDbType.Decimal;
                case "string":
                return OracleDbType.Varchar2;
                case "datetime":
                return OracleDbType.Date;
                default:
                return OracleDbType.Varchar2;
            }
        }
        public static dynamic InitList(Type type) {
            switch(type.Name.ToLower()) {
                case "decimal":
                return new List<decimal>();
                case "string":
                return new List<string>();
                case "datetime":
                return new List<DateTime>();
                default:
                return new List<string>();
            }
        }
        public static void AddValue(dynamic list, Type type, object value) {
            switch(type.Name.ToLower()) {
                case "decimal":
                list.Add(Convert.ToDecimal(value));
                break;
                case "string":
                list.Add(Convert.ToString(value));
                break;
                case "datetime":
                list.Add(Convert.ToDateTime(value));
                break;
                default:
                list.Add(Convert.ToString(value));
                break;
            }
        }

        public static int BulkCopy(DataTable dataTable) {

            string connStr = "";
            int result = 0;

            List<string> sql_column = new List<string>();
            List<string> sql_para = new List<string>();

            List<OracleParameter> paras = new List<OracleParameter>();
            foreach(DataColumn column in dataTable.Columns) {

                sql_column.Add(column.ColumnName);
                sql_para.Add(":" + column.ColumnName);

                dynamic list = InitList(column.DataType);

                foreach(DataRow dr in dataTable.Rows) {
                    AddValue(list, column.DataType, dr[column]);
                }
                OracleParameter para = new OracleParameter(column.ColumnName, ConvertOracleDbType(column.DataType));
                para.Value = list.ToArray();
                paras.Add(para);
            }
            using(var connection = new OracleConnection(connStr)) {
                connection.Open();
                string sql = $"insert into {dataTable.TableName}({string.Join(",", sql_column)}) values ({string.Join(",", sql_para)})";
                OracleCommand cmd = new OracleCommand(sql, connection);
                cmd.Parameters.AddRange(paras.ToArray());
                cmd.ArrayBindCount = dataTable.Rows.Count;
                result = cmd.ExecuteNonQuery();
                connection.Close();
            }
            return result;
        }

代码解析:连接Oracle的字符串尽量写成Data Source=IP:Port/DB;User ID=USER;password=PWD;即便配置了tns文件。

上面的方式有做了一下效率比对(各个机器配置等不一致,仅供参考):    

测试数据为5万条,3列,第一种等了很久没写完,直接断掉了;第二种和第三种都是4秒多一点。

到此这篇关于C#实现Oracle批量写入数据的方法详解的文章就介绍到这了,更多相关C# Oracle批量写入数据内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C#实现Oracle批量写入数据的方法详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C#实现Oracle批量写入数据的方法详解

往数据库批量写入数据,这个功能使用频率相对还是比较高的,特别是在做一些导入等功能的时候。本文为大家介绍了C#实现Oracle批量写入数据的方法,需要的可以参考一下
2022-11-13

Java实现批量向mysql写入数据的方法

本文实例讲述了Java实现批量向mysql写入数据的方法。分享给大家供大家参考,具体如下:private static String user = "root";private static String pass = "123456";p
2023-05-30

详解MyBatis批量插入数据Mapper配置文件的写法

对于MyBatis配置文件的用法一直不是很熟悉,之前一直是使用注解来开发的,但是注解也有不好的地方就是如果数据库的表结构发生变化在代码中修改起来很麻烦。其实批量插入很简单,这里做些简要的说明。请看配置文件的写法:2023-05-31

Python操控mysql批量插入数据的实现方法

在Python中,通过pymysql模块,编写简短的脚本,即方便快捷地控制MySQL数据库 一、连接数据库 使用的函数:pymysql.connect 语法:db=pymysql.connect(host='
2022-05-13

Python大批量写入数据(百万级别)的方法

目录背景方案代码方案二方案一总结背景现有一个百万行数据的csv格式文件,需要在两分钟之内存入数据库。方案方案一:多线程+协程+异步MySql方案二:多线程+MySql批量插入代码 1,先通过pandas读取所有csv数据存入
2023-08-08

ORACLE大批量插入数据的方法是什么

这篇文章主要介绍了ORACLE大批量插入数据的方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇ORACLE大批量插入数据的方法是什么文章都会有所收获,下面我们一起来看看吧。最近有几张表随着时间不断的增长
2023-07-05

SpringBoot用多线程批量导入数据库实现方法

这篇文章主要介绍了SpringBoot用多线程批量导入数据库实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
2023-02-03

Java实现将类数据逐行写入CSV文件的方法详解

这篇文章主要为大家详细介绍了Java如何实现将类数据逐行写入CSV文件,文中的示例代码讲解详细,具有一定的参考价值,需要的可以借鉴一下
2022-11-13

mysql 大表批量删除大量数据的实现方法

问题参考自:https://www.zhihu.com/question/440066129/answer/1685329456 ,mysql中,一张表里有3亿数据,未分表,其中一个字段是企业类型,企业类型是一般企业和个体户,个体户的数据量
2022-05-11

MySQL实现批量插入测试数据的方式总结

在开发过程中经常需要一些测试数据, 这个时候如果手敲的话, 十行二十行还好, 多了就很死亡了, 接下来介绍两种常用的MySQL测试数据批量生成方式,希望对大家有所帮助
2023-05-20

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录