获取当前日期作为存储过程的一部分

Dou*_*cil 2 sql-server t-sql

我有以下 SP:

SELECT
   moncallAdd.FirstListing,
   DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
         DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')) AS OnCallStart,
   DATEADD(MINUTE, mOnCallAdd.duration,
         DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
                 DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899'))) AS OnCallEnd
FROM
 mdr.dbo.mOnCallAdd
 where DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')= DATEADD(ms , 0 - DATEPART(ms , GETDATE()) ,
         DATEADD(s , 0 - DATEPART(s , GETDATE()) , GETDATE())) and
 mOnCallAdd.SchedName = 'arc im' 

UNION    
SELECT
 moncallDelete.FirstListing,
 DATEADD(MINUTE, mOnCallDelete.StartOnCallTime,
         DATEADD(DAY, mOnCallDelete.StartOnCallDate, '12/31/1899')) AS OnCallStart,
 DATEADD(MINUTE, mOnCallDelete.duration,
         DATEADD(MINUTE, mOnCallDelete.StartOnCallTime,
                 DATEADD(DAY, mOnCallDelete.StartOnCallDate, '12/31/1899'))) AS OnCallEnd
FROM
  mdr.dbo.mOnCallDelete
where DATEADD(DAY, mOnCallDelete.StartOnCallDate, '12/31/1899')= DATEADD(ms , 0 - DATEPART(ms , GETDATE()) ,
         DATEADD(s , 0 - DATEPART(s , GETDATE()) , GETDATE())) and
  mOnCallDelete.SchedName = 'arc im'
Run Code Online (Sandbox Code Playgroud)

我想要做的是如下:

如果我有一个从今天上午 9 点运行到今天下午 5 点的时间表,并且我在该时间范围内的任何时间运行我的 SP,我希望将该时间表作为我的数据集的一部分。我可以单独为约会工作,但无法弄清楚时间部分。任何人都可以提供任何帮助吗?


附录(是一个答案,合并了 -- jcolebrand)

理查德,

首先让我感谢您对这张桌子设计的见解,我同意您的观点,它设计得很差,但我没有设计它(感谢上帝。)其次,我尝试了您的查询,我正在变得更好结果,但它仍然没有消除所有不应返回的数据。以下是我的数据集中不应该出现的两个结果:

HEART HOSPITAL - xxxxx  2011-08-15 19:00:00.000 2011-08-16 07:00:00.000
HEART HOSPITAL - xxxxx  2011-08-15 13:00:00.000 2011-08-15 19:00:00.000
Run Code Online (Sandbox Code Playgroud)

(查询是在 9:18 CST 运行的,所以这些还不会发生。)

当我运行此查询时:

SELECT DATEADD(DAY,38490,'12/31/1899'), CAST(CONVERT(VARCHAR(10), getdate(), 111) AS DATETIME)
Run Code Online (Sandbox Code Playgroud)

(38490 是我的 StartOncallDate 字段的第一个值中的 int)

它返回一个值:

2005-05-19 00:00:00.000 2011-08-15 00:00:00.000
Run Code Online (Sandbox Code Playgroud)

这里还有我的表中的几行数据:

     Rec Id  Timestamp        SchedName     StartOnCallDate   StartOncallTime    FirstListing     Duration       AddDate  AddTime 
    70550    55426893      BITTAR&ESKEW        38490               1020             YIUM            840           38490    1293                                                             
    70551    55427287        ZZOB02            38494               1020         CARTER, KIMBERLY    900           38491     247 
Run Code Online (Sandbox Code Playgroud)

Ric*_*ard 6

1) 我不打算争论数据库设计,因为它似乎已经到位。

2) 查看代码,我必须假设 StartOnCallDate、StartOnCallTime 和 Duration 是整数。如果您尝试使用 DATETIME 来做到这一点,那么还有其他问题需要处理。

要回答你的问题...

首先, where 子句中的数学仍然包括时间(小时和秒)。所以这个东西:

DATEADD(ms , 0 - DATEPART(ms , GETDATE()) ,
            DATEADD(s , 0 - DATEPART(s , GETDATE()) , GETDATE()))
Run Code Online (Sandbox Code Playgroud)

给出了这个结果:

SELECT DATEADD(ms , 0 - DATEPART(ms , GETDATE()) ,
        DATEADD(s , 0 - DATEPART(s , GETDATE()) , GETDATE()))
-----------------------
2011-08-12 15:35:00.000
Run Code Online (Sandbox Code Playgroud)

因此,当您将 DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899') 与上面的混乱进行比较时,它几乎永远不会相等。那是因为当您使用 DATEADD(DAY...) 到那个硬编码日期时,您最终只会得到天数:

SELECT DATEADD(DAY, 40800, '12/31/1899')
-----------------------
2011-09-15 00:00:00.000
Run Code Online (Sandbox Code Playgroud)

为了减少小时和秒,你可以做更多的 DATEADD 东西,或者你可以做这样的事情:

(SQL Server 2008):
CONVERT (date, GETDATE())

(SQL Server 2005/2008 options):
CAST(CONVERT(VARCHAR(10), getdate(), 101) AS DATETIME)
CAST(FLOOR(CAST(GETDATE() AS DECIMAL(12, 5))) AS DATETIME)
Run Code Online (Sandbox Code Playgroud)

这些只会让你知道日期。如果您将其中之一放入 where 子句中,它将允许您过滤数据,向您显示与当前 DAY 匹配的所有值(今天将发生的任何事情):

WHERE DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')= 
    CAST(CONVERT(VARCHAR(10), getdate(), 101) AS DATETIME) AND
    mOnCallAdd.SchedName = 'arc im' 
Run Code Online (Sandbox Code Playgroud)

为了让您了解您正在比较的值,请将每个值(带有示例数据)提取到一个 select 语句中:

SELECT 
    DATEADD(DAY, 40766, '12/31/1899'), 
    CAST(CONVERT(VARCHAR(10), getdate(), 101) AS DATETIME)
----------------------- -----------------------
2011-08-12 00:00:00.000 2011-08-12 00:00:00.000
Run Code Online (Sandbox Code Playgroud)

现在,要过滤掉任何可能已经通过的内容,您需要向 WHERE 子句添加一个条件,以检查结束时间以确定它是否早于当前时间。

 DATEADD(MINUTE, mOnCallAdd.duration,
         DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
         DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899'))) > GetDate()
Run Code Online (Sandbox Code Playgroud)

这使得整个 where 子句:

WHERE DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')= 
        CAST(CONVERT(VARCHAR(10), getdate(), 111) AS DATETIME) AND
     DATEADD(MINUTE, mOnCallAdd.duration,
             DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
             DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899'))) > GetDate() AND
     mOnCallAdd.SchedName = 'arc im'
Run Code Online (Sandbox Code Playgroud)

编辑:

如果您只想显示当前正在发生的项目,您需要在结束时间(如上)和开始时间上都符合条件。要限定您的开始时间,您需要获取您的开始时间并确保当前时间大于或等于当前时间:

DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
        DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')) <= GetDate()
Run Code Online (Sandbox Code Playgroud)

这使得整个 WHERE 子句:

WHERE DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')= 
        CAST(CONVERT(VARCHAR(10), getdate(), 111) AS DATETIME) AND
     DATEADD(MINUTE, mOnCallAdd.duration,
             DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
             DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899'))) > GetDate() AND
     DATEADD(MINUTE, mOnCallAdd.StartOnCallTime,
             DATEADD(DAY, mOnCallAdd.StartOnCallDate, '12/31/1899')) <= GetDate() AND
     mOnCallAdd.SchedName = 'arc im'
Run Code Online (Sandbox Code Playgroud)