2011-11-21 223 views
2

在foreach循環內一次又一次調用存儲過程以將數據插入Oracle表是否是一種很好的做法?或者有另一種方法可以做到這一點?反覆調用oracle存儲過程

我有以下步驟:

procedure proc1 (id  in varchar2, 
       level in varchar2, 
       title in varchar2, 
       p_id in varchar2, 
       url in varchar2) 

這是代碼調用它:

foreach (var c in xDoc.Descendants("cat")) 
{ 
    // call store procedure provide all values 

    foreach (var a in xDoc.Descendants("abc")) 
    { 
     // call store procedure provide values 

     foreach (var d in xDoc.Descendants("def")) 
     { 
      // call stored procedure provide values 
     } 
    } 
} 

有沒有更好的方式來做到這一點?

+0

這聽起來像這可能是一個壞主意,但沒有一個清晰的理解你想完成什麼,我不能提供建議。你能解釋一下你在做什麼嗎? – wweicker

+0

@wweicker - 我試圖從每個foreach循環中提取數據並將該數據輸入到oracle表中。例如:第一個循環給出5個值:「1,2,Null,Null,Null)第二個循環給出(1,2,3,Null,Null)第三個循環給出(1,2,3,4,5)。 – NoviceMe

+0

您想要在內部循環的每次迭代中將數據插入到Oracle表中嗎? – wweicker

回答

4

我會親自構建存儲過程給你你想要的表格,這樣你只需要調用一次。像這樣多次調用這個過程是非常低效的,因爲數據庫會多次生成一個結果集,並且會產生網絡開銷。如果您創建的過程返回所需的表,而不是其中的一小部分,則可以調用該過程一次,並用光標遍歷表。

2

假設你使用ODP.NET,您可以使用array binding單個數據庫往返期間,你的程序多次調用。除非您將一個數組(而不是一個值)分配給OracleParameter.Value並相應地設置了OracleCommand.ArrayBindCount,否則幾乎可以像通常那樣綁定參數。

讓我給你一個簡單的例子,我相信你不會有麻煩它適應您的需求...

甲骨文:

CREATE TABLE TEST (
    ID INT PRIMARY KEY 
); 

CREATE OR REPLACE PROCEDURE TEST_INSERT (ID IN NUMBER) AS 
BEGIN 
    INSERT INTO TEST VALUES(ID); 
END TEST_INSERT; 

C#:

using (var conn = new OracleConnection("your connection string")) { 

    conn.Open(); 

    var cmd = conn.CreateCommand(); 
    cmd.CommandType = System.Data.CommandType.StoredProcedure; 
    cmd.CommandText = "TEST_INSERT"; 
    var param = cmd.Parameters.Add("ID", OracleDbType.Int32, System.Data.ParameterDirection.Input); 

    int[] arr = { 1, 2, 3, 4, 5, 6 }; 
    param.Value = arr; 
    cmd.ArrayBindCount = arr.Length; 
    cmd.ExecuteNonQuery(); 

} 

這段代碼執行後,TEST表將包含arr的所有六個值。

因此,不要在每次迭代中調用您的過程,只需記住數組中的值,然後在最後一次大調用中將其傳遞給您的過程。