Blazor 服务器应用程序中不允许从数据类型 datetime 到 int 的隐式转换错误

问题描述 投票:0回答:1

我正在使用 Dapper 构建 Blazor 应用程序。

我有一个包含以下代码的存储过程,当我在 SSMS 中测试它时,它执行得很好:

ALTER PROCEDURE [dbo].[GlobalCnsldSalesCurrencyConversionSelectSingle]
(
    -- Add the parameters for the stored procedure here
    @Currency nvarchar(50),
    @CalendarDate datetime
)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON

    -- Insert statements for procedure here
    DECLARE @FiscalPeriod int;
    SELECT @FiscalPeriod = CalendarFiscalPeriod FROM GlobalCnsldSalesDateDim WHERE CalendarDate = @CalendarDate
    
    SELECT Rate
    FROM GlobalCnsldSalesCurrencyConversion
    WHERE FromCurrency = @Currency AND ToCurrency = 'USD' AND FiscalPeriodSid = @FiscalPeriod
END

我从我的应用程序中的方法中调用它,如下所示:

public async Task<ExchangeRateDto> GetCnsldCurrencyExchangeRate(string currency, DateTime calendarDate) =>
    await _db.LoadDataAzureSingleSP<ExchangeRateDto, dynamic>(storedProcedure: "dbo.procGlobalCnsldSalesCurrencyConversionSelectSingle", new { Currency = currency, CalendarDate = calendarDate });

LoadDataAzureSingleSP 代码是:

public async Task<T> LoadDataAzureSingleSP<T, U>(string storedProcedure, U parameters)
{
    string connectionString = _configAzure.GetConnectionString(ConnectionStringAzure);

    using (IDbConnection connection = new SqlConnection(connectionString))
    {

        return await connection.QuerySingleAsync<T>(storedProcedure, parameters, commandType: CommandType.StoredProcedure);

    }
}

我已经检查了传递给该方法的参数,它们是正确的,但我仍然收到以下错误:

Microsoft.Data.SqlClient.SqlException (0x80131904):不允许从数据类型 datetime 到 int 的隐式转换。使用 CONVERT 函数运行此查询。

我完全不知道是什么原因造成的。

有什么想法吗?

c# .net sql-server dapper
1个回答
0
投票

事实

错误

Microsoft.Data.SqlClient.SqlException (0x80131904):不允许从数据类型 datetime 到 int 的隐式转换。使用 CONVERT 函数运行此查询。

告诉我们:

  • 错误发生在RDBMS处,所以成功到达RDBMS
  • 这是将
    datetime
    转换为
    int
  • 的问题
  • 存储过程是已知的,否则它会抱怨

因此,您需要弄清楚价值转换可能发生在哪里。

思考事实

第一个这样的地方是声明,特别是

@CalendarDate datetime

期望收到

datetime
,如果您碰巧传递了
int
,那么您将收到上面引用的错误。如果这是罪魁祸首,那么某些东西会将您的
DateTime
转换为
int
。如果是这样的话,那么这个
int
可能以其整数方式表示自过去给定时刻以来经过的时间。

可能发生这种情况的第二条可能的路线是

SELECT @FiscalPeriod = CalendarFiscalPeriod FROM GlobalCnsldSalesDateDim WHERE CalendarDate = @CalendarDate

在这种情况下

CalendarFiscalPeriod
datetime
并且它到
int
的隐式转换失败。

因此,您需要确定这两个候选者中的哪一个导致了您的错误。

认识论:如何确定罪魁祸首?

有多种方法可以做到这一点。您可以查看 RDBMS 的日志,看看如何调用存储过程、实际传递了什么以及是否符合您的期望。如果调用正确,则错误位于存储过程内部,并且您的手动测试并未使其显现出来。例如,考虑没有要分配的会计期间的情况。但是,如果调用本身是错误的,那么错误就在您的 C# 代码中,您需要在那里修复它。

确定它的另一种方法是暂时消除第二个可能的罪魁祸首(在临时更改的存储过程或其临时副本中将一些硬编码的

int
分配给
@FiscalPeriod
),并查看问题是否仍然发生。如果是这样,则传递参数时会出现 C# 错误。如果不是,那么你的第二个罪魁祸首就有错误了。

解决方案

解决方案很大程度上取决于问题是什么。您需要调整 C# 代码,以便它以正确的方式传递参数,或者您只需要在分配

datetime
时以显式方式将
int
转换为
@FiscalPeriod
。请参阅https://www.sqlservercentral.com/forums/topic/convert-datetime-to-integer

© www.soinside.com 2019 - 2024. All rights reserved.