2013-04-24 15 views
5

Tôi có một thủ tục được lưu trữ PL/SQL lấy 4 đầu vào. Một trong những đầu vào đó là một mảng kết hợp (Oracle Type: Table of VARCHAR2 (1) index bởi PLS_INTEGER).C# 2010, ODP.net, gọi thủ tục được lưu trữ qua mảng

Tôi muốn có một chương trình C# gọi thủ tục được lưu trữ này với các đầu vào thích hợp bao gồm mảng kết hợp.

Tôi đang sử dụng ODP.net 11.2 với Visual C# 2010 Express và Oracle 11gR2.

Tôi không thể tìm thấy bất kỳ ví dụ hay về cách chuyển mảng sang quy trình pl/sql từ C#. Ai có thể cho tôi một ví dụ? Sau tài liệu Oracle chính xác cho tôi lỗi nói sai số hoặc loại đối số.

C của tôi # Code:

 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(); 

Tất cả các thủ tục của tôi, không có gì ghi lại một tin nhắn. Tôi chỉ cố gắng để có được khái niệm này để làm việc.

Trả lời

4

Bạn có thể bắt đầu từ (cách đơn giản hơn):

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(); 
    } 
} 

Sau đó, thêm gói/thủ tục trong db:

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

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

lựa chọn khác là:

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(); 
    } 
} 

Nhưng đó là phức tạp hơn, vì bạn cần xác định loại mới cho quy trình được lưu trữ, như

TYPE integer_list IS TABLE OF Your_table.id_column%TYPE INDEX BY BINARY_INTEGER; 
// same for names 

tạo ra một kiểu lược đồ cấp như

create or replace TYPE T_ID_TABLE is table of number; 

Và sau đó sử dụng chúng trong các Stored Procedure, như

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

Cảm ơn cho câu trả lời. Tôi sẽ cho nó một viên đạn. – user2316634

+0

khi tôi chạy TYPE integer_list IS TABLE OF Your_table.id_cloumn% TYPE INDEX BY BINARY_INTEGER; Nó hiển thị câu lệnh sql không hợp lệ –

+0

Thử 'TẠO HOẶC THAY THẾ TYPE inst_id_list LÀ BẢNG INSTRUMENT.Inst_Id% LOẠI INDEX BỞI BINARY_INTEGER;'. Bạn cần phải thay thế các đối số gợi ý của EvgenyL bằng các đối tượng thực đã tồn tại trong db của bạn. (ví dụ: inst_id là một trường trong bảng INSTRUMENT). – dipdapdop