Oracle批量插入和更新
一、驱动。使用Oracle.ManagedDataAccess.Client
二、原理。利用OracleCommand的ArrayBindCount属性设置批量大小。
三、实现
函数使用的实体是efcore生成的实体,其字段命名法是帕斯卡命名法。
1.辅助函数

public static DataTable ToDataTable<T>(List<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name); // 获取所有属性
var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var prop in properties)
{
// 添加DataTable的列,列名为属性名
dataTable.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
} foreach (var item in items)
{
var values = new object[properties.Length];
for (int i = 0; i < properties.Length; i++)
{
// 通过反射获取属性值
values[i] = properties[i].GetValue(item, null);
}
dataTable.Rows.Add(values);
} return dataTable;
} private static OracleDbType GetOracleType(Type type)
{
// 如果类型是可空类型,获取基础类型
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
type = Nullable.GetUnderlyingType(type);
}
// 添加更多类型的映射,以适应您的特定需求
if (type == typeof(int))
{
return OracleDbType.Int32;
}
else if (type == typeof(string))
{
return OracleDbType.Varchar2;
}
else if (type == typeof(DateTime))
{
return OracleDbType.Date;
}
else if (type == typeof(decimal))
{
return OracleDbType.Decimal;
}
// 如果您有其他类型的映射需求,请在此处添加更多条件 // 默认情况下返回一个通用的值
return OracleDbType.Varchar2; // 或者您认为合适的默认类型
} private static string ConvertPascalToSnakeCase(string input)
{
if (string.IsNullOrEmpty(input))
{
return input;
} string snakeCase = char.ToUpper(input[0]).ToString(); // 将首字母大写 for (int i = 1; i < input.Length; i++)
{
char currentChar = input[i];
if (char.IsUpper(currentChar))
{
// 如果当前字符是大写字母,添加下划线并转换为小写
snakeCase += "_";
snakeCase += currentChar;
}
else
{
// 否则,直接添加字符
snakeCase += char.ToUpper(currentChar);
}
} return snakeCase;
} private static string GenerateInsertStatement(Type entityType, string tableName)
{
PropertyInfo[] properties = entityType.GetProperties(); string columns = string.Join(", ", properties.Select(p => ConvertPascalToSnakeCase(p.Name)));
string values = string.Join(", ", properties.Select(p => $":{ConvertPascalToSnakeCase(p.Name)}")); string insertStatement = $"INSERT INTO {tableName} ({columns}) VALUES ({values})"; return insertStatement;
} private static string GenerateUpdateStatement(Type entity, string tableName, string whereField)
{
PropertyInfo[] properties = entity.GetProperties(); // 生成 SET 部分,用于更新列
string setClause = string.Join(", ", properties.Select(p => $"{ConvertPascalToSnakeCase(p.Name)} = :{ConvertPascalToSnakeCase(p.Name)}"));
// 生成 WHERE 子句,基于指定的字段
string whereClause = $"{ConvertPascalToSnakeCase(whereField)} = :{whereField}";
string updateStatement = $"UPDATE {tableName} SET {setClause} WHERE {whereClause}"; return updateStatement;
}
2.批量插入

public static void BulkInsert<T>(List<T> entities, OracleConnection connection)
{
DataTable table = ToDataTable<T>(entities);
try
{
string cmdstr = GenerateInsertStatement(typeof(T), ConvertPascalToSnakeCase(typeof(T).Name));
using (OracleCommand command = new OracleCommand(cmdstr, connection))
{
command.ArrayBindCount = entities.Count; // 设置为批量操作的大小
command.BindByName = true; // 使用参数名称绑定
// 创建参数数组
OracleParameter[] parameters = new OracleParameter[table.Columns.Count];
for (int i = 0; i < table.Columns.Count; i++)
{
parameters[i] = new OracleParameter(ConvertPascalToSnakeCase(table.Columns[i].ColumnName), GetOracleType(table.Columns[i].DataType));
// 选择特定列的所有行,并将其转换为数组
object[] columnArray = table.AsEnumerable().Select(row => row.Field<object>(table.Columns[i].ColumnName)).ToArray();
parameters[i].Value = columnArray;
}
// 添加参数到命令
command.Parameters.AddRange(parameters);
// 执行批量插入
command.ExecuteNonQuery();
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
3.批量更新

public static void BulkUpdate<T>(List<T> entities, OracleConnection connection, PropertyInfo keyField)
{
DataTable table = ToDataTable<T>(entities);
try
{
string cmdstr = GenerateUpdateStatement(typeof(T), ConvertPascalToSnakeCase(typeof(T).Name), keyField.Name);
using (OracleCommand command = new OracleCommand(cmdstr, connection))
{
command.ArrayBindCount = entities.Count; // 设置为批量操作的大小
command.BindByName = true; // 使用参数名称绑定
// 创建参数数组
OracleParameter[] parameters = new OracleParameter[table.Columns.Count + 1];
for (int i = 0; i < table.Columns.Count; i++)
{
parameters[i] = new OracleParameter(ConvertPascalToSnakeCase(table.Columns[i].ColumnName), GetOracleType(table.Columns[i].DataType));
// 选择特定列的所有行,并将其转换为数组
object[] columnArray = table.AsEnumerable().Select(row => row.Field<object>(table.Columns[i].ColumnName)).ToArray();
parameters[i].Value = columnArray;
}
//where参数绑定
parameters[table.Columns.Count] = new OracleParameter(keyField.Name, GetOracleType(keyField.PropertyType));
object[] whereArray = table.AsEnumerable().Select(row => row.Field<object>(keyField.Name)).ToArray();
parameters[table.Columns.Count].Value = whereArray;
// 添加参数到命令
command.Parameters.AddRange(parameters);
// 执行批量插入
command.ExecuteNonQuery();
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
四、用例
//更新
ExampleClass.BulkUpdate(delList, connection, typeof(实体类).GetProperty("实体主键字段")); //插入
ExampleClass.BulkInsert(addList, connection);
Oracle批量插入和更新的更多相关文章
- Mybatis 向oracle批量插入与更新数据
插入 <insert id="batchSave" parameterType="java.util.List"> INSERT INTO T_UP ...
- oracle 批量插入-支持序列自增
1.创建表.序列 -- Create table create table test_batch ( id number not null, name ), account ) ) -- Create ...
- java批量插入或更新的问题
在批量插入或者更新中,setXXX的时候字段类型必须一致.例如:在普通sql中 pstmt8.setBigDecimal(j ,xxx);可以写成pstmt8.setString(j,xxx.toSt ...
- C#使用SqlDataAdapter 实现数据的批量插入和更新
近日由于项目要求在需要实现中型数据的批量插入和更新,晚上无聊,在网上看到看到这样的一个实现方法,特摘抄过来,以便以后可能用到参考. 一.数据的插入 DateTime begin = DateTime. ...
- mybatis 注解的方式批量插入,更新数据
一,当向数据表中插入一条数据时,一般先检查该数据是否已经存在,如果存在更新,不存在则新增 使用关键字 ON DUPLICATE KEY UPDATE zk_device_id为主键 model ...
- MySQL on duplicate key update 批量插入并更新已存在数据
业务上经常存在一种现象,需要批量往表中插入多条数据,但在执行过程中,很可能因为唯一键冲突,而导致批量插入失败.因此需要事先判断哪些数据是重复的,哪些是新增的.比较常用的处理方法就是找出已存在的数据,并 ...
- Mybatis中实现oracle的批量插入、更新
oracle 实现在Mybatis中批量插入,下面测试可以使用,在批量插入中不能使用insert 标签,只能使用select标签进行批量插入,否则会提示错误 ### Cause: java.sql.S ...
- Oracle+Mybatis批量插入,更新和删除
1.插入 (1)第一种方式:利用<foreach>标签,将入参的list集合通过UNION ALL生成虚拟数据,从而实现批量插入(验证过) <insert id="inse ...
- mybatis+oracle 批量插入,若数据库中有则做更新操作
1.只批量插入: insert into WXPAY_ACCOUNT(id ,out_trade_no ,transaction_id)select SEQ_WXPAY_ACCOUNT.nextval ...
- mybatis Oracle 批量插入,批量更新
传入的参数只要是list类型的参数就行了..............1.批量插入<insert id="insertBatch" parameterType="ja ...
随机推荐
- HUAWEI DevEco Testing注入攻击测试:以攻为守,守护OpenHarmony终端安全
OpenAtom OpenHarmony(以下简称"OpenHarmony")作为面向全场景的开源分布式操作系统,可广泛应用于智能家居物联网终端.智能穿戴.智慧大屏.汽车智能座舱. ...
- Avalonia的自定义用户组件
Avalonia中的自定义用户控件 Avalonia是一个跨平台的.NET UI框架,它允许开发者使用C#和XAML来构建丰富的桌面应用程序. 自定义用户控件(UserControl)是Avaloni ...
- Seaborn结构化图形绘制(FacetGrid)
结构化图形绘制(FacetGrid) 可实现多行多列个性化绘制图形. sns.FacetGrid( data, row=None, col=None, hue=None, col_wrap=None, ...
- 【4】Spring框架的起源
在我们的<Java Spring框架入门教程>中对 Spring 框架进行了十分详尽的介绍和剖析,但在学习 Spring Boot 之前,在这里回顾一下 Spring 是怎么出现的. Sp ...
- CentOS添加一个新的硬盘分区到挂载的过程
1.分区 分区工具fdisk用法介绍 fdisk命令参数介绍 p.打印分区表. n.新建一个新分区. d.删除一个分区. q.退出不保存. w.把分区写进分区表,保 ...
- ERP财务管理有哪些功能?如何选择合适的ERP软件开发商定制开发适合自己的ERP财务管理?
企业日常运营中,分工明确.结构清晰的财务管理非常重要,因此在完整的ERP解决方案中,财务管理是不可或缺的部分,甚至财务管理是整个ERP解决方案的核心,其它功能模块都围绕着财务管理构建价值链创造流程,最 ...
- 社区首款 OAM 可视化平台发布!
作者 | 徐运元,杭州谐云科技合伙人及资深架构师,云计算行业和 Kubernetes 生态资深从业者 导读:什么是 OAM?2019 年 10 月 17 日,阿里巴巴合伙人.阿里云智能基础产品事业部总 ...
- Flink SQL 1.11 on Zeppelin 平台化实践
简介: 鉴于有很多企业都无法配备专门的团队来解决 Flink SQL 平台化的问题,那么到底有没有一个开源的.开箱即用的.功能相对完善的组件呢?答案就是本文的主角--Apache Zeppelin. ...
- EasyNLP开源|中文NLP+大模型落地,EasyNLP is all you need
简介:EasyNLP背后的技术框架如何设计?未来有哪些规划?今天一起来深入了解. 作者 | 临在.岑鸣.熊兮 来源 | 阿里开发者公众号 一 导读 随着BERT.Megatron.GPT-3等预训练 ...
- Serverless 可观测性的过去、现在与未来
简介: 函数计算可观测性经历了 1.0 -> 2.0 的发展,从闭门造车的可观测发展成开源的可观测,从平台的可观测发展为开发者的可观测,从FaaS Only 的可观测演进成了云原生的可观测. 作 ...