#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();
}