Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/261.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#Oracle过程调用问题_C#_Oracle_.net 4.0 - Fatal编程技术网

C#Oracle过程调用问题

C#Oracle过程调用问题,c#,oracle,.net-4.0,C#,Oracle,.net 4.0,在以下给定信息中查找有关确定调用Oracle过程调用的正确方法的帮助。我正在Oracle.DataAccess.Client中使用.NET 4。 以下是Oracle提供的该过程的详细信息: CREATE OR REPLACE PACKAGE APPS.syk_serial_num_details AS TYPE account_rec_type IS RECORD( inv_item_id NUMBER ,item_num

在以下给定信息中查找有关确定调用Oracle过程调用的正确方法的帮助。我正在Oracle.DataAccess.Client中使用.NET 4。 以下是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
下面是显示参数类型和大小的更多详细信息…下面是来自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;
所以…我在尝试确定p_acc_集合输出的正确类型时遇到了很多麻烦。 以下是我目前的C#代码:

OracleConnection conn=getOracleConnection();
List ProductInfoList=新列表();
使用(康涅狄格州)
{
conn.Open();
使用(OracleCommand cmd=new OracleCommand(“syk\u serial\u num\u details.get\u prod\u details”,conn))
{
cmd.CommandType=CommandType.storedProcess;
//分配要传递的参数
OracleParameter param1=新的OracleParameter(“p_serial_num”,OracleDbType.Varchar2);
param1.Direction=ParameterDirection.Input;
参数1.尺寸=100;
param1.Value=“1025200453”;
cmd.Parameters.Add(param1);
OracleParameter param2=新的OracleParameter(“p_acc_nums”,OracleDbType.Varchar2);
param2.Direction=ParameterDirection.Input;
参数2.尺寸=100;
param2.Value=“8165”;
cmd.Parameters.Add(param2);
OracleParameter param3=新的OracleParameter(“p_ship_tos”,OracleDbType.Varchar2);
param3.Direction=ParameterDirection.Input;
参数3.尺寸=100;
param3.Value=“10332”;
cmd.Parameters.Add(param3);
//用于返回过程调用结果的参数
OracleParameter param4=新的OracleParameter(“p_acc_set”,OracleDbType.Object);
param4.Direction=ParameterDirection.Output;
参数4.尺寸=1;
cmd.Parameters.Add(param4);
OracleParameter param5=新的OracleParameter(“p_状态”,OracleDbType.Varchar2);
param5.Direction=ParameterDirection.Output;
参数5.尺寸=300;
cmd.Parameters.Add(param5);
cmd.ExecuteNonQuery();
if(cmd.Parameters[“p_status”].Value.ToString().Equals(“SUCCESS”))
{
//从p_acct_集合中获取结果,并将值放入列表中
}
}
}
到目前为止-尝试上述操作时,我得到以下错误:

无效的参数绑定 参数名称:p_acc_set

我应该为p_acc_集合使用OracleParameter UdtTypeName引用吗

我对Oracle过程调用非常陌生,请原谅我的经验不足。 感谢您的帮助!提前谢谢


-R

我发现参数“p_acc_set”和“p_status”与其他参数相比的不同之处在于,它们没有为它们指定大小。请尝试为它们指定大小,并应解决您的问题

我没有在OracleParameter.Size属性上找到非常清楚的解释。但我注意到评论中有一句话说

该行取自MSDN备注:

对于双向和输出参数以及返回值,必须 设置大小的值

OracleCommand类的属性(默认为false)可以处理此问题

您应该在执行命令之前将其设置为true,以避免该错误

欲了解更多信息,请阅读

编辑

对不起,我没有注意到有一个PL/SQL嵌套表!!我认为Oracle不支持绑定(特别是当它包含记录而不是简单值时)

关联数组、PL/SQL嵌套表和PL/SQL vararray是非常相似的数据类型,因此它们可能打算将这三种类型都命名为关联数组


使用用户定义类型的嵌套表来代替它应该可以解决您的问题,但对于新手来说,这将变得非常简单……如果是这样,您应该重新定义使用新数据类型的过程,并在C代码中设置UdtTypeName参数并不是唯一要做的事情。

否。请阅读OP并查看SP。@AVD您的权利我有更新了我的答案并感谢您的更正在我看来,您向名为GET_PROD_DETAILS的存储过程传递了错误数量或类型的参数。你应该单独提出这个问题mate@RustyMorton我没有粗鲁,我只是想保留评论线索smallerok,正要提出一个新问题,然后我意识到我应用大小的方式有问题。我解决了这个问题,但仍然会遇到同样的错误。我更新了代码以反映添加的size attributetried设置cmd.BindByName=true;仍然收到相同的错误“无效的参数绑定参数名称:p_acc_set”我编辑了我的答案,我认为错误消息指的是一个更简单的问题。@Allessandro感谢您的澄清。我可能会影响Oracle团队修改过程调用,使其在web前端变得更容易。除非其他人在接下来的几天内提出更好的解决方案,否则我将尝试这种方法,并让他们将记录类型更改为UDT表。
        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
                }



            }
        }