简体   繁体   English

C#Oracle过程调用的问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM