. 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数据类型有什么注意事项或实际经验?"'
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];