2012-07-23 33 views
3

我有一个C#程序将作为Windows计划任务运行。该程序将加载,运行SQL查询,通过电子邮件发送存储在数据集中的结果,然后关闭。除了使用Yesterdays日期之外,我拥有一切。如何将昨天的日期分配给参数C#

这里是我当前的查询:

SELECT  Store_Id, Paid_Out_Amount, Paid_Out_Comment, Paid_Out_Datetime, Update_UserName, Till_Number, @startdate AS Start, @enddate AS Today 
FROM   Paid_Out_Tb 
WHERE  (Store_Id = 1929) AND (Paid_Out_Datetime BETWEEN @startdate AND @enddate) 

很显然,我需要在查询的时间分配@startdate和@EndDate。因为我需要12AM到1159PM这是开始和结束的原因。举个例子。如果我想今天运行程序,它会搜索昨天(23日),所以@startdate将被分配7/22/12 00:00:00和@ enddate将被分配7/22/12 23:59:59 .. 。

在查询而不是程序中做它更合理吗?如果是这样,我将如何更改查询?

+0

不要之间使用的。请阅读http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do-between-and-the-devil-have-in-common.aspx和http://sqlblog.com/。 blog/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date-range-queries.aspx – 2012-07-23 17:15:08

回答

2

与日期间隔打交道时,不要使用between。使用>=<更容易和更安全。

像这样的东西会给你昨天没有参数的东西。

SELECT Store_Id, Paid_Out_Amount, Paid_Out_Comment, Paid_Out_Datetime, Update_UserName, Till_Number, @startdate AS Start, @enddate AS Today 
FROM Paid_Out_Tb 
WHERE Store_Id = 1929 AND 
     Paid_Out_Datetime >= dateadd(day, datediff(day, 0, getdate())-1, 0) and 
     Paid_Out_Datetime < dateadd(day, datediff(day, 0, getdate()), 0) 
+0

我用这个......在收集数据方面更清洁。谢谢! – Shmewnix 2012-07-23 17:32:49

0

我假定你都在寻找的东西这样

DateTime yesterdDaysDateTime = DateTime.Now.AddDays(-1); 
4

你可以计算出在C#昨天开始:

var yesterday = DateTime.Now.AddDays(-1); 
var startOfYesterday = new DateTime(yesterday.Year, yesterday.Day, yesterday.Month); 
com.Parameters.AddWithValue("@enddate", startOfYesterday); 

如果您使用的SQL Server 2008+,你可以改变数据类型从datetimedate。后者只能存储日期,因此您不必担心日期时间部分。

+2

使用'Today'而不是'Now',你不需要执行“start的昨天“计算。 – 2012-07-23 16:54:15

+0

这是SQL 2000,我会尝试在C#中的建议。 – Shmewnix 2012-07-23 16:54:18

0

您应该始终使用参数化查询。

为了支持您正在寻找的内容,您可以在昨天的日期中放入一个变量并将该变量传递给您的参数。

5

对现有答案略有改进,始终获得昨天的开始,无需致电DateTime构造函数。

var todayStart = DateTime.Today; 
var yesterdayStart = todayStart.AddDays(-1); 
var yesterdayEnd = todayStart.AddSeconds(-1); // Ick... 

注意,这将使用当前系统时区的“今天”的含义 - 你确定这就是你想要什么?您不妨考虑使用:

var todayUtcStart = DateTime.UtcNow.Date; 
... 

这是一个耻辱,BETWEEN治疗终点的包容性 - 如果它是相当于

start <= value && value < end 

,那么你可以只举两个午夜值,这将是更清晰。

同时还要注意它会不会与数据库中的任何清洁剂进行交互,用于日期和时间的其他用途,你不妨具体考虑我Noda Time库,其中包含一个数据类型为代表日期(另一个用于“一天中的时间”)等。目标无疑是澄清使用日期和时间的代码。如果没有,我失败了!

+0

Skeet不需要成为西部最快的枪... – canon 2012-07-23 16:55:52

+1

SQL Server默认存储几分之一秒,所以-1秒不会修复它。更好地通过第二天的开始,并使用'<'代替'<=' – Andomar 2012-07-23 16:58:33

+0

@Andomar:我只是想问问题。这就是为什么我说这是BETWEEN有效'<='的痛苦。格儿。 – 2012-07-23 19:21:40

0

这也可以工作,但是有一个缺点表现:

DateTime yesterday = DateTime.Today; 
Thread.Sleep(1000 * 60 * 60 * 24); 
0

你也可以这样做在SQL:

SELECT Store_Id, Paid_Out_Amount, Paid_Out_Comment, 
     Paid_Out_Datetime, Update_UserName, Till_Number, @startdate AS Start, @enddate AS Today 
FROM   Paid_Out_Tb 
WHERE  (Store_Id = 1929) 
AND (Paid_Out_Datetime BETWEEN DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())) 
    AND dateadd(second, -1, DATEADD(dd, 1, DATEDIFF(dd, 0, GETDATE())))) 
0

如果你希望把查询本身:

select (date_trunc('day', NOW()) - INTERVAL '1 day'); -- Yesterday Start 
select (date_trunc('day', NOW()) - INTERVAL '1 second'); -- Yesterday End 
+0

这是Oracle的语法吧?我相信这个问题是针对SQL Server – Andomar 2012-07-23 17:09:12

+0

不,是postgres。 – FabianoLothor 2012-07-23 17:36:20