C# 使用recordtype输入参数执行oracle包会在.NET中引发异常
过去几天我一直在讨论一个问题。该问题的详细信息如下: 此oracle软件包有15个输入参数(类型为C# 使用recordtype输入参数执行oracle包会在.NET中引发异常,c#,.net,oracle,C#,.net,Oracle,过去几天我一直在讨论一个问题。该问题的详细信息如下: 此oracle软件包有15个输入参数(类型为int和varchar),1个记录类型param和5个输出params 可以观察到,当将记录类型参数传递给包时,会引发此异常,可以很好地处理那些没有记录类型param的包 Exception Thrown:-Unable to cast object of type 'System.Int32' to type 'System.Array'. Stack Trace:- at Oracle.Data
int
和varchar
),1个记录类型param
和5个输出params
可以观察到,当将记录类型参数传递给包时,会引发此异常,可以很好地处理那些没有记录类型param
的包
Exception Thrown:-Unable to cast object of type 'System.Int32' to type
'System.Array'. Stack Trace:- at
Oracle.DataAccess.Client.OracleParameter.SetStatus(Int32 arraySize) at
Oracle.DataAccess.Client.OracleParameter.ResetCtx(Int32 arraySize) at
Oracle.DataAccess.Client.OracleParameter.PreBind(OracleConnection
conn, IntPtr errCtx, Int32 arraySize) at
Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery() at
POC_App.DataformatConverter.ExecuteCreateSOPackage()
我所尝试的:
public static void ExecuteCreateSOPackage()
{
string constr = EstablishDBConnection();
OracleConnection con = new OracleConnection(constr);
con.Open();
OracleCommand cmd = new OracleCommand("APPS.XX_OM_CREATE_SO_TEST.create_sale_orders", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.BindByName = true;
cmd.ArrayBindCount = 100;
OracleParameter retVal = new OracleParameter("retVal", OracleDbType.RefCursor);
retVal.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add(retVal);
OracleParameter paramPersonId = setInputParameters("p_person_id", OracleDbType.Int32, 0);
paramPersonId.Value = 31842;
cmd.Parameters.Add(paramPersonId);
<likewise 14 more input params >
---------------------------------
//Record type parameter..
OracleParameter p_so_lines_tab = new OracleParameter();
p_so_lines_tab.ParameterName = "p_so_lines_tab";
p_so_lines_tab.OracleDbType = OracleDbType.NVarchar2;
p_so_lines_tab.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
p_so_lines_tab.Size = 3;
p_so_lines_tab.Direction = ParameterDirection.Input;
OracleParameter P_SO_LINES_TAB_ITEM = new OracleParameter();
P_SO_LINES_TAB_ITEM.ParameterName = "p_so_lines_tab_item";
P_SO_LINES_TAB_ITEM.OracleDbType = OracleDbType.NVarchar2;
P_SO_LINES_TAB_ITEM.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
P_SO_LINES_TAB_ITEM.Size = 1000;
P_SO_LINES_TAB_ITEM.Direction = ParameterDirection.Input;
OracleParameter QUANTITY = new OracleParameter();
QUANTITY.ParameterName = "quantity";
QUANTITY.OracleDbType = OracleDbType.Int32;
QUANTITY.Value = 1;
OracleParameter QUANTITY_UOM = new OracleParameter();
QUANTITY_UOM.ParameterName = "quantity_uom";
QUANTITY_UOM.OracleDbType = OracleDbType.Varchar2;
QUANTITY_UOM.Value = "Ea";
OracleParameter ITEM_ID = new OracleParameter();
ITEM_ID.ParameterName = "item_id";
ITEM_ID.OracleDbType = OracleDbType.Int32;
ITEM_ID.Value = 162744;
OracleParameter PROMISE_DATE = new OracleParameter();
PROMISE_DATE.ParameterName = "promise_date";
PROMISE_DATE.OracleDbType = OracleDbType.Date;
PROMISE_DATE.Value = "2016-04-01T08:58:50.649Z";
OracleParameter SCHEDULE_SHIP_DATE = new OracleParameter();
SCHEDULE_SHIP_DATE.ParameterName = "schedule_ship_date";
SCHEDULE_SHIP_DATE.OracleDbType = OracleDbType.Date;
SCHEDULE_SHIP_DATE.Value = "2016-04-01T08:58:50.649Z";
OracleParameter CURRENCY_CODE = new OracleParameter();
CURRENCY_CODE.ParameterName = "currency_code";
CURRENCY_CODE.OracleDbType = OracleDbType.Varchar2;
CURRENCY_CODE.Value = "USD";
OracleParameter UNIT_SELLING_PRICE = new OracleParameter();
UNIT_SELLING_PRICE.ParameterName = "unit_selling_price";
UNIT_SELLING_PRICE.OracleDbType = OracleDbType.Int32;
UNIT_SELLING_PRICE.Value = 200;
OracleParameter SALESREP_ID = new OracleParameter();
SALESREP_ID.ParameterName = "salesrep_id";
SALESREP_ID.OracleDbType = OracleDbType.Int32;
SALESREP_ID.Value = 1412;
P_SO_LINES_TAB_ITEM.Value = new object[] { QUANTITY, QUANTITY_UOM, ITEM_ID, PROMISE_DATE, SCHEDULE_SHIP_DATE, CURRENCY_CODE, UNIT_SELLING_PRICE, SALESREP_ID };
//Adding to outer most collection
p_so_lines_tab.Value = P_SO_LINES_TAB_ITEM;
cmd.Parameters.Add(p_so_lines_tab);
cmd.Parameters.Add("x_time_stamp", OracleDbType.TimeStamp, ParameterDirection.Output);
cmd.Parameters.Add("x_order_header_id", OracleDbType.Int32, ParameterDirection.Output);
cmd.Parameters.Add("x_order_number", OracleDbType.Int32, ParameterDirection.Output);
cmd.Parameters.Add("x_return_code", OracleDbType.Varchar2, ParameterDirection.Output);
cmd.Parameters.Add("x_return_msg", OracleDbType.Varchar2, ParameterDirection.Output);
try
{
cmd.ExecuteNonQuery();
}
catch (Exception exp)
{
string str = exp.StackTrace.ToString();
string msg = exp.Message.ToString();
}
}
publicstaticvoid ExecuteCreateSOPackage()
{
字符串constr=buildedbConnection();
OracleConnection con=新的OracleConnection(cont);
con.Open();
OracleCommand cmd=新的OracleCommand(“APPS.XX\u OM\u CREATE\u SO\u TEST.CREATE\u sale\u orders”,con);
cmd.CommandType=CommandType.storedProcess;
cmd.BindByName=true;
cmd.ArrayBindCount=100;
OracleParameter retVal=新的OracleParameter(“retVal”,OracleDbType.RefCursor);
retVal.Direction=参数Direction.ReturnValue;
cmd.Parameters.Add(retVal);
OracleParameter paramPersonId=setInputParameters(“p_person_id”,OracleDbType.Int32,0);
paramPersonId.Value=31842;
cmd.Parameters.Add(paramPersonId);
---------------------------------
//记录类型参数。。
OracleParameter p_so_line_tab=新的OracleParameter();
p_so_line_tab.ParameterName=“p_so_line_tab”;
p_so_line_tab.OracleDbType=OracleDbType.NVarchar2;
p_so_line_tab.CollectionType=oraclecolectiontype.plsqlassociationarray;
p_so_line_tab.Size=3;
p_so_lines_tab.Direction=参数Direction.Input;
OracleParameter P_SO_line_TAB_ITEM=新OracleParameter();
P_SO_行_选项卡_项。参数name=“P_SO_行_选项卡_项”;
P_SO_行_选项卡_ITEM.OracleDbType=OracleDbType.NVarchar2;
P_SO_行_选项卡_ITEM.CollectionType=oraclecolectiontype.plsqlassociationarray;
P\u SO\u行\u选项卡\u项。大小=1000;
P_SO_行_选项卡_ITEM.Direction=参数Direction.Input;
OracleParameter数量=新的OracleParameter();
QUANTITY.ParameterName=“数量”;
QUANTITY.OracleDbType=OracleDbType.Int32;
数量。数值=1;
OracleParameter数量\计量单位=新的OracleParameter();
数量计量单位。参数name=“数量计量单位”;
数量_UOM.OracleDbType=OracleDbType.Varchar2;
数量/计量单位值=“Ea”;
OracleParameter项_ID=新的OracleParameter();
ITEM\u ID.ParameterName=“ITEM\u ID”;
ITEM_ID.OracleDbType=OracleDbType.Int32;
项目ID.Value=162744;
OracleParameter PROMISE_DATE=新的OracleParameter();
PROMISE\u DATE.ParameterName=“PROMISE\u DATE”;
PROMISE_DATE.OracleDbType=OracleDbType.DATE;
允诺_DATE.Value=“2016-04-01T08:58:50.649Z”;
OracleParameter SCHEDULE_SHIP_DATE=新的OracleParameter();
计划装运日期。参数name=“计划装运日期”;
计划\发货\日期.OracleDbType=OracleDbType.DATE;
附表_SHIP_DATE.Value=“2016-04-01T08:58:50.649Z”;
OracleParameter CURRENCY_CODE=新的OracleParameter();
货币代码。参数name=“货币代码”;
CURRENCY_CODE.OracleDbType=OracleDbType.Varchar2;
货币代码Value=“USD”;
OracleParameter单位\销售\价格=新OracleParameter();
单位售价。参数name=“单位售价”;
单位销售价格.OracleDbType=OracleDbType.Int32;
单位售价价值=200;
OracleParameter SALESREP_ID=新的OracleParameter();
SALESREP_ID.ParameterName=“SALESREP_ID”;
SALESREP_ID.OracleDbType=OracleDbType.Int32;
SALESREP_ID.Value=1412;
P_SO_line_TAB_ITEM.Value=新对象[]{QUANTITY,QUANTITY_UOM,ITEM_ID,PROMISE_DATE,SCHEDULE_SHIP_DATE,CURRENCY_CODE,UNIT_SELLING_PRICE,SALESREP_ID};
//添加到最外层集合
p_so_line_tab.Value=p_so_line_tab_项;
cmd.Parameters.Add(p_so_line_选项卡);
cmd.Parameters.Add(“x_time_stamp”,OracleDbType.TimeStamp,ParameterDirection.Output);
cmd.Parameters.Add(“x_order_header_id”,OracleDbType.Int32,ParameterDirection.Output);
cmd.Parameters.Add(“x_order_number”,OracleDbType.Int32,ParameterDirection.Output);
cmd.Parameters.Add(“x_return_code”,OracleDbType.Varchar2,ParameterDirection.Output);
cmd.Parameters.Add(“x_return_msg”,OracleDbType.Varchar2,ParameterDirection.Output);
尝试
{
cmd.ExecuteNonQuery();
}
捕获(异常扩展)
{
字符串str=exp.StackTrace.ToString();
字符串msg=exp.Message.ToString();
}
}
您有以下OracleParameter:
OracleParameter P_SO_LINES_TAB_ITEM = new OracleParameter();
P_SO_LINES_TAB_ITEM.ParameterName = "p_so_lines_tab_item";
P_SO_LINES_TAB_ITEM.OracleDbType = OracleDbType.NVarchar2;
P_SO_LINES_TAB_ITEM.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
P_SO_LINES_TAB_ITEM.Size = 1000;
P_SO_LINES_TAB_ITEM.Direction = ParameterDirection.Input;
p\u SO\u line\u TAB\u项的值
必须是纯文本列表(即您通过属性OracleDbType
声明的NVARCHAR2
)。但是,您尝试使用OracleParameter
对象的列表
P_SO_LINES_TAB_ITEM.Value = new object[] { QUANTITY, QUANTITY_UOM, ITEM_ID, PROMISE_DATE, SCHEDULE_SHIP_DATE, CURRENCY_CODE, UNIT_SELLING_PRICE, SALESREP_ID };
这是不可能的,您不能创建嵌套参数。为我的问题找到了解决方案。我们可以通过将oracle.Dbtype设置为NVarchar来传递数据集合,如下所示
var commandObject = new OracleCommand
{
Connection = con,
CommandText = "Your Packge Name",
CommandType = CommandType.StoredProcedure
};
commandObject.Connection.Open();
commandObject.Parameters.Add("param1", OracleDbType.Int32, ParameterDirection.Input).Value = some int value;
commandObject.Parameters.Add("param2", OracleDbType.Int32, ParameterDirection.Input).Value = some int value;
commandObject.Parameters.Add("param3", OracleDbType.Int32, ParameterDirection.Input).Value = some int value;
commandObject.Parameters.Add("p_xml_type", OracleDbType.NVarchar2, ParameterDirection.Input).Value =some collection
commandObject.Parameters.Add("param returncode", OracleDbType.Varchar2, 200).Direction = "some string value";
commandObject.ExecuteNonQuery();
正在设置的集合是string类型的xml格式,在oracle包中,参数的定义如下所示
p_xml_type IN CLOB
参数的值是另一个参数吗?p_so_line_tab.Value=p_so_line_tab_项;是的,p_so_lines_tab.Value应该包含p_so_lines_tab_项目的集合,intern由varchar和int32类型的参数组成。感谢您的回复,在这种情况下,将嵌套参数传递给oracle软件包的最佳方式是什么。另外,请告诉我如何处理来自.NET的oracle记录类型参数。您不能使用记录类型。返回递归或转换为Xml文档