我将数据作为XML进入存储过程。其中一个元素是DateTime
值。有时当我得到它有“Z”时区指定的值时,其他时间可能不是。
我正在寻找一些方法来始终从此元素中检索日期值。为了使事情复杂化,似乎数据库实例类型之间的结果是不同的。具有2005兼容级别的2005实例与具有2005兼容级别的2008R2实例的行为不同。
以下是简化问题演示的示例查询。有3个不同的日期元素,一个具有相同的日期,一个具有时区名称,第三个使用“nil”/ null日期格式:
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实例: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 Server实例: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的日期时间字段中。它始终以UTC时间存储。
答案 0 :(得分: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