.NET6使用Oracle.ManagedDataAccess.Core调用11g UDT存储过程报错求助
.NET 6 连接Oracle 11g使用UDT报错排查方案
核心报错根因
你遇到的PLS-00306: wrong number or types of arguments in call to 'GET_TYPE_SHAPE'错误,和UDT定义、存储过程逻辑无关,是版本兼容问题:
- 你当前使用的
Oracle.ManagedDataAccess.Core 3.21.61最低支持的数据库版本为Oracle 12c R1,该版本驱动解析UDT类型时会调用12c版本才新增的内置过程GET_TYPE_SHAPE,Oracle 11g不存在该过程的匹配签名,因此直接抛出参数不匹配错误。 - 你贴出的C#代码本身存在一处逻辑bug:外层包了一层
if (paramList != null)的判断,但你的代码中从未对paramList变量赋值,该判断永远不会进入,参数根本没有被添加到命令对象中,即使解决驱动兼容问题也会触发参数个数不匹配错误。
可落地解决方案(无需推迟.NET 6升级进度)
不需要等后续Oracle数据库升级完成再推进.NET 6迁移,按以下步骤调整即可:
- 将Nuget包
Oracle.ManagedDataAccess.Core从3.21.61降级到2.19.x系列的最新稳定版,该版本驱动兼容.NET 6,同时最低支持Oracle 11g R2版本,UDT解析逻辑不依赖12c专属的内置过程。 - 删除代码中多余的
if (paramList != null)判断,直接将两个参数添加到OracleCommand对象中,修正后的调用代码片段如下:
using (OracleCommand SqlCmd = new OracleCommand(packageProc, SqlCon)) { SqlCmd.BindByName = true; SqlCmd.Parameters.Add(clientparam); SqlCmd.Parameters.Add(plateparam); SqlCmd.CommandType = CommandType.StoredProcedure; SqlCmd.Connection.Open(); SqlCmd.ExecuteNonQuery(); }
- 按照你之前.NET Framework 4.5.1环境下的写法,给UDT对应的C#实体类添加
[OracleCustomTypeMapping]特性完成类型映射即可,业务逻辑不需要做任何调整。
后续升级说明
等你后续完成Oracle数据库到12c及以上版本的升级后,可按需将Oracle.ManagedDataAccess.Core升级回3.21.x或更高版本,原有UDT相关代码不需要做修改即可正常运行。
内容的提问来源于stack exchange,提问作者David Gerst
相关产品推荐
相关产品推荐

