登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
轻量养虾,开箱即用!低 Token + 稳定算力,Gitee & 模力方舟联合出品的 PocketClaw 正式开售!点击了解详情
代码拉取完成,页面将自动刷新
开源项目
>
WEB应用开发
>
Web开发框架
&&
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
9.9K
Star
14.5K
Fork
4.2K
GVP
dotNET China
/
Furion
代码
Issues
0
Pull Requests
0
统计
流水线
服务
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
开发画像分析
我知道了,不再自动展开
更新失败,请稍后重试!
移除标识
内容风险标识
本任务被
标识为内容中包含有代码安全 Bug 、隐私泄露等敏感信息,仓库外成员不可访问
在Oracle数据库下使用 sql.SqlNonQuery(model),更新问题(实体中的字段不能超过sql语句标识字段)
已完成
#I5D057
qd98zhq
创建于
2022-06-19 23:25
坑,坑,坑问题,今天遇到一个oracle数据库的问题,oracle版本为19c,问题如下: 更新的sql语句: ```sql update Rpt_101_5104 set Year=:Year,Month=:Month,Day=:Day,Code=:Code,Name=:Name where OrgId=23135741603074 And KeyId=36945527409409; ``` 使用 `sql.SqlNonQuery(model)` 执行,其中模型 `model` 中的属性成员有很多个, `KeyId,OrgId,Year,Month,Day,HeadImgUrl,Code,Name,IdNo,HouseFundNo,DeptCode,DeptName......` 使用执行 `sql.SqlNonQuery(model)` 执行后报错:ORA-01006: 绑定变量不存在,刚开始以为是sql语句写的有问题,反复检查了多次,确定没有问题,下载了furion源码一步步调试发现提交到了oracle数据库这边后,sql语句中带有:=这样的标识的字段数量必须与model实体中的属性成员一样,只要实体模型属性多一个都不行,执行就错,后面我在furion框架中把以下方法修改为根据SQL语句的:=标识字段生成同等的参数List<DbParameter>,就能正常执行。因为默认的情况下,furion框架这边默认是把整个model的所有成员解析出来List<DbParameter>,如果成员有50个就会有50个DbParameter。 上面描述的问题不知道我说清楚了吗,组织了很久写了出来。 ```cs /// <summary> /// 将模型转为 DbParameter 集合 /// </summary> /// <param name="model">参数模型</param> /// <param name="dbCommand">数据库命令对象</param> /// <param name="providerName">数据库的驱动名称:如 Oracle.EntityFrameworkCore</param> /// <returns></returns> internal static DbParameter[] ConvertToDbParameters(object model, DbCommand dbCommand, string providerName ) { var modelType = model?.GetType(); // 处理 JsonElement 类型 if (model is JsonElement jsonElement && jsonElement.ValueKind == JsonValueKind.Object) return ConvertToDbParameters((Dictionary<string, object>)jsonElement.ToObject(), dbCommand); // 处理 Clay 类型 if (model is Clay clay) return ConvertToDbParameters((Dictionary<string, object>)clay.ToDictionary(), dbCommand); // 处理字典类型参数 if (modelType == typeof(Dictionary<string, object>)) return ConvertToDbParameters((Dictionary<string, object>)model, dbCommand); var dbParameters = new List<DbParameter>(); if (model == null || !modelType.IsClass) return dbParameters.ToArray(); // 获取所有公开实例属性 var properties = modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance); if (properties.Length == 0) return dbParameters.ToArray(); IList<System.Text.RegularExpressions.Match> matchFields = null; // 遍历所有属性 foreach (var property in properties) { //oracle坑问题:判断oracle数据库模式下,sql语句中的:=变量数量必须和实体中的字段相同且相等 //(实体中的字段不能超过sql语句中不存在的标识字段) if (providerName == "Oracle.EntityFrameworkCore") { try { if (matchFields == null) { //过滤oracle语句变量名称正则表达式 string pattern = ":[\u4E00-\u9FA5A-Za-z0-9]{1,99}"; string expres = dbCommand.CommandText; matchFields = System.Text.RegularExpressions.Regex.Matches(expres, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase); } if (matchFields != null && matchFields.Count > 0) { var propertyInfo = matchFields.FirstOrDefault(t => t.Value.ToUpper() == $":{property.Name.ToUpper()}"); //实体中的字段不能超过sql语句中不存在的标识字段 if (propertyInfo == null) { continue; } } } catch (Exception err) { //避免错误影响原来处理逻辑 } } var propertyValue = property.GetValue(model) ?? DBNull.Value; // 创建命令参数 var dbParameter = dbCommand.CreateParameter(); // 判断属性是否贴有 [DbParameter] 特性 if (property.IsDefined(typeof(DbParameterAttribute), true)) { var dbParameterAttribute = property.GetCustomAttribute<DbParameterAttribute>(true); dbParameters.Add(ConfigureDbParameter(property.Name, propertyValue, dbParameterAttribute, dbParameter)); continue; } dbParameter.ParameterName = property.Name; dbParameter.Value = propertyValue is JsonElement propertyJsonElement && propertyJsonElement.ValueKind != JsonValueKind.Object && propertyJsonElement.ValueKind != JsonValueKind.Array ? propertyJsonElement.ToObject() : propertyValue; // 解决 object/json 类型值 dbParameters.Add(dbParameter); } return dbParameters.ToArray(); } ``` 添加的代码段附加图如下  
坑,坑,坑问题,今天遇到一个oracle数据库的问题,oracle版本为19c,问题如下: 更新的sql语句: ```sql update Rpt_101_5104 set Year=:Year,Month=:Month,Day=:Day,Code=:Code,Name=:Name where OrgId=23135741603074 And KeyId=36945527409409; ``` 使用 `sql.SqlNonQuery(model)` 执行,其中模型 `model` 中的属性成员有很多个, `KeyId,OrgId,Year,Month,Day,HeadImgUrl,Code,Name,IdNo,HouseFundNo,DeptCode,DeptName......` 使用执行 `sql.SqlNonQuery(model)` 执行后报错:ORA-01006: 绑定变量不存在,刚开始以为是sql语句写的有问题,反复检查了多次,确定没有问题,下载了furion源码一步步调试发现提交到了oracle数据库这边后,sql语句中带有:=这样的标识的字段数量必须与model实体中的属性成员一样,只要实体模型属性多一个都不行,执行就错,后面我在furion框架中把以下方法修改为根据SQL语句的:=标识字段生成同等的参数List<DbParameter>,就能正常执行。因为默认的情况下,furion框架这边默认是把整个model的所有成员解析出来List<DbParameter>,如果成员有50个就会有50个DbParameter。 上面描述的问题不知道我说清楚了吗,组织了很久写了出来。 ```cs /// <summary> /// 将模型转为 DbParameter 集合 /// </summary> /// <param name="model">参数模型</param> /// <param name="dbCommand">数据库命令对象</param> /// <param name="providerName">数据库的驱动名称:如 Oracle.EntityFrameworkCore</param> /// <returns></returns> internal static DbParameter[] ConvertToDbParameters(object model, DbCommand dbCommand, string providerName ) { var modelType = model?.GetType(); // 处理 JsonElement 类型 if (model is JsonElement jsonElement && jsonElement.ValueKind == JsonValueKind.Object) return ConvertToDbParameters((Dictionary<string, object>)jsonElement.ToObject(), dbCommand); // 处理 Clay 类型 if (model is Clay clay) return ConvertToDbParameters((Dictionary<string, object>)clay.ToDictionary(), dbCommand); // 处理字典类型参数 if (modelType == typeof(Dictionary<string, object>)) return ConvertToDbParameters((Dictionary<string, object>)model, dbCommand); var dbParameters = new List<DbParameter>(); if (model == null || !modelType.IsClass) return dbParameters.ToArray(); // 获取所有公开实例属性 var properties = modelType.GetProperties(BindingFlags.Public | BindingFlags.Instance); if (properties.Length == 0) return dbParameters.ToArray(); IList<System.Text.RegularExpressions.Match> matchFields = null; // 遍历所有属性 foreach (var property in properties) { //oracle坑问题:判断oracle数据库模式下,sql语句中的:=变量数量必须和实体中的字段相同且相等 //(实体中的字段不能超过sql语句中不存在的标识字段) if (providerName == "Oracle.EntityFrameworkCore") { try { if (matchFields == null) { //过滤oracle语句变量名称正则表达式 string pattern = ":[\u4E00-\u9FA5A-Za-z0-9]{1,99}"; string expres = dbCommand.CommandText; matchFields = System.Text.RegularExpressions.Regex.Matches(expres, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase); } if (matchFields != null && matchFields.Count > 0) { var propertyInfo = matchFields.FirstOrDefault(t => t.Value.ToUpper() == $":{property.Name.ToUpper()}"); //实体中的字段不能超过sql语句中不存在的标识字段 if (propertyInfo == null) { continue; } } } catch (Exception err) { //避免错误影响原来处理逻辑 } } var propertyValue = property.GetValue(model) ?? DBNull.Value; // 创建命令参数 var dbParameter = dbCommand.CreateParameter(); // 判断属性是否贴有 [DbParameter] 特性 if (property.IsDefined(typeof(DbParameterAttribute), true)) { var dbParameterAttribute = property.GetCustomAttribute<DbParameterAttribute>(true); dbParameters.Add(ConfigureDbParameter(property.Name, propertyValue, dbParameterAttribute, dbParameter)); continue; } dbParameter.ParameterName = property.Name; dbParameter.Value = propertyValue is JsonElement propertyJsonElement && propertyJsonElement.ValueKind != JsonValueKind.Object && propertyJsonElement.ValueKind != JsonValueKind.Array ? propertyJsonElement.ToObject() : propertyValue; // 解决 object/json 类型值 dbParameters.Add(dbParameter); } return dbParameters.ToArray(); } ``` 添加的代码段附加图如下  
评论 (
2
)
登录
后才可以发表评论
状态
已完成
待办的
进行中
已完成
已关闭
负责人
未设置
百小僧
monksoul
负责人
协作者
+负责人
+协作者
标签
优先
优化
建议
新功能
未设置
标签管理
里程碑
未关联里程碑
未关联里程碑
Pull Requests
未关联
未关联
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
未关联
分支 (
-
)
标签 (
-
)
开始日期   -   截止日期
-
置顶选项
不置顶
置顶等级:高
置顶等级:中
置顶等级:低
优先级
不指定
严重
主要
次要
不重要
参与者(2)
C#
1
https://gitee.com/dotnetchina/Furion.git
git@gitee.com:dotnetchina/Furion.git
dotnetchina
Furion
Furion
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册