反复调用oracle存储过程

时间:2011-11-21 21:43:22

标签: c# oracle stored-procedures

在foreach循环中一次又一次地调用存储过程以将数据插入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
        }
     }
}

有更好的方法吗?

2 个答案:

答案 0 :(得分:4)

我会亲自设计存储过程,为您提供所需的表,以便您只需调用一次。像这样多次调用该过程是非常低效的,因为数据库多次生成结果集并且您有网络开销。如果创建过程以返回所需的表,而不是它的一些部分,则可以调用该过程一次并使用光标遍历该表。

答案 1 :(得分: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中的所有六个值。

因此,不是在每次迭代中调用您的过程,只需记住数组中的值,然后在最后一次大调用中将其传递给您的过程。