Вызов нескольких хранимых процедур в.net, как это сделать?

Мне нужно вызывать хранимую процедуру несколько раз, я использую 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();
}

Проблема в том, что каждая хранимая процедура возвращает истину или ложь.

Спасибо

2 ответа

Решение

Из соображений производительности лучше всего подготовить команду перед циклом. Внутри цикла вы можете установить значения параметров и запустить считыватель. Я бы также улучшил код двумя вещами:

  • использование заводов; таким образом, вы можете легко переключаться между OdbcDriver и IfxDriver или чем-то еще в будущем;
  • обработка ошибок: вы должны закрыть читателя в секции finally или использовать предложение "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 в некоторых сценариях, которые я получил давно. Возможно, что это уже исправлено - так, вероятно, это больше не нужно.

Вы должны создавать новый объект IfxCommand для каждого вызова, поэтому просто переместите эту часть кода в цикл for. На самом деле это так, независимо от того, какого провайдера вы используете.

Другие вопросы по тегам