0

以下の情報から、Oracleプロシージャ呼び出しを呼び出す正しい方法を特定するためのヘルプを探しています。Oracle.DataAccess.Clientで.NET4を使用しています。以下は、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_set出力の適切なタイプを識別しようとして多くの問題を抱えています。以下は私の現在の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
                }



            }
        }

今のところ-上記を試みると、次のエラーが発生します:

無効なパラメーターバインディングパラメーター名:p_acc_set

p_acc_setにOracleParameterUdtTypeNameリファレンスを使用する必要がありますか?

私はOracleプロシージャの呼び出しに非常に慣れていないので、経験不足を許してください。どんな助けでも大歓迎です!前もって感謝します!!

-R

4

2 に答える 2

0

パラメータ「p_acc_set」と「p_status」を他のパラメータと比較して見つけた違いは、サイズが割り当てられていないことです。サイズを割り当ててみてください。問題が解決するはずです。

OracleParamter.Sizeプロパティについて明確に説明しているMSDNが見つかりませんでした。しかし、私は発言の中に次のような行に気づきました

行はMSDNの備考から取られています:

双方向パラメーターと出力パラメーター、および戻り値については、Sizeの値を設定する必要があります。

于 2012-07-14T01:42:11.867 に答える
0

これを処理するために、OracleCommand クラス (デフォルトは false )のプロパティBindByNameがあります。

そのエラーを回避するには、コマンドを実行する前に true に設定する必要があります。

詳細については、こちらもお読みください!!

編集

申し訳ありませんが、PL/SQL のネストされたテーブルがあることに気付きませんでした!! Oracle がそのバインドをサポートしているとは思いません (特に、単純な値ではなくレコードが含まれている場合)。

連想配列、PL/SQL のネストされたテーブル、および PL/SQL Vararray は非常によく似たデータ型であるため、おそらくここでは連想配列という名前で 3 つすべてを意図しています。

代わりにユーザー定義型のネストされたテーブルを使用すると問題は解決しますが、初心者にとっては非常に簡単に処理できます...その場合は、新しいデータ型を使用し、C# で UdtTypeName パラメーターを設定する手順を再定義する必要があります。やるべきことはコードだけではありません。

于 2012-07-14T18:03:21.153 に答える