求助:使用Oracle.DataAccess将PLSQL的t_table_var类型绑定到C# API
使用Oracle.DataAccess绑定PLSQL自定义数组类型到C#
步骤1:定义C#对应的数据类型
在C#中创建与PLSQL对象类型tt_tabl_var、数组类型t_table_var对应的类,通过Oracle自定义类型映射特性关联数据库中的类型:
using Oracle.DataAccess.Client; using Oracle.DataAccess.Types; using System; // 映射PLSQL包内的tt_tabl_var对象类型 [OracleCustomTypeMapping("你的包名.TT_TABL_VAR")] public class TtTablVar : IOracleCustomType, INullable { private bool _isNull; [OracleObjectMapping("AAAAAAAA1")] public string Aaaaaaa1 { get; set; } [OracleObjectMapping("AAAAAAAA2")] public string Aaaaaaa2 { get; set; } [OracleObjectMapping("AAAAAAAA3")] public string Aaaaaaa3 { get; set; } public bool IsNull => _isNull; public static TtTablVar Null => new TtTablVar { _isNull = true }; public void FromCustomObject(OracleConnection conn, IntPtr pUdt) { OracleUdt.SetValue(conn, pUdt, "AAAAAAAA1", Aaaaaaa1); OracleUdt.SetValue(conn, pUdt, "AAAAAAAA2", Aaaaaaa2); OracleUdt.SetValue(conn, pUdt, "AAAAAAAA3", Aaaaaaa3); } public void ToCustomObject(OracleConnection conn, IntPtr pUdt) { Aaaaaaa1 = (string)OracleUdt.GetValue(conn, pUdt, "AAAAAAAA1"); Aaaaaaa2 = (string)OracleUdt.GetValue(conn, pUdt, "AAAAAAAA2"); Aaaaaaa3 = (string)OracleUdt.GetValue(conn, pUdt, "AAAAAAAA3"); } } // 映射PLSQL包内的t_table_var数组类型 [OracleCustomTypeMapping("你的包名.T_TABLE_VAR")] public class TTableVar : OracleArrayTypeFactoryBase<TtTablVar> { // 继承OracleArrayTypeFactoryBase即可,无需额外实现逻辑 }
步骤2:绑定参数并调用PLSQL程序
构造数组数据,通过OracleParameter绑定到PLSQL的存储过程或函数:
using (OracleConnection conn = new OracleConnection("你的数据库连接字符串")) { conn.Open(); using (OracleCommand cmd = new OracleCommand()) { cmd.Connection = conn; cmd.CommandText = "你的包名.目标存储过程/函数名"; cmd.CommandType = System.Data.CommandType.StoredProcedure; // 创建数组类型参数 OracleParameter arrayParam = new OracleParameter { ParameterName = "p_input", // PLSQL程序的参数名 OracleDbType = OracleDbType.Array, UdtTypeName = "你的包名.T_TABLE_VAR", // 必须指定完整的PLSQL类型名(包名+类型名) Direction = System.Data.ParameterDirection.Input // 根据实际参数方向调整 }; // 构造数组内容(匹配ARRAY(1)的长度,创建1个元素) TtTablVar[] arrayData = new TtTablVar[1]; arrayData[0] = new TtTablVar { Aaaaaaa1 = "测试值1", Aaaaaaa2 = "测试值2", Aaaaaaa3 = "测试值3" }; arrayParam.Value = arrayData; cmd.Parameters.Add(arrayParam); // 执行命令 cmd.ExecuteNonQuery(); } }
关键注意事项
- 类型名称匹配:Oracle默认将标识符转为大写,
OracleCustomTypeMapping和OracleObjectMapping中的名称必须与数据库中类型、字段的大写名称一致(若创建PLSQL类型时未用双引号指定小写)。 - 包名前缀:因为
t_table_var和tt_tabl_var定义在PLSQL包内,必须在UdtTypeName和OracleCustomTypeMapping中添加包名前缀,格式为包名.类型名。 - 版本兼容:确保
Oracle.DataAccess.dll版本与服务器端、客户端Oracle版本兼容,避免类型识别错误。 - 数组长度:PLSQL中定义的是
ARRAY(1),C#构造的数组长度不能超过1,否则会抛出异常。
内容的提问来源于stack exchange,提问作者Ahmed Al-aali
相关产品推荐
相关产品推荐

