2017-10-18 64 views
0

我已经继承了一些C#应用程序代码,它具有在我们的代码库中使用的流畅SQL查询构建器。一些更常见的查询应用过滤器,如“今天或之后的日期”。这些过滤器作为查询构建器的元数据存储在SQL表中,同时调查性能和死锁问题,我意识到这些查询组件不是可靠的。DateDiff的Sargable版本()SQL查询

该生成器生成一个典型的查询是这样的:

DECLARE @systemDate DATETIME 
SET @systemDate = [dbo].GetSystemDate() 

SELECT [table1].* FROM [dbo].[XXX] AS [table1] 
WHERE ... AND DateDiff(d, @systemDate, [table1].PaymentDate) <= 0 
AND ... 

列PAYMENTDATE存储为日期时间,与时间分量。 GetSystemDate()返回午夜的日期时间 - 即2017-10-18 00:00:00.000

问题是,即使我在PaymentDate中包含索引,SQL Server也无法对其执行查找,因为它是在DateDiff()函数中。但是,查询生成器的设计使我可以很容易地用一个更有效的,可查询的表达式替换,这个表达式将应用于所有构造的SQL查询。

对于以下情况,什么是等效的可查询的查询,因为时间组件也在查询列上播放,并且生成的查询需要将相同的结果返回给现有的DateDiff()调用?我已经看到了使用DateAdd()和比较的其他解决方案,但由于数据中存在时间组件,我对这些行为有所警惕。

OperatorDisplayName OperatorExpression ValueExpression ColumnExpression 
Today      =     0   DateDiff(d, @systemDate, {0}) 
This Week     =     0   DateDiff(ww, @systemDate, {0}) 
Last Week     =     -1   DateDiff(ww, @systemDate, {0}) 
This Month     =     0   DateDiff(m, @systemDate, {0}) 
Last Month     =     -1   DateDiff(m, @systemDate, {0}) 
On or Before Today   <=     0   DateDiff(d, @systemDate, {0}) 
On or After Today   >=     0   DateDiff(d, @systemDate, {0}) 
Before Today     <     0   DateDiff(d, @systemDate, {0}) 
After Today     >     0   DateDiff(d, @systemDate, {0}) 

回答

0

由于@systemDate没有时间组件,您可以构建> = <比较:

OperatorDisplayName OperatorExpression ValueExpression ColumnExpression 
Today      =     0   {0} >= @systemDate AND {0} < DATEADD(d, 1, @systemDate) 

你真的不使用操作员或价值这种方式,因为它内置在列表达式。

由于您的表达式需要包含代码来计算基于@systemDate的第一天/月的第一天,但​​是网上已经有这样的示例,因此周和月运营商将变得更加复杂。