2012-06-08 2 views
1

В следующем коде T-SQL:Значение CAST ('1/1' + ...... as DATETIME)?

wt.clsdt_date >= CAST('1/1/' + CAST(2011 - 1 AS varchar) AS DateTime) 

что означает '1/1' означает?

+1

В то время как я ценю все советы относительно лучший способ, чтобы написать код выше, я боюсь, что я не могу ничего сказать о том, как она написана, независимо от того, насколько запутанным он может быть сделать. У меня нет доступа к коду, чтобы внести соответствующие изменения. Я просто пытаюсь перевести его в LINQ to SQL из Word Document. Однако ваши объяснения были очень полезны для объяснения того, что происходит, и за это я благодарю всех вас. –

ответ

3

(Пожалуйста, смотрите другие ответы для улучшения в SQL.)

'1/1/' является строкой, так что результирующая строка после + является '1/1/year', например,

'1/1/' + CAST(2011 - 1 as varchar) 
-> '1/1/' + '2010' 
-> '1/1/2010' 

, который затем отлит (преобразован, действительно) в соответствующий тип.

Я был бы удивлен, если для этого не было более красивого метода.

Для SQL Server 2008 и до there does not appear to be a particularly nice standard method.

Для SQL Server 2012 есть DATEFROMPARTS, как показано на this related SO post:

SELECT DATEFROMPARTS(@Year, @Month, @Day) 
+0

Хорошо. Спасибо за помощь. –

+1

Обратите внимание, что ['DATEFROMPARTS'] (http://technet.microsoft.com/en-us/library/hh213228.aspx) является новым в SQL Server 2012. –

+0

@AaronBertrand Nabbits. –

2

Этот метод используется для оценки того или нет wt.clsdt_date это во время или после 2010 года уборщик путь для достижения этой цели будет быть следующим:

YEAR(wt.clsdt_date) >= 2010 
+1

Это не поддается продвижению. Обтекание столбца с помощью функции «YEAR» означает, что индекс не может использоваться. –

+0

@MartinSmith Lame, я бы ожидал, что планировщик сможет сделать некоторые выводы там ... –

+0

@pst - В основном это даже не в принципе. [Есть запрос на расширение случаев, когда он здесь) (http://connect.microsoft.com/SQLServer/feedback/details/526431/make-more-functions-sargable) –

3

гораздо безопаснее способ сделать это:

WHERE wt.clsdt_date >= CONVERT(CHAR(4), 2011 - 1) + '0101'; 

Вам не нужно явно привести его к datetime, но вы можете:

WHERE wt.clsdt_date >= CONVERT(DATETIME, CONVERT(CHAR(4), 2011 - 1) + '0101'); 

Это использует Внерегиональные формат даты, а также по-прежнему использует индекс на столбце, если таковой существует.

Также varchar without length is a bad habit.

+0

+1 Хотя «1/1/yyyy» должен быть «безопасным» в * данном конкретном случае *? Я не возражаю против такого подхода, разум. –

+0

@pst. То, что люди могут извлечь уроки из примера «1/1 /» и предположить, что он также безопасен для «6/15 /» (что может привести к ошибке) или даже хуже «6/7 /», что может привести к к неправильным результатам, но не обнаружены. –

+0

Да, я полностью согласен, это намного лучше привычка/способ написать это. Мне просто интересно, может ли это повлиять на этот конкретный ввод строки. –