C#调用Oracle存储过程传递整数数组报错,请求技术支持
我来帮你排查这个问题——你遇到的「wrong number or types of arguments in call to 'V1'」错误,核心原因是C#代码里的集合类型和Oracle端自定义的类型不匹配,咱们一步步解决:
问题根源
你的Oracle自定义类型INNUMARRAY是SQL嵌套表类型(TABLE OF INTEGER),但你在C#代码里设置了OracleCollectionType.PLSQLAssociativeArray——这个枚举对应的是PL/SQL的关联数组(即带INDEX BY关键字的那种类型),两者属于完全不同的集合类型体系,自然会触发参数类型不匹配的错误。
修正后的C#代码
我把关键修改点标注出来了:
DBEngine oracleEngine = new OracleEngine(connectionString); DbCommand cmd = oracleEngine.MakeTextCmd("v1"); cmd.CommandType = CommandType.StoredProcedure; List<int> values = new List<int>() { 1, 2, 3, 4, 5 }; OracleParameter p_strings = new OracleParameter(); p_strings.ParameterName = "VehicleGroupID_Array"; // 1. 把OracleDbType改为Array,对应SQL嵌套表类型 p_strings.OracleDbType = OracleDbType.Array; // 2. 必须指定UdtTypeName,匹配你创建的自定义类型名称(Oracle默认大写) p_strings.UdtTypeName = "INNUMARRAY"; p_strings.Direction = ParameterDirection.Input; // 3. 移除PLSQLAssociativeArray的设置,这是适配PL/SQL关联数组的,和你的类型不兼容 // p_strings.CollectionType = OracleCollectionType.PLSQLAssociativeArray; // 直接传递int数组即可,Oracle驱动会自动转换为对应的嵌套表类型 p_strings.Value = values.ToArray(); cmd.Parameters.Add(p_strings); // 如果需要获取存储过程返回的游标,取消下面的注释 // DbDataReader reader = oracleEngine.ExecuteReader(cmd); cmd.ExecuteNonQuery();
额外注意事项
- 确保
UdtTypeName的名称和你创建的类型完全一致:Oracle中如果创建类型时没有加双引号,类型名会自动转为大写,所以这里写"INNUMARRAY"是正确的。 - 如果你使用的是
Oracle.ManagedDataAccess.Client驱动(推荐的最新驱动),这种SQL嵌套表类型的传递是完全支持的。 - 你的存储过程中
table(VehicleGroupID_Array)的用法是正确的,因为INNUMARRAY是SQL表类型,可以直接通过table()函数转换为行集用于查询。
内容的提问来源于stack exchange,提问作者masoud vali
相关产品推荐
相关产品推荐

