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 ...
随机推荐
- 【中秋国庆不断更】OpenHarmony定义可动画属性:@AnimatableExtend装饰器
[中秋国庆不断更]OpenHarmony定义可动画属性:@AnimatableExtend装饰器 @AnimatableExtend装饰器用于自定义可动画的属性方法,在这个属性方法中修改组件不可动画的 ...
- 深入剖析 Java 类属性与类方法的应用
Java 类属性 Java 类属性,也称为字段,是类中的变量.它们用于存储与类相关的数据. 创建类属性 在类定义中声明属性: public class Main { int x; // 属性 Stri ...
- c# 托管和非托管资源-详解
前言 引用:带你复习c# 托管和非托管资源_C#教程_脚本之家 (jb51.net) c# 托管和非托管比较重要,因为这涉及到资源的释放. 现在只要在计算机上运行的,无论玩出什么花来,整个什么概念,逃 ...
- 详讲openGauss 5.0 单点企业版如何部署_Centos7_x86
本文分享自华为云社区<openGauss 5.0 单点企业版部署_Centos7_x86>,本文作者:董小姐 本文档环境:CentOS7.9 x86_64 4G1C40G python2. ...
- 机器学习服务活体检测算法荣获CFCA权威安全认证
随着人脸识别技术在金融.医疗等多个领域的加速落地,网络安全.信息泄露等问题愈为突出,用户对应用稳定性和安全性的要求也更为严格.为保障各行业高效稳定的开展业务,提前发现和应对潜在安全风险,HMS Cor ...
- 在Mac系统上使用Qt调用摄像头不出图解决方法
需求:在Mac系统上,调用摄像头,实现旋转.缩放.处理视频帧等功能 问题:使用获取视频帧的方法,在Mac上调不起来摄像头 解决方法: 将视频窗口(QVideoWidget)和视频帧(QVideoFra ...
- BiLSTM算法(一)
原理分析: BiLSTM(双向长短期记忆网络) 是一种循环神经网络(RNN)的变体,它在自然语言处理任务中非常有效,其中包括给定一个长句子预测下一个单词. 这种效果的主要原因包括以下几点: 长短期记忆 ...
- MogDB 2.1.1 初始化参数概要说明
MogDB 2.1.1 初始化参数概要说明 本文出处:https://www.modb.pro/db/394787 MogDB 数据库安装完成后,官方文档提供了刷新参数的脚本,推荐执行脚本来进行初始化 ...
- 域名之A记录,CNAME,NS联系和区别
域名解析中常常涉及:A记录,CNAME,NS 1. A记录 又称IP指向,用户可以在此设置子域名并指向到自己的目标主机地址上,从而实现通过域名找到服务器.说明:指向的目标主机地址类型只能使用IP地址; ...
- CentOS文件备份|还原
CentOS文件备份|还原 时间:2014-03-18 00:27 来源:51cto博客 作者:sailyangfan的空间 举报 点击:205次 dump备份 restore还原 dd数据备份 mk ...