首页 > 解决方案 > SqlException:将 ****** 值 '******' 转换为数据类型 ****** 时转换失败

问题描述

我有一个 ASP.NET MVC Web 应用程序,在 Azure 中运行,针对 Azure SQL 数据库,使用 EF 6。

昨天我在打开一个使用存储过程获取一些数据的页面时发现了一个错误:

System.Data.SqlClient.SqlException (0x80131904):
将 ****** 值 '******' 转换为数据类型 ****** 时转换失败

星号在错误消息中,不是我放在那里的。

错误发生在具有单行的控制器操作中:

return JsonConvert.SerializeObject(Uow.StoredProcedures.GetClientLiasonDetails(highlightOnIfi, hasMedicalIssues, medicalSummaryStatusIds, duplicate, azContactUserId).ToList());

我本来希望调用GetClientLiasonDetails,但由于某种原因,Elmah 中的堆栈跟踪(见下文)没有显示这一点。假设它进入GetClientLiasonDetails,存储过程将像这样被触发:

return DbContext.Database.SqlQuery<ClientLiasonDetailsResult>("dbo.GetClientLiasonDetails @HighlightOnIfi, @HasMedicalIssues, @MedicalSummaryStatusId, @Duplicate, @AzContactUserID", highlightOnIfiParam, hasMedicalIssuesParam, medicalSummaryStatusIdsParam, duplicateParam, azContactUserIdParam);

每次打开页面时都会发生错误,但到目前为止,我无法在开发数据库中复制它,或者通过调用生产数据库中的存储过程,即使以网站用户身份登录也是如此。

数据库启用了透明数据加密,但没有列加密或数据屏蔽。

我尝试查看 DMV,虽然我可以看到插入 ELMAH 错误的 SQL,但没有迹象表明导致错误的 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);

来自 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)

标签: sql-serverazure-sql-databaseazure-web-app-service

解决方案


推荐阅读