【问题标题】:Calling multiple stored procedures in .net, how to do it?在.net中调用多个存储过程,怎么做?
【发布时间】:2010-01-15 20:42:07
【问题描述】:

我需要多次调用存储过程,我正在使用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();
}

问题是每个存储过程都返回真或假。

谢谢

【问题讨论】:

  • 忽略异常肯定有点可疑,不是吗?

标签: .net sql informix


【解决方案1】:

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

  • 使用工厂;这样您以后就可以轻松地在 OdbcDriver 和 IfxDriver 之间切换;
  • 错误处理:您应该在 finally 部分关闭阅读器或使用“usings”子句保证在出现异常时释放资源;我更喜欢 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 错误。可能这已经修复了 - 所以可能不再需要了。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 为什么会有好处?我不知道 .Add 操作的确切语义(如果它覆盖了相同参数名称的先前设置,那么一切都很好;如果没有,可能会有问题)。但是在普通的 SQL 编程中,一次准备一条语句并使用不同的参数集多次执行它是一个好主意。
    • 其实我在写完这篇文章后检查了文档,看来你确实可以重用命令对象,只要关闭命令对象上的任何数据读取器。
    猜你喜欢
    • 2021-09-24
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 2012-02-29
    • 2013-11-23
    相关资源
    最近更新 更多