在CLR执行中出现错误

本文关键字:错误 CLR 执行 | 更新日期: 2023-09-27 17:51:08

我想这可能和this Issue一样

我也参考了它,但仍然不能得到我的问题的解决方案。这是我第一次创建CLR并遇到问题。

我已经为c#开发了一个CLR::
public partial class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction]
    public static SqlDateTime GetTimeForCompanyID(SqlInt64 CompanyID)
    {
        string strZoneID;
        string connStr = @"data source=.;initial catalog=dbName;Integrated Security=SSPI;user id=RJ;password=RJ@123;enlist=false;";
        using (SqlConnection connection = new SqlConnection(connStr))
        {
            connection.Open();
            using (SqlCommand select = new SqlCommand(
                "select SettingValue from CompanySetting where CompanyID="+CompanyID+" and Setting='TimeZone'",
                connection))
            {
                using (SqlDataReader reader = select.ExecuteReader())
                {
                        strZoneID = reader.GetString(0);
                }
            }
        }

        TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(strZoneID);
        DateTime result = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tzi);
        SqlDateTime Final = result;
        return Final;
    }


}

和在SQL中创建Assembly的方式如下::

1)我首先在主数据库中创建了Assembly Key::

use master
CREATE ASYMMETRIC KEY MyDllKey FROM EXECUTABLE FILE = 'C:'Temp'CueBusinessFunctions.dll'
CREATE LOGIN MyDllLogin FROM ASYMMETRIC KEY MyDllKey
GRANT EXTERNAL ACCESS ASSEMBLY TO MyDllLogin

2)创建程序集为::

use Learn
CREATE ASSEMBLY CueBusinessFunctions FROM 'C:'Projects'CueBusinessFunctions.dll'
WITH PERMISSION_SET = EXTERNAL_ACCESS 
GO

创建CLR UDF为::

CREATE FUNCTION [dbo].[GetTimeForCompanyID](@CompanyID bigint)
RETURNS datetime
WITH EXECUTE AS CALLER
AS
EXTERNAL NAME CueBusinessFunctions.UserDefinedFunctions.GetTimeForCompanyID;
GO

但是问题是当执行UDF为::

select [dbo].[GetTimeForCompanyID](1)

我得到的错误是::

    Msg 6522, Level 16, State 1, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "GetTimeForCompanyID": 
System.Security.HostProtectionException: Attempted to perform an operation that was forbidden by the CLR host.
The protected resources (only available with full trust) were: All
The demanded resources were: MayLeakOnAbort
System.Security.HostProtectionException: 
   at UserDefinedFunctions.GetTimeForCompanyID(SqlInt64 CompanyID)
.

在CLR执行中出现错误

在SQLCLR函数中使用TimeZoneInfo结构会带来一个警告,即这种特定的数据类型实际上是用MayLeakOnAbort属性标记的。这就是为什么你会得到你所看到的异常。

你可以在这个线程上找到一些有用的信息:如何在SQL Server 2012中使用TimeZoneInfo在SQLCLR程序集

David是对的。一旦在代码中创建了TimeZoneInfo,就会出现这个错误。我有一个类似的问题要解决(将本地时间转换为UTC时间)。我将编写一段c#代码,从数据库读取记录,进行计算并返回结果。我也会建议你这么做。我还担心您的代码位的性能。每次调用函数时,都要构建一个新的SQL连接。查看如何在SQL Server 2012的SQLCLR程序集中使用TimeZoneInfo