DATEDIFF检查一分钟实际上是一到两分钟

时间:2016-07-28 16:10:36

标签: sql-server tsql

我正在使用DATEDIFF确保某项操作不会超过每分钟一次。

SELECT COUNT(*) 
FROM FOOD_ACTION
WHERE 
DATEDIFF(MINUTE,INSERT_DT,GETDATE()) <= 1

INSERT_DT是一个日期列,格式与GETDATE()返回

相同

如果从此查询返回任何内容,则不允许执行此操作。

问题是,只有有效。我已经把它从一分钟到10秒一直到最近差不多两分钟才能再次发生动作。如果它接近一分钟或两分钟似乎没有任何一致性,并且我已确认GETDATE()返回与我的应用程序设置INSERT_DT列时相同的确切时间。

不一致和不正确的时间是怎么回事?

2 个答案:

答案 0 :(得分:4)

当您执行日期更改时,T-SQL将查找时间/日期部分边界何时越过以增加差异。

所以:

DECLARE @StartDate DATETIME = '2000-01-01T12:51:59.999',
        @EndDate DATETIME = '2000-01-01T12:52:00:000'

SELECT DATEDIFF(minute, @StartDate, @EndDate)

您将得到以下结果:1
即使日期之间只有1毫秒的差异。

在实践中,我通过更低的粒度来解决这个问题,并寻找自己的交叉,即:

DECLARE @StartDate DATETIME = '2000-01-01T12:51:59.999',
        @EndDate DATETIME = '2000-01-01T12:52:00:000'

SELECT 
   CASE WHEN DATEDIFF(second, @StartDate, @EndDate) >= 59 THEN CAST(1 as bit)
        ELSE CAST(0 as bit)
   END as InNewMinute

这显然是0,显然1ms不是1分钟差异。

注意:上面的代码显然仅用于处理1分钟差异

请参阅:MSDN DATEDIFF (Transact-SQL)(查看datePart Boundaries)

答案 1 :(得分:1)

     // using a File just for demonstration / testing
     File f = new File("a");
     try (InputStream stream = new FileInputStream(f)) {
        ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(null, "Downloading...", stream);
        int downloadSize = f.length();
        ProgressMonitor pm = pmis.getProgressMonitor();
        pm.setMillisToDecideToPopup(0);
        pm.setMillisToPopup(0);
        // tell the progress bar that we start at the beginning of the stream
        pm.setMinimum(0);
        // tell the progress bar the total number of bytes we are going to read.    
        pm.setMaximum(downloadSize);
        copyInputStreamToFile(pmis, new File("/tmp/b"));
     }

为什么要访问所有数据以表明什么都不应该发生?做得更好

SELECT COUNT(*) 
 FROM FOOD_ACTION
  WHERE 
   DATEDIFF(MILLISECOND,INSERT_DT,GETDATE()) <= 60000

然后如果返回1,则使用它作为指示,这样就不会读取数据并切断网络流量