SQLCLR和DateTime2

使用SQL Server 2008,Visual Studio 2005,.net 2.0 with SP2(支持新的SQL Server 2008数据类型)。

我正在尝试编写一个SQLCLR函数,它将DateTime2作为输入并返回另一个DateTime2。 例如:

using System; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; namespace MyCompany.SQLCLR { public class DateTimeHelpCLR { [SqlFunction(DataAccess = DataAccessKind.None)] public static SqlDateTime UTCToLocalDT(SqlDateTime val) { if (val.IsNull) return SqlDateTime.Null; TimeZone tz = System.TimeZone.CurrentTimeZone; DateTime res = tz.ToLocalTime(val.Value); return new SqlDateTime(res); } } } 

现在,上面的编译很好。 我希望这些SqlDateTimes映射到SQL Server的DateTime2,所以我尝试运行这个T-SQL:

 CREATE function hubg.f_UTCToLocalDT ( @dt DATETIME2 ) returns DATETIME2 AS EXTERNAL NAME [SQLCLR].[MyCompany.SQLCLR.DateTimeHelpCLR].UTCToLocalDT GO 

这会出现以下错误:

消息6551,级别16,状态2,过程f_UTCToLocalDT,第1行“f_UTCToLocalDT”的CREATE FUNCTION失败,因为返回值的T-SQL和CLR类型不匹配。

使用DATETIME(而不是DATETIME2)工作正常。 但我宁愿使用DATETIME2来支持提高的精度。 我做错了什么,或者SQLCLR没有(完全)支持DateTime2?

您需要在函数方法的签名中更改DateTime类型。 SQLDateTime映射到数据库上的DateTime。

System.DateTime更精确, 可以映射到DateTime2(但默认情况下,它将在部署脚本中作为DateTime删除)。

 [SqlFunction(DataAccess = DataAccessKind.None)] //OLD Signature public static SqlDateTime UTCToLocalDT(SqlDateTime val) public static DateTime UTCToLocalDT(DateTime val) { ... } 

然后,您可以调整部署脚本以进行阅读。

 CREATE FUNCTION [UTCToLocalDT] ( @dt [datetime2] ) RETURNS [datetime2] AS EXTERNAL NAME [SQLCLR].[MyCompany.SQLCLR.DateTimeHelpCLR].UTCToLocalDT GO 

运行您的function现在应该为您提供更精确的输出。

 DECLARE @input DateTime2, @output DateTime2 SET @input = '2010-04-12 09:53:44.48123456' SET @output = YourDatabase.dbo.[UTCToLocalDT](@input) SELECT @input, @output 

请注意使用“DateTime?” 仍然总是给出构建错误(即使在使用sql 2012的VS 2013中),但显然结果是可用的,如果选择“构建,部署”然后使用obj文件夹中的文件,在sql查询窗口中编辑generated.sql文件(在执行时将DateTime2用作参数)将其添加到Sql Server。
生成错误是“SQL46010:语法不正确”。“ 在\ obj \ Debug \ YourPrjName.generated.sql中

(如果可以的话,会在上面发表评论。)