SQLCLR 和 DateTime2

发布于 2024-08-28 21:40:48 字数 1222 浏览 6 评论 0原文

使用 SQL Server 2008、Visual Studio 2005、.net 2.0 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”失败,因为 返回值的 T-SQL 和 CLR 类型 不匹配。

使用 DATETIME (而不是 DATETIME2)效果很好。但我宁愿使用 DATETIME2 来支持提高的精度。我做错了什么,或者 SQLCLR 不(完全)支持 DateTime2 ?

Using SQL Server 2008, Visual Studio 2005, .net 2.0 with SP2 (has support for new SQL Server 2008 data types).

I'm trying to write an SQLCLR function that takes a DateTime2 as input and returns another DateTime2. e.g. :

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);
        }
    }
}

Now, the above compiles fine. I want these SqlDateTimes to map to SQL Server's DateTime2, so I try to run this T-SQL :

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

This gives the following error :

Msg 6551, Level 16, State 2, Procedure
f_UTCToLocalDT, Line 1 CREATE FUNCTION
for "f_UTCToLocalDT" failed because
T-SQL and CLR types for return value
do not match.

Using DATETIME (instead of DATETIME2) works fine. But I'd rather use DATETIME2 to support the increased precision. What am I doing something wrong, or is DateTime2 not (fully) supported by SQLCLR ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

很快妥协 2024-09-04 21:40:48

您需要更改函数方法签名中的日期时间类型。 SQLDateTime 映射到数据库上的日期时间。

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

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

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

You need to change the DateTime types in the signature of your Function Method. SQLDateTime maps to a DateTime on the database.

System.DateTime is more precise and can be mapped to DateTime2 (but by default, it'll be dropped as a DateTime in the deploy script).

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

Then you can tweak your deploy script to read.

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

Running your function should now give you more precise output.

DECLARE @input DateTime2, @output DateTime2
SET @input = '2010-04-12 09:53:44.48123456'
SET @output = YourDatabase.dbo.[UTCToLocalDT](@input)
SELECT @input, @output
猥︴琐丶欲为 2024-09-04 21:40:48

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

(如果可以的话,我会在上面作为评论发布。)

Note that using "DateTime?" still always gives build errors (even in VS 2013 with sql 2012), though apparently the result is usable if one selects "build, deploy" and then uses the files in the obj folder, editing the generated.sql file in the sql query window (to use DateTime2 as parameter) before executing to add it to Sql Server.
The build error is "SQL46010: Incorrect syntax near )."
in \obj\Debug\YourPrjName.generated.sql

(Would post above as comment if I could.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文