2010-01-25 17 views
2

필자는 앱에서 반환 한 모든 데이터 시간에 8601 개의 datetimes를 사용할 것이라고 결정했습니다. 갑자기 특정 proc에서 getdate()가 중간에 T가있는 datetime을 반환하지 않습니다. FOR XML PATH를 사용하여 datetime을 포함하는 집합을 XML으로 변환한다는 것을 언급해야합니다. 일반적으로 datetime을 포함하는 테이블을 xml로 변환하면 8601 형식의 날짜가됩니다. 하지만 한 경우에는 그렇지 않습니다.내 126 datetime이 중간에 T가 돌아 오지 않는 이유는 무엇입니까?

select convert(datetime, getdate(), 126) -- returns 2010-01-25 10:14:35.923 

을하지만이 NVARCHAR로 캐스팅하면 나는 T를 얻을! :

select (cast(getdate() as datetime)) -- returns 2010-01-25 10:13:46.033 

그래서 내가 직접 그렇게처럼 변환

SELECT CONVERT(NVARCHAR(30), GETDATE(), 126) -- returns 2010-01-25T10:15:29.633 

내가 낯선 것은 조합으로이 버전을 여러 개 선택하면 T 버전이 사라진다는 것입니다. 그러나 노동 조합없이 선택하면 T 버전 (마지막 버전)이 남아 있습니다.

-- returns 4 rows of 2010-01-25 10:15:57.333 
select getdate() union all 
select (cast(getdate() as datetime)) union all 
select convert(datetime, getdate(), 126) union all 
SELECT CONVERT(NVARCHAR(30), GETDATE(), 126) 

나는이 일이 발생할 수있는 원인을 알지 못합니다. 저는 8601 개의 날짜가 로케일에 독립적이라고 생각했기 때문에 그렇게 생각하지 않습니다.

참조 ("YYYY-MM ISO 형식 : MI : ss.mmm"126에 대한) : http://msdn.microsoft.com/en-us/library/ms187928.aspx

답변

4

날짜 형 값을 형식화 된 문자열과 혼합합니다.

처음 두 예제는 어떤 식 으로든 날짜 형식을 반환하지 않으며 단지 datetime 값입니다. 값을 텍스트로 형식화하는 방법은 값을 데이터베이스에서 가져온 후 표시하는 방법에 따라 결정됩니다. 다른 국가에 거주하여 기본 문화권 설정이 다른 경우 날짜는 예를 들어 1/25/2010 10:14 AM으로 표시 될 수 있습니다.

datetime 값을 datetime 값으로 변환 할 때 형식화 또는 구문 분석이 필요하지 않으므로 두 번째 예에서는 형식 매개 변수 (126)가 무시됩니다.

세 번째 예제는 데이터베이스에서 반환되기 전에 datetime 값을 문자열로 형식화하므로 데이터베이스에서 사용하는 형식으로 가져옵니다.

차이 데이터 형식의 공용 구조체를 사용하는 경우 결과의 유형을 결정하는 것은 type precedence입니다. datetime 형식은 nvarchar보다 우선 순위가 높으므로 nvarchar 값을 datetime으로 변환하려고 시도합니다.

+0

(노조 예제에서) nvarchar 쿼리를 먼저 입력하면 모든 것이 datetime으로 변환됩니다 .. weird .. (SQL SERVER 2005) –

+0

내 테스트 설정이 좋지 않다고 생각합니다. 아직도 나는 (실제 proc) 내 결과에서 이상한 것을보고 있었다. 문제는 XML에 있습니다. FOR XML PATH를 수행하면 변환기는 8601 개의 날짜를 넣습니다. 나는 이것을 포함하도록 질문을 편집했다. 제 경우에는 SQL보다 다르게 datetimes를 변환하는 datalayer가있었습니다 (일부 경우). – jcollum

+1

@Gaby : 맞습니다. 데이터 유형을 결정하는 첫 번째 결과는 아니며 형식 우선 순위의 규칙입니다. 나는 대답에서 그것을 바꿨다. – Guffa

1

당신이 날짜로 변환, 당신이 형식을 선택하지 않는 - 날짜, 시간 및 날짜 시간입니다 모두 내부 형식으로 저장됩니다. 문자열 (char, varchar, nvarchar)로 변환 할 때만 형식이 출력에 중요합니다. 다른 경우에 형식은 암시 적으로 SQL 서버에 의해 선택되고, 8601

+0

그렇다면 일부 procs는 getdate()를 8601 형식으로 반환하고 다른 형식은 T? getdate()는 proc을 반환하는 것과 상관없이 항상 같은 것을 반환하지 않아야합니까? – jcollum

+0

getdate()가 문자열을 반환하지 않으면 datetime 객체가 반환됩니다. datetime 객체가 문자열로 변환되면 형식이 지정됩니다. procs의 일관성을 유지하려면 항상 문자열을 반환하게하십시오. –

1

GETDATE() 이미 DATETIME을 반환에 가까운하지만 동일하지 될 일이, 그래서이 식 :

CONVERT(datetime, getdate(), 126) 

는 아무것도 실시하지 않습니다.

CONVERT 부분을 생략하는 다른 형식 옵션을 대체 할 수도 있습니다. 결과는 동일합니다.

DATETIME 문자열 표현은 서버가 아닌 클라이언트가 선택합니다.

내부 표현 1900-01-01로부터 일수를 나타내는 제 4 바이트, 자정부터 1/300초의 수를 나타내는 제 4 바이트와 8 -byte 정수이다.

NVARCHAR으로 변환하면 서버가 텍스트 표현을 작성한 그대로 반환합니다. 이 경우 서버로 대체 된 T이 표시됩니다.

+0

여기에서 문제는 일부 procs select getdate()가 8601 형식으로 돌아오고 다른 procs에서는 그렇지 않다는 것입니다. – jcollum

+0

'GETDATE()'는 '8'바이트 시퀀스를 반환합니다. "돌아 오는"모든 값은 문자열로 변환 될 때만 발생합니다 (클라이언트가이를 수행 할 수 있음). – Quassnoi

+0

getdate() select가 지난 주에 T로 돌아 왔지만 이번주에는 T가 돌아 오는 것은 이상합니다. 내가 바꿀 수있는 지구상의 궁금한 점 (SSMS 설정에서의 어떤 것). – jcollum

0

연산자 우선 순위에서 공용어는 첫 번째 행이므로 모든 것이 datetime으로 형변환됩니다.그런 다음 T를 원하는 경우에 당신은 VARCHAR로 캐스팅 할 필요가 있지만, 다시는 (가능한 경우) 혼합 데이터 유형이 동일한 데이터 형식으로 캐스팅되기 때문에 노동 조합

이것은 T, 날짜 시간을 포함에서이 작업을 수행 할 수 없습니다 그 자체는 2 개의 정수로 저장되며 이것과 아무 관계가 없습니다.

SELECT CONVERT(VARCHAR(30), GETDATE(), 126) 
관련 문제