2012-02-21 2 views
-2

Поместите этот кусок кода в анализатор запросов и нажмите F5.SQL Server dateformat сомнительное поведение

declare @aaa datetime 
set @aaa='01/12/2011' 
set dateformat dmy 
select month(@aaa) 

Это дает вам 1. Хит F5 снова, это дает вам 12. Почему?

+4

Query Analyzer? Неужели я искал время назад 10 лет? –

+1

Если вы используете ** основанную на языке/не зависящую от вас ** строчную дату (например, ** ISO-8601 ** стандартный формат 'YYYYMMDD') - например, 'set @aaa = '20111201'' - тогда вы можете переключаться между форматами даты столько раз, сколько хотите - вы будете ** ВСЕГДА ** получите' 12' за месяц ...... –

ответ

1

Это потому, что ваша линия set dateformat dmy находится на полпути через скрипт.

Это переключая формат даты после первоначального назначения для первого «F5», но затем это сохраняется для второго «F5»

Если вы сделаете это первая линия должна быть последовательной и вернуть 12 каждый время

Чтобы быть ясным - set dateformat dmy имеет значение для строки set @aaa='01/12/2011', поскольку это влияет на то, как строка '01/12/2011' анализируется на дату и время.

В первом запуске @aaa фактически будет содержать дату '12 -Jan-2011 ', тогда как после вас set dateformat dmy он будет содержать дату '01 -Dec-2011'.

+0

set dateformat dmy он должен быть там. @aaa - это только парметер, полученный хранимой процедурой. Первые 2 строки - попробовать процедуру во время разработки – Florin

+1

@Florin: в вопросе не было указано - чем больше информации вы дадите, тем лучше ответ вы получите. Откуда вызывается сохраненная proc? –

+0

ОК. Сожалею. Посмотрим. У вас есть эта процедура: CREATE PROCEDURE [dbo]. [Test] \t @dDate datetime AS НАЧАЛО \t SET NOCOUNT ON; \t набор DateFormat ДМГ \t выберите месяц (@dDate) END Если выполнить процедуру его возврата 1 вместо 12 – Florin

1

Поскольку в первый раз, когда вы запускали код, дата была сохранена внутренне как 12 января. Установленная настройка соответствует вашей сессии, затем вы запустили ее снова, чтобы вы переопределили переменную, и на этот раз ее интерпретировали как 1 декабря. Параметр set не влияет на функции datepart, такие как MONTH(), потому что дата уже была интерпретирована и не хранится внутри, как вы ее набрали.

Вместо того, чтобы объявлять литературные даты с региональным и неоднозначным форматированием, вы всегда должны использовать безопасные, недвусмысленные форматы. Для даты и времени/smalldatetime:

yyyymmdd 
yyyy-mm-ddThh:mm:ss 

На сегодняшний день:

yyyy-mm-dd 

Если вы хотите отобразить даты в этих дружественных, но запутанных форматов, всеми средствами сделать это на уровне представления. Но не пытайтесь путать с ними SQL Server. Пожалуйста, прочтите this blog post и this article by Tibor Karaszi.

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