2013-04-24 30 views
5

私は4つの入力を取るPL/SQLストアドプロシージャを持っています。これらの入力の1つは、連想配列です(Oracleタイプ:PLS_INTEGERによるVARCHAR2(1)索引の表)。C#2010、ODP.net、コールストアドプロシージャの渡し配列

このストアドプロシージャを連想配列を含む適切な入力で呼び出すC#プログラムが必要です。

私は、Visual C#2010 ExpressとOracle 11gR2でODP.net 11.2を使用しています。

C#の配列をpl/sqlプロシージャに渡す方法の良い例は見つかりません。誰か私に例を教えてもらえますか? Oracleのマニュアルに従うと、間違った数または引数の型が間違っています。

私のC#コード:

 OracleCommand cmd = new OracleCommand("begin sdg_test.sdg_test2(:1); end;", conn); 

     OracleParameter Param1 = cmd.Parameters.Add("1", OracleDbType.Varchar2); 

     Param1.Direction = ParameterDirection.Input; 

     Param1.CollectionType = OracleCollectionType.PLSQLAssociativeArray; 

     Param1.Value = new string[22] { "Y", "Y", "N", "Y", "N", "Y", "Y", "Y", "Y", "Y", "N", "Y", "N", "Y", "Y", "Y", "Y", "Y", "N", "Y", "N", "Y" }; 

     Param1.Size = 22; 
     Param1.ArrayBindSize = new int[22] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 

     cmd.ExecuteNonQuery(); 

     conn.Close(); 
     conn.Dispose(); 

すべての私の手順は、メッセージをログに記録されません。私はこの概念を働かせようとしています。

答えて

4

あなたは(簡単な方法)から起動することができます。

List<int> idList = yourObjectList; 
List<int> nameList = yourObjectList; 

using (OracleConnection oraconn = new OracleConnection()) 
{ 
    oraconn.ConnectionString = "Your_Connection_string"; 

    using (OracleCommand oracmd = new OracleCommand()) 
    { 
     oracmd.Connection = oraconn; 

     oracmd.CommandType = CommandType.StoredProcedure; 
     oracmd.CommandText = "Your_Procedura_name"; 
     oraconn.Open(); 

     // To use ArrayBinding, you need to set ArrayBindCount 
     oracmd.BindByName = true; 
     oracmd.ArrayBindCount = idList.Count; 

     // Instead of single values, we pass arrays of values as parameters 
     oracmd.Parameters.Add("ids", OracleDbType.Int32, oyourObjectList.ToArray(), ParameterDirection.Input); 
     oracmd.Parameters.Add("names", OracleDbType.Varchar2, oyourObjectList.ToArray(), ParameterDirection.Input); 

     oracmd.ExecuteNonQuery(); 
     oraconn.Close(); 
    } 
} 

その後、デシベルでパッケージ/プロシージャを追加:

using (OracleConnection oraconn = new OracleConnection()) 
{ 
    oraconn.ConnectionString = "Your_Connection_string"; 

    using (OracleCommand cmd = new OracleCommand()) 
    { 

     cmd.Connection = oraconn; 

     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.CommandText = "Your_Procedure_name"; 
     oraconn.Open(); 


     OracleParameter idParam = new OracleParameter("i_idList", OracleDbType.Int32, ParameterDirection.Input); 
     idParam.CollectionType = OracleCollectionType.PLSQLAssociativeArray; 
     idParam.Value = idList.ToArray(); 
     idParam.Size = idList.Count; 

     OracleParameter nameParam = new OracleParameter("i_nameList", OracleDbType.Varchar2, ParameterDirection.Input); 
     nameParam.CollectionType = OracleCollectionType.PLSQLAssociativeArray; 
     nameParam.Value = nameList.ToArray(); 
     nameParam.Size = nameList.Count; 

     // You need this param for output 
     cmd.Parameters.Add("ret", OracleDbType.RefCursor).Direction = ParameterDirection.Output; 
     cmd.Parameters.Add(idParam); 
     cmd.Parameters.Add(nameParam); 

     conn.Open(); 

     //If you need to read results ... 
     using (OracleDataReader dr = cmd.ExecuteReader()) 
     { 
      while (dr.Read()) 
      { 
       ... 
      } 
     } 
     conn.Close(); 
    } 
} 

しかし、それは次のとおりです。

PROCEDURE Your_Procedure_name(
     name IN VARCHAR2, 
     id IN NUMBER 
    ) IS  
BEGIN 

    INSERT INTO your_table VALUES(id, name); 
END Your_Procedure_name; 

別のオプションです

のようなストアドプロシージャの新しい型を定義する必要があるため、より複雑です
TYPE integer_list IS TABLE OF Your_table.id_column%TYPE INDEX BY BINARY_INTEGER; 
// same for names 

create or replace TYPE T_ID_TABLE is table of number; 

のようなスキーマ・レベルのタイプを作成し、答えを

PROCEDURE Your_Procedure_name(
     v_ret IN OUT SYS_REFCURSOR, 
     i_idList integer_list, 
     i_nameList string_list) 
    IS 
    begin 
    -- Store passed object id list to array 
idList T_ID_TABLE := T_ID_TABLE(); 
    ... 
    begin 

    -- Store passed object id list to array 
    idList.Extend(i_idList.Count); 
    FOR i in i_idList.first..i_idList.last loop 
    idList(i) := i_idList(i); 
    END LOOP;  

    ... 
END Your_Procedure_name; 
+0

おかげのように、ストアドプロシージャでそれらを使用しています。私はそれを撃つだろう。 – user2316634

+0

私はTYPE integer_listを実行しています。あなたのテーブルはYour_table.id_cloumn%TYPE INDEX BY BINARY_INTEGERです。無効なSQL文が表示されます –

+0

'CREATE OR REPLACE TYPE inst_id_list IS TABLE OF INSTRUMENT.Inst_Id%TYPE INDEX BY BINARY_INTEGER; 'を試してください。 EvgenyLの提案された引数を、あなたのdbにすでに存在する実際のオブジェクトに置き換える必要があります。 (つまり、inst_idはテーブルINSTRUMENTのフィールドです)。 – dipdapdop

関連する問題