2012-06-26 3 views
0

У меня есть хранимая процедура: -Только дата сравнения Часть с системой Дата в SQL Server

CREATE procedure St_Proc_GetTimeEntryID    
@userID int,    
@timeEntryID int output    
as begin    
    set nocount on;  
    SET @timeEntryID=0  
    DECLARE @TEMP INT  
    SET @TEMP=0   
    SELECT @TEMP=ProductionTimeEntryID    
    FROM production    
    WHERE ProductionTimeEntryID =    
     (SELECT MAX(ProductionTimeEntryID)    
      FROM production    
      where [email protected]    
      and (CalendarDate = (select GETDATE()))    
      and IsTaskCompleted=1)  
      BEGIN  
       SET @[email protected]  
      END  
END 

Здесь CalendarDate находится колонна, которая содержащая Дата Как 06/26/201212: формат 12 вечера. Я хочу, чтобы сравнить часть даты только с системной датой части (06/26/2012 = 06/26/2012) в моем подзапроса, который

(SELECT MAX(ProductionTimeEntryID)    
      FROM production    
      where [email protected] 
      and (CalendarDate = (select GETDATE()))    
      and IsTaskCompleted=1) 

Пожалуйста, руководство мне, что модификация я буду делать, чтобы получить результат ,

+0

ли в 'CalendarDate' столбец' DATETIME' или что-то еще? Для ясности важно указать тип данных, а также понять, что тип данных DATETIME не хранит какой-либо формат, как вы предлагаете, именно так Management Studio отображает его вам на основе региональных настроек машины, вашего языка настройки и т. д. Также полезно указать версию SQL Server. –

+0

Столбец CalendarDate - DATETIME, и я использую Sql Server 2008. Ваши комментарии помогли мне, и в следующий раз я действительно буду указывать все эти точки, если они попадут в какую-либо проблему. Спасибо за предложение @Aoron –

ответ

1

Наиболее эффективный метод (то есть полностью в состоянии использовать индекс по CalendarDate, если таковой существует) будет на SQL Server 2000/2005:

DECLARE @today SMALLDATETIME; 
SET @today = DATEDIFF(DAY, 0, CURRENT_TIMESTAMP); 

... 
WHERE CalendarDate >= @today 
AND CalendarDate < DATEADD(DAY, 1, @today); 

При использовании SQL Server 2008+:

DECLARE @today DATE = CURRENT_TIMESTAMP; 
... 
WHERE CalendarDate >= @today 
AND CalendarDate < DATEADD(DAY, 1, @today); 

Вы можете также использовать прямой бросок в SQL Server 2008+, но я не 100% уверен, что это гарантированно использовать индекс CalendarDate во всех сценариях:

WHERE CONVERT(DATE, CalendarDate) = CONVERT(DATE, CURRENT_TIMESTAMP); 

Поскольку эта отливка не работайте с другими типами данных даты и времени, для согласованности. Я предпочитаю широко используемую технику диапазона и, безусловно, не допускаю большинство сценариев, в которых вы выполняете неявные или явные преобразования в столбце (так как это обычно означает, что индекс не будет использоваться). Я разглагольствовал об этом, и некоторые другие даты/времени злодеяния много в следующих постах в блоге:

http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date-range-queries.aspx

http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do-between-and-the-devil-have-in-common.aspx

0

Что-то вроде этого?

(SELECT MAX(ProductionTimeEntryID)    
     FROM production    
     where UserID=412    
     and (convert(datetime, convert(varchar(100), CalendarDate, 106)) <= convert(datetime, convert(varchar(100), GETDATE(), 106)))    
     and IsTaskCompleted=1) 
+0

В SQL2008R2 вы также можете использовать: 'и CAST (CalendarDate AS DATE) <= CAST (GETDATE() AS DATE)' – Sean

+0

Спасибо большое ... –

+0

@SeanW Ваш комментарий намного лучше, чем ответ.По крайней мере, у этого еще есть шанс использовать индекс. Ваш ответ предполагает четыре расточительных конверсии. –

0

Использование convert function

В вашем случае:

SELECT CONVERT(DATE,GETDATE(),101) 

Более конкретно:

(SELECT MAX(ProductionTimeEntryID)    
      FROM production    
      where [email protected] 
      and (CONVERT(DATE,CalendarDate) = CONVERT(DATE,GETDATE()))    
      and IsTaskCompleted=1) 
+0

Зачем вам 101? –

+0

@AaronBertrand - для сравнения его не требуется, хотя OP задал его так: 06/26/2012 = 06/26/2012' i.e. Месяц/день/год – NaveenBhat

+0

Помогло ли OP сказать, что данные были сохранены в виде строки? Мое подозрение - это то, что показывает ему студия Management Studio. –

2

В SQL2K8;

... WHERE CAST(CalendarDate AS DATE) <= CAST(GETDATE() AS DATE) 

(Это будет отрицать любое использование индекса на CalendarDate, в качестве альтернативы кронштейн CalendarDate между CalendarDate >= CAST(CalendarDate AS DATE) AND < DATEADD(...)

+0

На самом деле это одно из исключений, где SQL Server все еще предпочитает использовать индекс, даже если вы преобразовали столбец в DATE. Но поскольку это не документировано (по крайней мере, это я нашел), потому что могут быть исключения за пределами моих тестовых случаев, а также потому, что они не работают с другими типами данных даты и времени, я по-прежнему предпочитаю> = & формат. –

Смежные вопросы