2013-07-01 4 views
4

XML로 저장 프로 시저에 들어오는 데이터가 있습니다. 요소 중 하나는 DateTime 값입니다. 때로는 "Z"시간대 지정이있는 값을 얻을 때 다른 시간은 그렇지 않을 수도 있습니다.일반적인 방법으로 XML 입력에서 SQL DateTime 변환을 처리하는 방법

이 요소에서 항상 날짜 값을 검색하는 몇 가지 방법을 찾고 있습니다. 복잡한 점은 결과가 데이터베이스 인스턴스 유형마다 서로 다른 것으로 보입니다. 2005 호환성 수준의 2005 인스턴스는 2005 호환성 수준의 2008R2 인스턴스와 다르게 작동합니다.

다음은 문제를 간단하게 보여주는 샘플 쿼리입니다. 여기

DECLARE @p_LogInfo XML, @datetimeval Varchar(50), @tzdatetimeval Varchar(50); 

set @datetimeval='2013-07-01T14:27:00.454725' 
set @tzdatetimeval='2013-07-01T14:27:00.454725Z' 
set @p_LogInfo = '<processLog xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.somthing.com"><notzdatetime>' + @datetimeval + '</notzdatetime><tzdatetime>' + @tzdatetimeval + '</tzdatetime><nulldatetime i:nil="true"/></processLog>'; 

WITH XMLNAMESPACES (DEFAULT 'http://www.somthing.com') 
SELECT 
tbl.UPD.value('xs:dateTime(notzdatetime[1])', 'datetime') as no_tz_date 
,tbl.UPD.value('notzdatetime[1]', 'datetime') as no_tz_date2 
,tbl.UPD.value('xs:dateTime(tzdatetime[1])', 'datetime') as tzdate 
,tbl.UPD.value('tzdatetime[1]', 'datetime') as tzdate2 
,tbl.UPD.value('xs:dateTime(nulldatetime[1])', 'datetime') as nulldate 
,tbl.UPD.value('nulldatetime[1]', 'datetime') as nulldate2 
FROM 
@p_LogInfo.nodes('/processLog') AS tbl(UPD) 

결과 있습니다 :

SQL Server는 3 개 개의 다른 날짜 요소 동일한 날짜 일, 시간대 지정 하나 및/널 (null) 날짜 형식을 "무기 호"를 사용하여 3이 있습니다 인스턴스 : 2008R2 - 데이터베이스 (호환) 수준 : 2005 (90)

no_tz_date --Query Successful but returns NULL 
no_tz_date2 --SUCCESSFUL DATE 
tzdate --SUCCESSFUL DATE 
tzdate2 --SUCCESSFUL DATE 
nulldate --Query Successful but returns NULL 
nulldate2 --SUCCESSFUL returns '1900-01-01 00:00:00.000' 

SQL 서버 인스턴스 : 2005 - 데이터베이스 (호환) 수준 : 2005 (90)

no_tz_date --Query Successful but returns NULL 
no_tz_date2 --(ERROR: Conversion failed when converting datetime from character string.) 
tzdate --SUCCESSFUL DATE 
tzdate2 --(ERROR: Conversion failed when converting datetime from character string.) 
nulldate --Query Successful but returns NULL 
nulldate2 --(SUCCESSFUL returns '1900-01-01 00:00:00.000') 

제 질문은 어떻게 XML 데이터를 가져 와서 간단한 일반적인 방식으로 날짜를 포맷 할 수 있습니까? 이 날짜는 SQL Server의 datetime 필드에 저장됩니다. 항상 UTC 시간으로 저장됩니다.

+0

한 오류 '전환이 ... 실패'가있는 경우입니다 당신은 주어진 필드에 여분의 문자가 있습니다. –

+0

제가 그걸로 할 일이 없다고 생각합니다. 예제에서 당신은 내가 테스트 한 날짜 값을 볼 수 있습니다. 나는 varchar (50)하지만 그것은 문자열의 정확한 크기를 사용하더라도 문제가되지 않습니다. – Jay

답변

3

이렇게하는 방법을 찾았지만 프로세스가 마음에 들지 않습니다. SQL에서 문자열로 날짜를 가져 와서 23 자로 제한하는 간단한 스칼라 함수를 만들었습니다. 그런 다음 문자열이 null 또는 비어 있지 않으면 CONVERT to datetime이 사용됩니다. 그렇다면 어디서나 나는이 함수를 감싸고 있습니다. 누군가에게 더 좋은 옵션이 있으면 알려주세요. 그것은 작동하지만 해킹 :(

예처럼 보인다 : 기능 코드

SELECT [dbo].GetFormattedDate('2013-07-01T14:27:00.434') 
,[dbo].GetFormattedDate('') 
,[dbo].GetFormattedDate(NULL) 
,[dbo].GetFormattedDate('2013-07-01T14:27:00.434Z') 
,[dbo].GetFormattedDate('2013-07-01T14:27:00.434445Z') 
,[dbo].GetFormattedDate('2013-07-01') 

다음에 대한 가장 일반적인 범인의

CREATE FUNCTION [dbo].[GetFormattedDate] 
( 
    @p_DateString varchar(23) 
) 
RETURNS datetime 
AS 
BEGIN 

/* 
Notice that the in parameter truncates all datetime values to 23 characters 
Which would truncate the date time to the thousandths place of the milliseconds 
*/ 
DECLARE @returnDatetime as datetime; 

IF ((@p_DateString IS NULL) OR (@p_DateString = '')) 
    BEGIN 
     /* Return null is string is empty or null already */ 
     SET @returnDatetime = NULL; 
    END 
ELSE 
    BEGIN 
     /* Otherwise conver the string to a datetime */ 
     SET @returnDatetime = CONVERT(datetime, @p_DateString); 
    END 

RETURN @returnDatetime; 

END