Здравствуйте, Olaf, Вы писали:
O>Здравствуйте, Vladek, Вы писали:
V>>Вызываю хранимку, в результате ... V>>... V>>Ну вот что это, куда копать?
O>А как выглядит сама процедура ?
Процедура большая и сложная, но с ней всё в порядке, дело точно не в ней.
Здравствуйте, Vladek, Вы писали:
V>Процедура большая и сложная, но с ней всё в порядке, дело точно не в ней.
Хорошо, что вы уверены в процедуре. Но у меня первые подозрения упали именно на процедуру, т.к. сомневаюсь, что стандартный метод Ado.Net GetValues так предсказуемо просто складывает значения двух выбранных колонок, причем как я понимаю проблема носит плавающий характер, то колонка А, то Б.
Вызываю хранимку, в результате 7 столбцов — два последних типа decimal (назовём их A и Б). SqlDataReader считывает их некорректно — значение последнего столбца равно сумме A и Б. Ну то есть, если в БД A=1 и Б=2, то вызов dataReader.GetDecimal(dataReader.GetOrdinal("Б")) даёт 3! Как такое вообще может быть? Иногда такое же происходит и со столбцом A, значения тоже как-то портятся (пока не понял как именно). Остальные столбцы считываются нормально.
ASP.NET MVC 4, .NET 4.5.1, Sql Server 2008 R2 (отдельный сервер)
internal static ICollection<T> ExecuteProcedure<T>(
this IDbConnection connection,
string procedure, object parameters,
Func<IDataRecord, T> factory)
{
using (var command = connection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = procedure;
TryAddParameters(command, parameters); // заполняет command.Parametersif (connection.State != ConnectionState.Open)
{
connection.Open();
}
if (log.Switch.ShouldTrace(TraceEventType.Information))
{
TraceCommand(command);
}
using (var dataReader = command.ExecuteReader(CommandBehavior.SingleResult))
{
var items = new List<T>();
while (dataReader.Read())
{
if (log.Switch.ShouldTrace(TraceEventType.Verbose))
{
var values = new object[dataReader.FieldCount];
dataReader.GetValues(values);
log.TraceData(TraceEventType.Verbose, 1, values); // вот тут уже видно некорректные значения
}
items.Add(factory(dataReader)); // factory делает из IDataRecord объект, значения к этому моменту уже испорчены
}
return items.ToArray();
}
}
}
Здравствуйте, Olaf, Вы писали:
O>Здравствуйте, Vladek, Вы писали:
V>>Процедура большая и сложная, но с ней всё в порядке, дело точно не в ней.
O>Хорошо, что вы уверены в процедуре. Но у меня первые подозрения упали именно на процедуру, т.к. сомневаюсь, что стандартный метод Ado.Net GetValues так предсказуемо просто складывает значения двух выбранных колонок, причем как я понимаю проблема носит плавающий характер, то колонка А, то Б.
Нет, вроде бы имеет значение к какому столбцу обратились раньше. Если прочитать Б, то и А будет некорректным, если сначала прочитать А, то он будет корректным. Б всегда некорректен. Медитирование над исходниками SqlDataReader результатов не принесло. Он читает поля в буфер, но не суммирует их конечно же.
попробуй запустить SqlProfiler и посмотреть, какие данные приходят и какие параметры отправляются.
я никогда ничего подобного не видел, и единственная мысль, которая у меня возникает: отправляются неверные параметры
Всё сказанное выше — личное мнение, если не указано обратное.
Здравствуйте, Olaf, Вы писали:
O>Здравствуйте, Vladek, Вы писали:
V>>Процедура большая и сложная, но с ней всё в порядке, дело точно не в ней.
O>Хорошо, что вы уверены в процедуре. Но у меня первые подозрения упали именно на процедуру, т.к. сомневаюсь, что стандартный метод Ado.Net GetValues так предсказуемо просто складывает значения двух выбранных колонок, причем как я понимаю проблема носит плавающий характер, то колонка А, то Б.
Отбой, дело было действительно в процедуре или значениях параметров. Нужно было передавать значение окончания периода времени и вот такой код давал ошибку: