SQLCLR 用户定义聚合 (UDA) 中的数据访问

Data Access within SQLCLR User-Defined Aggregates (UDA)

我了解 SQLCLR 聚合在数据访问方面的局限性。话虽如此,有没有办法(解决方法)将结果存储到 table?它必须在 SQLCLR 聚合中。

在 C# 函数中准备好聚合结果后,为什么不使用 C# ADO.NET(用于数据库操作)将这些聚合存储在数据库中。这将在您的 SQL CLR 函数中,以便您从数据库中调用 SQL CLR 函数一次,它将聚合存储在一些 table 中。

为什么需要将聚合结果存储到用户定义聚合 (UDA) 中的 table 中?这几乎没有意义,因为您可以使用普通 T-SQL:

将结果存储到 table
INSERT INTO SchemaName.TableName (Col1, Col2, ...)
  SELECT tab.SomeColumn, SchemaName.CustomAggregate(tab.OtherColumn)
  FROM   SchemaName.TableName tab
  GROUP BY tab.SomeColumn;

本质上,这与存储任何内置聚合函数的结果相同,例如:SUMMINMAXCOUNTAVG、等等

但是,如果您 确实 出于某种奇怪的原因需要这样做,只需使用外部连接(即 not Context Connection = true;) 在 UDA 的 Terminate() 方法中。

请注意,进行此类数据访问的要求是连接 尝试在当前事务上下文中登记(登记是默认行为)。这意味着您的连接字符串需要包含以下关键字和值:Enlist = false;。这确实有效,因为我已经在 Terminate() 方法中成功使用了以下内容,并且在添加 Enlist=false; 之前我也得到了“在此上下文中不允许数据访问。上下文是未标记 DataAccessKind.Read 或 SystemDataAccessKind.Read 的函数或方法,是从 Table 值函数的 FillRow 方法获取数据的回调,或者是 UDT 验证方法。 ”错误。

using (SqlConnection _Connection =
                    new SqlConnection("Trusted_Connection=true; Enlist=false;"))
{
    using (SqlCommand _Command = _Connection.CreateCommand())
    {
        _Command.CommandText = "SELECT TOP 1 * FROM sys.objects;";
        _Connection.Open();
        _Command.ExecuteNonQuery();
    }
}

另请注意,建立 regular/external 连接需要将程序集标记为 EXTERNAL_ACCESS。但是,不需要 将数据库设置为 TRUSTWORTHY ON:您只需签署程序集,从该 DLL/程序集在 master 中创建一个非对称密钥,从该非对称密钥创建一个登录名,最后 GRANT 登录 EXTERNAL ACCESS ASSEMBLY 权限。