Пользовательская переменная .Net MySQL в качестве выходного параметра

#c# #mysql #asp.net #.net

#c# #mysql #asp.net #.net

Вопрос:

Я некоторое время искал, но ответы, которые я нахожу, обычно включают хранимые процедуры или другую функциональность.

Я пытаюсь выполнить средство чтения, а также вернуть скаляр в одном запросе. Я думал, что смогу сделать это с помощью выходного параметра, но я получаю исключение для проверки моего синтаксиса рядом с NULL = @rows_found (), поэтому, похоже, выходной параметр не инициализируется.

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

 command.CommandText = @"
    SELECT SQL_CALC_FOUND_ROWS
        accounting.*
    FROM
        accounting
    WHERE
        transaction_type = @transaction_type
    LIMIT
        @index, @results;

    SET @total_rows = FOUND_ROWS();
";

 command.Parameters.AddWithValue("transaction_type", transaction_type);
 command.Parameters.AddWithValue("index", index);
 command.Parameters.AddWithValue("results", results);

 MySqlParameter totalRows = new MySqlParameter("total_rows", 0);
 totalRows.Direction = System.Data.ParameterDirection.Output;
 command.Parameters.Add(totalRows);

 using (MySqlDataReader dr = command.ExecuteReader())
 {
     while (dr.Read())
         invoices.Add(new AccountingDataModel(dr));
 }

 invoices.Total = (int)totalRows.Value;
  

Ответ №1:

 cmd.Parameters["@output"].Value.ToString()
  

Используйте объект command для доступа к вашему параметру out ….
вы не можете получить доступ к параметру out напрямую.

Вы должны использовать как

 invoices.Total = Convert.ToInt32(command.Parameters["total_rows"].Value.ToString())
  

пример для хранимой процедуры

  MySqlCommand cmd = new MySqlCommand(nameOfStoredRoutine, connection);    
 cmd.CommandType = CommandType.StoredProcedure;    

//input parameters

 for (int i = 0; i < (parameterValue.Length / 2); i  )
 {
     cmd.Parameters.AddWithValue(parameterValue[i, 0], parameterValue[i, 1]);
     cmd.Parameters[parameterValue[i, 0]].Direction = ParameterDirection.Input;
     parameterList = parameterList   parameterValue[i,0]   " "   parameterValue[i,1]   " ";
  }

  //single output parameter
  cmd.Parameters.AddWithValue("@output", MySqlDbType.Int32);
  cmd.Parameters["@output"].Direction = ParameterDirection.Output;

  cmd.ExecuteNonQuery(); //Execute command


  return Convert.ToInt32(cmd.Parameters["@output"].Value.ToString());
  

Комментарии:

1. На самом деле это не заходит так далеко. Из того, что я прочитал, выходные параметры привязываются при закрытии datareader, и именно здесь возникает исключение. Еще раз, ответ, который вы предоставляете, связан с хранимой процедурой. Я подозреваю, что вы не можете использовать выходные параметры без хранимой процедуры, но нигде не смогли это подтвердить.

Ответ №2:

Кажется, что это невозможно. Из документации MySqlParameter членов для Direction свойства:

Возвращает или задает значение, указывающее, является ли параметр только для ввода, только для вывода, двунаправленным или параметром возвращаемого значения хранимой процедуры. Начиная с версии MySQL 4.1 и более ранних версий, единственным допустимым выбором является только ввод.

Таким образом, параметр, независимо от того, что вы установили Direction , всегда является входным параметром. Если вы измените значение с null на что-либо другое (например, 15), вы должны увидеть, что сгенерированный запрос имеет вид

 SET 15 = FOUND_ROWS()
  

В итоге я выполнил два запроса. Возможно, это не так эффективно, как могло бы быть, но, по крайней мере, это дает желаемый результат (с использованием EF Core):

 using (var context = new MyDbContext(...))
{
    context.Database.OpenConnection();
    var estates = context.MySet
        .FromSql("SELECT SQL_CALC_FOUND_ROWS * FROM myset LIMIT 25 OFFSET 25")
        .ToList();

    var cmd = context.Database.GetDbConnection().CreateCommand();
    cmd.CommandText = "SELECT FOUND_ROWS()";

    var rows = (long)cmd.ExecuteScalar();
    context.Database.CloseConnection();
}