在.net中调用多个存储过程,该怎么做?

时间:2010-01-15 20:42:07

标签: .net sql informix

我需要多次调用存储过程,我正在使用informix。我想知道如果使用相同的连接多次调用一个过程是相同的,生成带有多次调用存储过程的字符串并将其作为查询执行。

这是代码示例:

IfxCommand cmd = new IfxCommand("storeData", myconn);
cmd.CommandType = CommandType.StoredProcedure;
for (int i = 0; i < lbim; i++)
{

  cmd.Parameters.Add("id", IBM.Data.Informix.IfxType.VarChar, 255).Value = info.id;
  cmd.Parameters.Add("descripcionDescuentoImpuesto", IBM.Data.Informix.IfxType.VarChar, 255).Value = info.data[i].value;
  try
  {
     IfxDataReader myreader = cmd.ExecuteReader();
     if (myreader.Read())
     {
        Boolean aux = (Boolean)myreader[0];
        myreturn = aux;
     }
     myreader.Close();
  }
  catch (IfxException ex)
  {
  }
  cmd.Parameters.Clear();
}

问题是每个存储过程都返回true或false。

由于

2 个答案:

答案 0 :(得分:2)

出于性能原因,最好的方法是在循环之前准备命令。在循环内部,您可以设置参数值并执行阅读器。 我还会用两件事改进代码:

  • 使用工厂;通过这种方式,您可以在以后轻松切换OdbcDriver和IfxDriver之间的其他内容;
  • 错误处理:您应该在最后一节中关闭读者或使用“usings”子句,以保证在异常情况下释放资源;我更喜欢使用,因为在更复杂的场景中,最终部分变得非常复杂。

此更改将提供以下代码:

DbProviderFactory dbfactory;
dbfactory = DbProviderFactories.GetFactory("IBM.Data.Informix");
using (myconn = dbfactory.CreateConnection())
{
    myconn.ConnectionString = " ... ";
    myconn.Open();
    DbCommand cmd = dbfactory.CreateCommand();
    cmd.Connection = myconn;
    cmd.CommandText = "storeData";
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Parameters.Clear();

    DbParameter parameter = dbfactory.CreateParameter();
    parameter.ParameterName = "id";
    parameter.DbType = DbType.String;
    parameter.Size = 255; // probably not necessary
    cmd.Parameters.Add(parameter);

    parameter = dbfactory.CreateParameter();
    parameter.ParameterName = "descripcionDescuentoImpuesto";
    parameter.DbType = DbType.String;
    parameter.Size = 255;
    cmd.Parameters.Add(parameter);

    cmd.Prepare();
    for (int i = 0; i < lbim; i++)
    {
        cmd.Parameters[0].Value = info.id;
        cmd.Parameters[1].Value = info.data[i].value;
        using (DbDataReader myreader = cmd.ExecuteReader()) {
            if (myreader.Read())
            {
                Boolean aux = (Boolean)myreader[0];
                myreturn = aux;
            }
        }
    }
}

现在代码要长得多,但我认为优势很普遍。更好的方法是使用Spring.NET(我只是学习它) - 代码大小的一半,驱动程序独立(类似于工厂方法),在异常情况下自动处理资源。 我也会使用

myreturn = (bool)cmd.ExecuteScalar();

而不是数据阅读器。 接下来是我使用命令类型文本而不是“执行过程storeData(?,?)”。这是因为在很久以前的某些场景中存在Informix错误。可能已经修复了 - 所以可能不再需要了。

答案 1 :(得分:1)

您应该为每个调用创建一个新的IfxCommand对象,因此只需将该部分代码移动到for循环中。实际上,无论您使用什么提供商,都是如此。