. net DataRowComparer DateTime与T-SQL DateTime的比较

本文关键字:DateTime 比较 T-SQL DataRowComparer net | 更新日期: 2023-09-27 18:17:03

我了解到SQL Server存储DateTime与。net框架不同。在以下情况下,这是非常不幸的:假设我有一个从我的对象属性填充的DataRow -其中一些是DateTime -和第二个DataRow从SQL Server中持久化的对象的数据填充:

DataRow drFromObj = new DataRow(itemArrayOfObjProps);
DataRow drFromSQL = // blah select from SQL Server

对这两个数据行使用DataRowComparer会得到一个意想不到的结果:

// This gives false about 100% of the time because SQL Server truncated the more precise
// DateTime to the less precise SQL Server DateTime
DataRowComparer.Default.Equals(drFromObj, drFromSQL);
我的问题是,"其他人是如何以一种安全而理智的方式面对现实的?"我还打算排除转换为字符串或编写自己的DataRowComparer的可能性。在没有更好的建议的情况下,我将更改所有DateTime属性上的'set',将其转换为System.Data.SqlTypes.SqlDateTime并返回存储:
public Nullable<DateTime> InsertDate
{
  get
  {
    if (_InsDate.HasValue)
      return _InsDate;
    else
      return null;
  }
  set
  {
    if (!object.ReferenceEquals(null, value) && value.HasValue)
    _InsDate = (DateTime)(new System.Data.SqlTypes.SqlDateTime(value));
  }
}

我很清楚,这可能会搞砸,因为我直接使用_instdate变量,而不是通过属性。所以我的另一个建议是简单地使用System.Data.SqlTypes.SqlDateTime的所有属性,我可能想要一个DateTime类型往返SQL Server(而且,令人高兴的是,SqlDateTime是空的)。然而,这篇文章改变了我的想法,似乎解决了我眼前的问题。我的新问题是,"使用SQL Server datetime2(7)数据类型而不是好的、旧的datetime数据类型有什么注意事项或实际经验?"'

. net DataRowComparer DateTime与T-SQL DateTime的比较

TL;DR:比较日期实际上很难,尽管看起来很容易,因为大多数时间你可以摆脱它。

您必须意识到这个问题,并将两个值四舍五入到所需的精度。

这与比较浮点数本质上是相同的问题。如果两个时间相差4纳秒,那么您的应用程序认为它们是不同的还是相同的,这有意义吗?

例如,如果两个服务器记录了相同的事件,搜索相应的记录,您不会说"不,那不可能是正确的事件,因为时间错误了200纳秒"。无论两台服务器多么努力地保持时间同步,它们的时钟都可能相差这么多。您可能会接受在服务器A上看到的事件,并在服务器B的时间几秒钟后记录的时间可能实际上是同时看到的,或者相反。

注意:

  • 如果您正在比较应该从数据库中进行某种往返的数据,您可能会发现它已被截断为秒或分钟。(例如,如果它已经通过Excel或旧的VB应用程序,或被写入文件并解析回。)

  • 来自外部来源的数据通常四舍五入到日、分或秒。(除了日志文件、事件日志或电子数据记录器,它们的毫秒级甚至更高)

  • 如果数据来自SQL Server,并且您将其与自身进行比较(例如检测更改),您可能不会遇到任何问题,因为它们将隐式截断到相同的精度

  • 夏令时和时区引入了额外的问题。

  • 如果搜索日期,则使用日期范围。并确保您以任何索引都可以使用的方式编写查询。

有些相关:

  • 为什么这个sql查询没有返回任何比较浮点数的结果?

标识递增。按身份排序,得到插入顺序。你(可以)控制插入顺序。

我非常怀疑输出是否会乱序,但如果你不相信它,你可以使用@SeeMeSorted

DECLARE @SeeMeSort TABLE
( [ID] [int] IDENTITY(1,1) NOT NULL,
  [Name] [nvarchar](20) NOT NULL);
DECLARE @SeeMeSorted TABLE
( [ID] [int] primary key  NOT NULL,
  [Name] [nvarchar](20) NOT NULL);
insert into @SeeMeSort ([Name])
OUTPUT INSERTED.[ID], INSERTED.[name]
values ('fff'), ('hhh'), ('ggg');
insert into @SeeMeSort ([Name])
OUTPUT INSERTED.[ID], INSERTED.[name]
  into @SeeMeSorted
values ('xxx'), ('aaa'), ('ddd');
select * from @SeeMeSorted order by [ID];