C#调用Oracle存储过程时如何正确构建UDT数组?
关于BizTalk生成的Oracle UDT数组创建及存储过程调用的问题
背景
因BizTalk 2020存在问题,我引用BizTalk生成的C# DLL,在C#中复现调用Oracle存储过程的场景。现有代码尝试创建XXCMI.PWR_FWD_PRICES_TABLE类型的UDT数组,但存在语法错误:
public static XXCMI.PWR_FWD_PRICES_TABLE TestCreateUDT1() { var objTable = new XXCMI.PWR_FWD_PRICES_TABLE(); var objrow = new XXCMI.PWR_FWD_PRICES_REC_TYPE(); objrow.OPR_DATE = System.Convert.ToDateTime("2023-01-12"); objrow.MONTH = System.Convert.ToDateTime("2023-01-01"); objrow.HUBCDTPEAK=56.48M; objrow.HUBCDTOFFPEAK = 22.77M; objrow.HUBCDTWKNDPEAK = 58.39M; objrow.CDTPEAK = 59.23M; objrow.CDTOFFPEAK = 24.27M; objrow.CDTWKNDPEAK = 60.87M; objTable.Array = { objrow }; // 该行存在语法错误 return objTable; }
我尝试多种写法后,最终以下写法可正常编译,现需确认两个问题:
- 写法
XXCMI.PWR_FWD_PRICES_REC_TYPE[] objRows = { objRow }; objTable.Array = objRows;是否正确? - 调用存储过程时设置
p.UdtTypeName = "XXCMI.PWR_FWD_PRICES_REC_TYPE";是否合理?
问题解答
1. UDT数组赋值写法的正确性
你采用的写法是完全正确的。
原代码的语法错误源于C#集合初始化器{ ... }仅支持在变量声明时直接初始化,无法单独用于给已存在的数组属性赋值。先声明并初始化数组,再赋值给objTable.Array的方式,完全符合C#语法规则,也适配BizTalk生成的UDT类的属性要求。
如果想简化代码,也可以直接使用数组创建表达式,效果一致:
objTable.Array = new XXCMI.PWR_FWD_PRICES_REC_TYPE[] { objrow };
2. UdtTypeName设置的合理性
这个设置是否合理,取决于存储过程的参数定义:
- 如果存储过程参数是单个
XXCMI.PWR_FWD_PRICES_REC_TYPE类型的UDT,那么该设置完全正确,它明确指定了Oracle客户端要使用的自定义类型名称。 - 如果存储过程参数是**
XXCMI.PWR_FWD_PRICES_TABLE类型的数组UDT**,则UdtTypeName必须设置为"XXCMI.PWR_FWD_PRICES_TABLE",与参数类型严格匹配。
注意:类型名称(包括Schema前缀XXCMI)必须和Oracle数据库中创建的自定义类型完全一致,若类型是区分大小写创建的,还需严格匹配大小写。
内容的提问来源于stack exchange,提问作者NealWalters
相关产品推荐
相关产品推荐

