Я поддерживаю некоторые запросы, определенные в конструкторе адаптеров таблиц в Visual Studio, который используется в некоторых отчетах в приложении Windows Forms (.NET 2.0).Когда я запускаю приложение и выполняю определенный запрос, я получаю сообщение об ошибке: Ошибка арифметического переполнения при преобразовании выражения в тип данных smallmoney.Я был удивлен, поскольку запрос должен производить довольно небольшие суммы, поэтому я собрал запрос с помощью профилировщика SQL и выполнил точно такой же запрос в SQL Server Management Studio (очевидно, в той же базе данных).Здесь запрос выполняется без проблем, а smallmoney - «33.00»;не ближе к границе 214 748,3647.
Чтобы усложнить отладку, эта проблема возникает только в среде QA клиента и не воспроизводится локально (и база данных не может быть скопирована в среду разработки по юридическим причинам).Это делает цикл отладки очень медленным, поскольку сборка и развертывание новых версий в среде клиента занимает до 30 минут, поэтому я был бы очень признателен за некоторые подсказки, которые позволят мне точно определить эту проблему с минимальными экспериментами.Привязка к запросу в SQL Studio мне мало помогает, поскольку я не могу заставить его выдавать те же ошибки.
Вот запрос:
SELECT CONVERT(varchar, Events.Occurred, 102) AS Day, Users.Name, COUNT(*) AS Deleted_Invoices, SUM(i.TotalExVat + i.TotalVat) AS Total
FROM Events WITH (nolock) INNER JOIN
Users WITH (nolock) ON Events.UserID = Users.UserID INNER JOIN
Types AS t WITH (nolock) ON t.TypeID = Events.TypeID INNER JOIN
InvoicesEvents AS ie ON ie.EventID = Events.EventID INNER JOIN
Invoices AS i ON i.InvoiceID = ie.InvoiceID
WHERE (Events.Occurred BETWEEN @startDate AND @endDate) AND (t.Name = 'InvoiceDeleted')
GROUP BY CONVERT(varchar, Events.Occurred, 102), Users.Name
ORDER BY Day, Users.Name
TotalExVat и TotalVat issmallmoney не нуль.Поле «Всего» в таблице данных сопоставлено с «System.Decimal».Я мог бы попытаться преобразовать smallmoney в деньги в выражении, но зачем мне это делать, если в SQL Studio все работает нормально?
Исключение, которое я получаю: Тип исключения: System.Data.SqlClient.SqlException Сообщение об исключении: Ошибка арифметического переполнения при преобразовании выражения в тип данных smallmoney.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlDataReader.HasMoreRows()
at System.Data.SqlClient.SqlDataReader.ReadInternal(Boolean setTimeout)
at System.Data.SqlClient.SqlDataReader.Read()
at System.Data.Common.DataAdapter.FillLoadDataRow(SchemaMapping mapping)
at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue)
at System.Data.Common.DataAdapter.Fill(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)
at ... (calling code)
Обновление
Изменение SUM (i.TotalExVat + i.TotalVat) наSUM (i.TotalExVat) + SUM (i.TotalVat) устранил ошибку, но я до сих пор не понимаю, почему, поскольку в полученных результатах нет переполнения малых денежных сумм.
Обновление 2
Новые проблемы.Теперь проблема с кастингом маленьких денег исчезла, но теперь у меня проблема с тайм-аутом.Другой запрос, используемый в том же отчете, выполняется в течение 5-6 секунд, если выполняется в SSMS.При запуске в настольном адаптере время ожидания истекает через 10 минут.Другие запросы выполняются, как и ожидалось, с тем же результатом, что и в SSMS.Это поддерживает моё подозрение, что что-то гнилое происходит, когда мой адаптер таблицы пытается запросить базу данных.
Обновление 3
Это начинает становиться странным.Запрос проблемы smallmoney был заполнен запросом номер пять в серии запросов, использованных для генерации отчета.После того, как я применил исправление, упомянутое в первом обновлении, я получаю тайм-ауты в первом из запросов.Этот запрос выполнялся без проблем, когда smallmoney был переполнен в последующем запросе.В чем может быть причина?
Запрос выполняется, когда запрос smallmoney выдает ошибку, и НЕ выполняется при его работе:
SELECT u.Name AS Username, rea.Text AS DeleteReason, COUNT(*) AS DeletedRegistrations, SUM(r.Shipments) AS DeletedShipments
FROM RecordingsEvents AS re WITH (nolock) INNER JOIN
Events AS e WITH (nolock) ON e.EventID = re.EventID INNER JOIN
Reasons AS rea WITH (nolock) ON rea.ReasonID = e.ReasonID INNER JOIN
Users AS u WITH (nolock) ON u.UserID = e.UserID INNER JOIN
Recordings AS r ON r.RecordingID = re.RecordingID
WHERE (rea.Category = 'DeleteRecording') AND (e.Occurred BETWEEN @startDate AND @endDate)
GROUP BY u.Name, rea.Text
ORDER BY Username, MAX(rea.SortOrder)
Приведенный выше запрос работает, если я ограничиваю интервал датгде запрос smallmoney дал результат 30.0.Если я расширяю интервал дат до периода, когда запрос smallmoney также не выполнялся, я получаю тайм-аут.Как я могу получить тайм-аут в запросе, который выполняется ДО запроса smallmoney, если он работает нормально, когда запрос smallmoney не выполняется?Выполнение всех запросов в SSMS работает как положено.Кстати, запросы выполняются синхронно.