[英]Issue With C# Oracle Procedure Call
looking for some help in identifying the correct method of calling an Oracle Procedure call from the given info below. 在下面的给定信息中寻找一些帮助,以帮助您确定正确的调用Oracle Procedure调用的方法。 I am using .NET 4 with Oracle.DataAccess.Client.
我正在将.NET 4与Oracle.DataAccess.Client一起使用。 Below are the details of the Procedure from Oracle:
以下是Oracle过程的详细信息:
CREATE OR REPLACE PACKAGE APPS.syk_serial_num_details
AS
TYPE account_rec_type IS RECORD(
inv_item_id NUMBER
,item_num VARCHAR2(40)
,item_desc VARCHAR2(240)
,acc_num VARCHAR2(30)
,ship_to VARCHAR2(1000)
,bill_to VARCHAR2(1000)
);
TYPE account_set IS TABLE OF account_rec_type;
PROCEDURE get_prod_details(
p_serial_num IN VARCHAR2
,p_acc_nums IN VARCHAR2
,p_ship_tos IN VARCHAR2
,p_acc_set OUT syk_serial_num_details.account_set
,p_status OUT VARCHAR2
);
END syk_serial_num_details
here are some more details showing the param types and size...below is an example of the procedure call from Toad interface: 以下是一些更多详细信息,显示了参数类型和大小...下面是从Toad界面调用过程的示例:
DECLARE
l_serial_num csi_item_instances.serial_number%type;
l_acc_nums VARCHAR2(100);
l_ship_tos VARCHAR2(100);
l_acc_set syk_serial_num_details.account_set;
l_status VARCHAR2(80);
BEGIN
l_serial_num := '1025200453';
l_acc_nums := '8165';
l_ship_tos := '10332';
l_acc_set := syk_serial_num_details.account_set();
syk_serial_num_details.get_prod_details(p_serial_num => l_serial_num
,p_acc_nums => l_acc_nums
,p_ship_tos => l_ship_tos
,p_acc_set => l_acc_set
,p_status => l_status
);
Dbms_output.put_line('Status ::' || l_status);
IF(l_acc_set.count >0) then
FOR i IN 1 .. l_acc_set.count
LOOP
l_acc_set.extend;
DBMS_OUTPUT.put_line( 'Item_Number:'
|| l_acc_set(i).item_num||'|'
|| ' Desc:'
|| l_acc_set(i).item_desc||'|'
|| ' Accunt Number:'
|| l_acc_set(i).acc_num||'|'
|| ' Ship To:'
|| l_acc_set(i).ship_to||'|'
|| ' Bill To:'
|| l_acc_set(i).bill_to||'|'
);
END LOOP;
end if;
END;
So...I am having LOTS of trouble trying to identify the proper type for the p_acc_set output. 所以...我在尝试确定p_acc_set输出的正确类型时遇到了很多麻烦。 Below is my current C# code:
以下是我当前的C#代码:
OracleConnection conn = getOracleConnection();
List<AccountSearchResultsDto> ProductInfoList = new List<AccountSearchResultsDto>();
using (conn)
{
conn.Open();
using (OracleCommand cmd = new OracleCommand("syk_serial_num_details.get_prod_details", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
//ASSIGN PARAMETERS TO BE PASSED
OracleParameter param1 = new OracleParameter("p_serial_num", OracleDbType.Varchar2);
param1.Direction = ParameterDirection.Input;
param1.Size = 100;
param1.Value = "1025200453";
cmd.Parameters.Add(param1);
OracleParameter param2 = new OracleParameter("p_acc_nums", OracleDbType.Varchar2);
param2.Direction = ParameterDirection.Input;
param2.Size = 100;
param2.Value = "8165";
cmd.Parameters.Add(param2);
OracleParameter param3 = new OracleParameter("p_ship_tos", OracleDbType.Varchar2);
param3.Direction = ParameterDirection.Input;
param3.Size = 100;
param3.Value = "10332";
cmd.Parameters.Add(param3);
//PARAMETERS USED TO RETURN RESULT OF PROCEDURE CALL
OracleParameter param4 = new OracleParameter("p_acc_set", OracleDbType.Object);
param4.Direction = ParameterDirection.Output;
param4.Size = 1;
cmd.Parameters.Add(param4);
OracleParameter param5 = new OracleParameter("p_status", OracleDbType.Varchar2);
param5.Direction = ParameterDirection.Output;
param5.Size = 300;
cmd.Parameters.Add(param5);
cmd.ExecuteNonQuery();
if (cmd.Parameters["p_status"].Value.ToString().Equals("SUCCESS"))
{
//Get results from p_acct_set and put values in list
}
}
}
As of now - attempting the above I am getting the following error: 截至目前-尝试上述操作,我收到以下错误:
Invalid parameter binding Parameter name: p_acc_set
无效的参数绑定参数名称:p_acc_set
Should i be using the OracleParameter UdtTypeName reference for the p_acc_set? 我应该为p_acc_set使用OracleParameter UdtTypeName引用吗?
I am very new to Oracle Procedure calls so please forgive my inexperience. 我对Oracle Procedure调用非常陌生,因此请原谅我。 Any help is appreciated!
任何帮助表示赞赏! thanks in advance!!
提前致谢!!
-R -R
The difference i spotted for parameter "p_acc_set" and "p_status" compare to others is that they did not assign Size on them please try to assign size on them and should fix your issue 我发现参数“ p_acc_set”和“ p_status”与其他参数的区别在于,它们没有为其分配尺寸,请尝试为其分配尺寸,并应解决您的问题
I did not find the MSDN explaining very clearly on OracleParamter.Size property. 我没有找到有关OracleParamter.Size属性的非常清楚的MSDN说明。 But i did notice a line in the remarks that says
但是我的确注意到在一行中说
The line is taken from MSDN remarks :
该行摘自MSDN的评论:
For bidirectional and output parameters, and return values, you must set the value of Size.
对于双向和输出参数以及返回值,必须设置Size的值。
There's the property BindByName of OracleCommand class ( defaulted to false ) to handle this. 有OracleCommand类的属性BindByName ( 默认为false )来处理此问题。
You should set it to true before executing the command to avoid that error! 您应该在执行命令之前将其设置为true以避免该错误!
for further informations read this too!! 有关更多信息,请阅读此内容 !!
Edit 编辑
Sorry, I didn't notice there was a PL/SQL Nested Table!! 抱歉,我没有发现有PL / SQL嵌套表! I don't think that Oracle supports a bind for that (especially if it contains records instead of simple values).
我不认为Oracle支持该绑定(特别是如果它包含记录而不是简单值)。
Associative Arrays, PL/SQL Nested tables and PL/SQL Vararrays are very similar data types so probably here they intend all the three things with the name Associative Arrays. 关联数组,PL / SQL嵌套表和PL / SQL Vararrays是非常相似的数据类型,因此在这里它们可能用名称Associative Arrays表示所有三样东西。
Using a Nested Table of User defined Types in place of it should solve your problem but it will become very trivial to handle for a newbie ...If so you should redefine the procedure to use the new data type and setting UdtTypeName parameter in the C# code is not the only thing to do. 使用用户定义类型的嵌套表代替它应该可以解决您的问题,但是对于新手来说将变得非常琐碎...如果是这样,则应重新定义使用新数据类型的过程并在C#中设置UdtTypeName参数代码不是唯一要做的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.