You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何SQL MAX(DateTime)查询在SSMS正常,C#调用时丢失毫秒值

问题排查与解决方案

根因定位

问题并不出在SQL查询逻辑层面,从Azure SQL数据库返回的DateTime值本身自带毫秒精度,丢失毫秒的原因是你在GetLastSeenList方法中拼接CSV字符串时,直接对object类型的DateTime值执行了默认转换:C#中DateTime类型的默认ToString()输出不会携带毫秒部分,因此看起来就像被截断了。

验证方法

你可以在GetLastSeenList的循环中加入调试代码确认值本身的精度:

foreach(var record in list)
{
    // 输出毫秒值验证数据本身没有丢失精度
    Console.WriteLine(((DateTime)record[1]).Millisecond);
    sb.Append($"{record[0]} {record[1]},");
}

修复方案

方案1:C#代码层调整(推荐)

在拼接字符串时明确指定DateTime的输出格式,保证和SSMS输出的时间格式完全对齐,保留毫秒:

// 将原来的sb.Append行替换为以下代码
string name = record[0].ToString();
DateTime lastSeen = (DateTime)record[1];
sb.Append($"{name} {lastSeen:yyyy-MM-dd HH:mm:ss.fff},");

方案2:SQL查询层调整

如果希望直接从数据库返回格式化好的字符串,可以修改查询语句,使用SQL Server的CONVERT函数指定带毫秒的输出格式:

select 
  Name, 
  CONVERT(VARCHAR(23), MAX(DTStamp), 121) AS Last_Seen 
FROM dbo.MyTable 
GROUP BY Name

注:样式值121对应ODBC标准时间格式,输出为yyyy-MM-dd HH:mm:ss.fff,完全匹配你在SSMS中看到的输出结构。

额外优化建议

  1. 你当前使用的多层CAST转换完全冗余:DTStamp本身就是datetime类型,MAX聚合后返回值依然是datetime类型,不需要额外做CAST转换,多余的转换不会解决问题还可能带来不必要的性能损耗。
  2. 后续拉取完整行数据时,优先使用参数化查询,直接传递DateTime类型的参数而非拼接字符串形式的时间值,既可以彻底避免精度丢失问题,也能防范SQL注入风险。

内容的提问来源于stack exchange,提问作者Redgum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 10:45:06