【发布时间】:2017-12-17 09:09:23
【问题描述】:
我正在尝试建立一个旧的解决方案,该解决方案将许多 .net 函数发布到 SQL Server 数据库。但是尝试发布到新数据库的操作在操作日期的功能上失败了。
失败的函数是:
[SqlFunction(TableDefinition="localtime datetime2", IsDeterministic=true, IsPrecise=true,
DataAccess=DataAccessKind.None,
SystemDataAccess=SystemDataAccessKind.None)]
public static DateTime ConvertFromUTC(DateTime utctime, string timezoneid)
{
if (utctime.Kind == DateTimeKind.Unspecified)
utctime = DateTime.SpecifyKind( utctime, DateTimeKind.Utc );
utctime = utctime.ToUniversalTime();
return TimeZoneInfo.ConvertTimeBySystemTimeZoneId( utctime, timezoneid );
}
我在尝试发布时收到的错误消息是:
正在创建 [dbo].[ConvertFromUTC]...
(268,1):SQL72014:.Net SqlClient 数据提供者:
消息 6551,级别 16,状态 2,过程 ConvertFromUTC,第 1 行
“ConvertFromUTC”的 CREATE FUNCTION 失败,因为返回值的 T-SQL 和 CLR 类型不匹配。(268,0): SQL72045: 脚本执行错误
从 .net 生成的 SQL 以尝试添加函数:
CREATE FUNCTION [dbo].[ConvertFromUTC]
(@utctime DATETIME, @timezoneid NVARCHAR (MAX))
RETURNS TABLE ([localtime] DATETIME2 (7) NULL)
AS EXTERNAL NAME [database].[IntelligentTutor.Database.Functions].[ConvertFromUTC]
现有数据库中函数版本的 SQL 定义(这证实了@MattJohnson 关于需要修复的方式是正确的):
CREATE FUNCTION [dbo].[ConvertFromUTC]
(@utctime [datetime], @timezoneid [nvarchar](4000))
RETURNS [datetime] WITH EXECUTE AS CALLER
AS EXTERNAL NAME [database].[IntelligentTutor.Database.Functions].[ConvertFromUTC]
【问题讨论】:
-
除了@Matt 的回答中提到的建议,您还应该考虑以下几点:从属性中删除
TableDefinition="localtime datetime2",;使用SqlString而不是string代替timezoneid(这需要将return中的timezoneid更改为timezoneid.Value);并将@timezoneid从NVARCHAR(MAX)更改为NVARCHAR(50) 或任何有意义但不是MAX的大小。另外,请注意TimeZoneInfo类存在内存泄漏,这就是它要求将程序集标记为UNSAFE的原因。 -
有关一般使用 SQLCLR 的更多信息,请参阅我在 SQL Server Central 上写的关于此主题的系列:Stairway To SQLCLR(需要免费注册才能阅读其内容,但值得)。
-
@srutzky -
HostProtectionAttribute.MayLeakOnAbort并不意味着“有内存泄漏”。 -
@MattJohnson 感谢您提供该链接。所以只是意味着“可以泄漏,如果中止”,对吗?如中,如果允许成功完成不会泄漏?
-
对。这是极不可能的事件。甚至有人会争辩说,这个特定的类不需要该属性,尽管现在对此无能为力。
标签: c# .net sql-server sqlclr