【问题标题】:Data Access within SQLCLR User-Defined Aggregates (UDA)SQLCLR 用户定义聚合 (UDA) 中的数据访问
【发布时间】:2016-07-24 14:49:44
【问题描述】:

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

【问题讨论】:

  • 您到底想完成什么?请解释这个过程,因为这可能不是你想要做的..
  • 感谢大家的回复;但是,我不是要求代码/设计审查或批评。我只想知道在用户定义的聚合函数的上下文中访问数据是否有解决方法?

标签: sql sql-server sql-server-2014 sqlclr


【解决方案1】:

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

INSERT INTO SchemaName.TableName (Col1, Col2, ...)
  SELECT tab.SomeColumn, SchemaName.CustomAggregate(tab.OtherColumn)
  FROM   SchemaName.TableName tab
  GROUP BY tab.SomeColumn;

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

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

请注意,进行此类数据访问的要求是连接尝试在当前事务上下文中登记(并且登记是默认行为)。这意味着您的连接字符串中需要包含以下关键字和值:Enlist = false;。这确实有效,因为我已经在 Terminate() 方法中成功使用了以下内容,并且在添加 Enlist=false; 之前,我也得到了“在此上下文中不允许数据访问。上下文是一个函数或未标记 DataAccessKind.Read 或 SystemDataAccessKind.Read 的方法,是从表值函数的 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();
    }
}

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

【讨论】:

  • 无法访问 UDA 中的数据。异常:System.InvalidOperationException:在此上下文中不允许数据访问。
  • @T.Nguyen 我更新了我的答案以添加说明。如果将 Enlist=false; 添加到 ConnectionString 中,它确实有效。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2021-08-01
    • 2015-09-25
    • 2015-11-22
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 2021-08-20
    • 2015-12-03
    • 1970-01-01
    相关资源
    最近更新 更多