【问题标题】:Calling oracle stored procedure repeatedly反复调用oracle存储过程
【发布时间】:2012-01-03 08:57:23
【问题描述】:

在 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
        }
     }
}

有没有更好的方法来做到这一点?

【问题讨论】:

  • 这听起来可能是个坏主意,但如果没有清楚地了解您要完成的工作,我无法提供建议。你能解释一下你在做什么吗?
  • @wweicker - 我正在尝试从每个 foreach 循环中提取数据并将该数据输入到 oracle 表中。示例:第一个循环给出 5 个值:"1, 2, Null, Null, Null) 第二个循环给出 (1, 2, 3, Null, Null) 第三个循环给出 (1, 2, 3, 4, 5)。而 i只需要按此顺序排列的值。
  • 您想在内部循环的每次迭代中将数据插入到 Oracle 表中?
  • @wweicker- 是的,外循环也是。就像第一个循环将有 1、2、3、null、null.. 第二个循环将从第一个循环 1、4、5、5、null 中获取一个值并执行插入。依此类推,第三个循环将从第二个循环中获取一个值并进行插入。

标签: c# oracle stored-procedures


【解决方案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 的所有六个值。

    因此,无需在每次迭代中调用您的过程,只需将值存储在一个数组中,然后在最后一次大调用中将其传递给您的过程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-13
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      • 2011-03-13
      • 2011-04-25
      • 2010-12-16
      • 2015-05-22
      相关资源
      最近更新 更多