У меня есть веб-приложение ASP.NET MVC, работающее в Azure для базы данных SQL Azure с использованием EF 6.
Вчера я обнаружил ошибку при открытии страницы, которая использует хранимую процедуру дляполучить некоторые данные:
System.Data.SqlClient.SqlException (0x80131904):
Преобразование не удалось при преобразовании значения ****** '******' в тип данных******
Звездочки в сообщении об ошибке , не поставлены мной.
Ошибка возникает в действии контроллера содна строка:
return JsonConvert.SerializeObject(Uow.StoredProcedures.GetClientLiasonDetails(highlightOnIfi, hasMedicalIssues, medicalSummaryStatusIds, duplicate, azContactUserId).ToList());
Я бы ожидал, что для вызова GetClientLiasonDetails
, но по какой-то причине трассировка стека в Эльмах (см. ниже) не показывает этого.Предполагая, что он превратился в GetClientLiasonDetails
, хранимая процедура будет запущена следующим образом:
return DbContext.Database.SqlQuery<ClientLiasonDetailsResult>("dbo.GetClientLiasonDetails @HighlightOnIfi, @HasMedicalIssues, @MedicalSummaryStatusId, @Duplicate, @AzContactUserID", highlightOnIfiParam, hasMedicalIssuesParam, medicalSummaryStatusIdsParam, duplicateParam, azContactUserIdParam);
Ошибка происходит каждый раз, когда я открываю страницу, но до сих пор я не смог ее воспроизвести вбазу данных dev или путем вызова хранимой процедуры в рабочей базе данных, даже если вы вошли в систему как пользователь веб-сайта.
В базе данных включено прозрачное шифрование данных, но нет шифрования столбцов или маскирования данных.
Я пытался посмотреть в DMV, и хотя я вижу SQL, который вставляет ошибку ELMAH, нет никаких признаков SQL, вызывающего ошибку.
Кажется, что нетлюбые другие проблемы с системой - другие вызовы хранимых процедур работают нормально.
Обновление 1
Хранимая процедура, вызывающая проблему (GetClientLiasonDetails
), использует функцию SQL Server (GetClientLiasonFullData
) чтобы получить его данные.Когда я написал эту функцию пару лет назад, она использовала string_split
, которая работала на моем локальном SQL Server и работала в Azure SQL, но вызвала ошибку , когдаБаза данных Azure SQL была экспортирована.
Чтобы обойти проблему экспорта, я написал свою собственную версию string_split
(функция с именем AzStringSplit
).
Кажется, что причина сегодняшнего дняпроблема была где-то в AzStringSplit
, потому что я только что переключил GetClientLiasonFullData
на использование встроенного string_split
вместо AzStringSplit
, и проблема исчезла.
Обновление 2
Я собирался опубликовать код для AzStringSplit
, чтобы кто-то мог объяснить, как это вызвало проблему, но затем я безучастно задумался, была ли перекомпиляция GetClientLiasonFullData
, которая устранила проблему, а неизменение на string_split
... Я переключил функцию на использование AzStringSplit
, и она все еще работает.
Итак, проблема была исправлена путем перекомпиляции функции GetClientLiasonFullData
.Код ниже приведен ниже, на случай, если кто-нибудь сможет объяснить, как он работал раньше, затем вызвал ошибку и теперь работает снова.
CREATE FUNCTION [dbo].[GetClientLiasonFullData](
@HighlightOnIfi VARCHAR(MAX),
@HasMedicalIssues VARCHAR(MAX),
@MedicalSummaryStatusId VARCHAR(MAX),
@Duplicate VARCHAR(MAX),
@AzContactUserID NVARCHAR(128)
)
RETURNS TABLE
AS
RETURN
SELECT gcld.ClientId,
gcld.Client,
anu.FirstName AS AzContactUserFirstName,
anu.LastName AS AzContactUserLastName,
gcld.ProgrammeId,
gcld.Programme,
gcld.ProgrammeOrder,
gcld.ParticipantId,
gcld.ParticipantFirstName,
gcld.ParticipantLastName,
gcld.HighlightOnIfi,
g.Description AS Gender,
gcld.HasMedicalIssues,
gcld.MedicalSummaryStatusId,
mss.Description AS MedicalSummaryStatus,
CASE WHEN mss.DisplaySortOrder = 1 THEN 1 WHEN Duplicate = 1 THEN 2 ELSE mss.DisplaySortOrder + 1 END AS StatusOrder,
gcld.HasNotes,
Duplicate,
Withdrawn
FROM dbo.GetClientLiasonData() gcld
INNER JOIN dbo.Gender g
ON g.GenderId = gcld.GenderId
INNER JOIN dbo.MedicalSummaryStatus mss
ON mss.MedicalSummaryStatusId = gcld.MedicalSummaryStatusId
INNER JOIN dbo.AspNetUsers anu
ON anu.Id = gcld.AzContactUserId
INNER JOIN AzStringSplit(@HighlightOnIfi, ',') hoi
ON gcld.HighlightOnIfi = hoi.value
INNER JOIN AzStringSplit(@HasMedicalIssues, ',') hmi
ON gcld.HasMedicalIssues = hmi.value
INNER JOIN AzStringSplit(@MedicalSummaryStatusId, ',') mssi
ON gcld.MedicalSummaryStatusId = mssi.value
INNER JOIN AzStringSplit(@Duplicate, ',') d
ON gcld.Duplicate = d.value
WHERE (@AzContactUserID IS NULL
OR gcld.AzContactUserId = @AzContactUserID);
Stack Trace от Elmah
System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting the ****** value '******' to data type ******.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
at System.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
at System.Data.SqlClient.SqlDataReader.Read()
at System.Data.Entity.Core.Objects.Internal.ShapelessBufferedDataRecord.Initialize(String providerManifestToken, DbProviderServices providerSerivces, DbDataReader reader)
at System.Data.Entity.Core.Objects.Internal.BufferedDataReader.Initialize(String providerManifestToken, DbProviderServices providerServices, Type[] columnTypes, Boolean[] nullableColumns)
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters)
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass69`1.<ExecuteStoreQueryReliably>b__68()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass69`1.<ExecuteStoreQueryReliably>b__67()
at System.Data.Entity.Infrastructure.DbExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryReliably[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters)
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQuery[TElement](String commandText, ExecutionOptions executionOptions, Object[] parameters)
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Az.Ems.Web.Controllers.ParticipantsController.OverviewResults(Boolean[] highlightOnIfi, Boolean[] hasMedicalIssues, Int32[] medicalSummaryStatusIds, Boolean[] duplicate, String azContactUserId) in C:\Users\Jon\Source\Repos\EMS\Az.Ems.Web\Controllers\ParticipantsController.cs:line 510
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)