#c# #mysql #sql #stored-procedures
#c# #mysql #sql #хранимые процедуры
Вопрос:
Я вызываю хранимую в MySQL процедуру из приложения на C #.
В зависимости от количества доступных записей я хочу вызывать разные операторы sql, поэтому я использовал оператор if . т. е. Если существует n записей, то используйте этот оператор, else …
По какой-то причине, как только я использую оператор if в сохраненной процедуре, хотя он будет работать при тестировании с использованием MySQL, он не будет работать при вызове его из моего приложения на C #. Фокус, похоже, просто не возвращается к вызывающей процедуре — приложение просто зависает на cmd.ExecuteNonQuery(); оператор.
Если я удалю оператор if в сохраненном proc и использую один sql select и вызову его из приложения C #, он будет работать нормально.
Есть какие-нибудь идеи, в чем дело?
C#:
private List<Record> GetListOfRecordsToProcess(string exchange, string shareCode, DateTime lastProcessedDate, Indicator indicator)
{
List<Record> list = new List<Record>();
MySqlConnection conn = new MySqlConnection(Data.cs);
MySqlCommand cmd = new MySqlCommand("get_records_to_process1", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@p_exchange", exchange);
cmd.Parameters.AddWithValue("@p_share_code", shareCode);
cmd.Parameters.AddWithValue("@p_from_date", lastProcessedDate);
cmd.Parameters.AddWithValue("@p_num_days", (int)indicator);
conn.Open();
//Create MySqlDataAdapter object and assign the query and connection to it
MySqlDataAdapter adapter = new MySqlDataAdapter(cmd);
cmd.ExecuteNonQuery();
MySQL:
CREATE DEFINER=`root`@`localhost` PROCEDURE `get_records_to_process1`(
p_exchange varchar(10),
p_share_code varchar(10),
p_from_date date,
p_num_days int)
BEGIN
-- variables
declare data_count int;
-- for debugging
declare counter int;
set counter = 1;
-- for debugging
call log_message_insert (5, concat(counter,' Start'));
set counter = counter 1;
call log_message_insert (5, concat(counter, ' p_exchange: ', p_exchange, ', p_share_code: ', p_share_code, ', p_from_date: ', p_from_date, ', p_num_days: ', p_num_days));
set counter = counter 1;
-- find out if we have enough data to calculate the ema
select count(1) into data_count
from eod_data_sharenet s1
where s1.exchange = p_exchange
and s1.share_code = p_share_code;
if data_count < p_num_days then
select *
from eod_data_sharenet
where 1 = 2; -- insufficient data, return nothing
else
select *
from eod_data_sharenet eds
where eds.exchange = p_exchange
and eds.share_code = p_share_code
and eds.trading_date > p_from_date;
end if;
END
Процедура изменена в соответствии с предложением Алекса и работает:
private List<Record> GetListOfRecordsToProcess(string exchange, string shareCode, DateTime lastProcessedDate, Indicator indicator)
{
List<Record> list = new List<Record>();
MySqlConnection connection = new MySqlConnection(Data.cs);
using (connection)
{
MySqlCommand cmd = new MySqlCommand("get_records_to_process", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@p_exchange", exchange);
cmd.Parameters.AddWithValue("@p_share_code", shareCode);
cmd.Parameters.AddWithValue("@p_from_date", lastProcessedDate);
cmd.Parameters.AddWithValue("@p_num_days", (int)indicator);
connection.Open();
MySqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
Record newRecord = new Record(Convert.ToDateTime(reader["trading_date"].ToString()),
reader["exchange"].ToString(),
reader["share_code"].ToString(),
Convert.ToInt32(Convert.ToDouble(reader["close"].ToString())));
list.Add(newRecord);
}
}
else
{
Console.WriteLine("No rows found.");
}
reader.Close();
}
connection.Close();
return list;
}
Комментарии:
1.
cmd.ExecuteNonQuery()
, это не вернет результат, пожалуйста, используйтеExecuteReader
2. Действительно. Еще раз StackOverflow спасает меня от моих ошибок школьника. Спасибо, Алекс. Модифицированный процесс, который я использовал для тестирования, добавлен выше.
Ответ №1:
Решение, предложенное Алексом:
private List<Record> GetListOfRecordsToProcess(string exchange, string shareCode, DateTime lastProcessedDate, Indicator indicator)
{
List<Record> list = new List<Record>();
using (MySqlConnection conn = new MySqlConnection(Data.cs))
{
conn.Open();
using (MySqlCommand cmd = new MySqlCommand("get_records_to_process", conn))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("@p_exchange", exchange);
cmd.Parameters.AddWithValue("@p_share_code", shareCode);
cmd.Parameters.AddWithValue("@p_from_date", lastProcessedDate);
cmd.Parameters.AddWithValue("@p_num_days", (int)indicator);
conn.Open();
using (MySqlDataReader reader = cmd.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
Record newRecord = new Record(Convert.ToDateTime(reader["trading_date"].ToString()),
reader["exchange"].ToString(),
reader["share_code"].ToString(),
Convert.ToInt32(Convert.ToDouble(reader["close"].ToString())));
list.Add(newRecord);
}
}
}
}
}
return list;
}