【问题标题】:What are good problems to solve using CLR stored procs?使用 CLR 存储过程可以解决哪些好的问题?
【发布时间】:2011-01-09 14:34:41
【问题描述】:

我在 SQL Server 中使用 CLR 存储过程已经有一段时间了,但我仍然想知道使用它们的最佳情况是什么。

MSDN 提供了一些使用指南,例如繁重的字符串操作 (regex),或替换声明大量表变量和游标的 T-SQL。我很想知道 SO 用户使用 CLR 存储过程解决了哪些问题,以及示例/基准测试。

例如,我发现 CLR 存储过程 + SSRS 是一种很好的方法,可以将数据操作逻辑从 SSRS 和 T-SQL 中提取出来,并将其放入更易于阅读和操作的托管代码中。

【问题讨论】:

    标签: c# .net sql-server vb.net sqlclr


    【解决方案1】:

    字符串操作 - 正则表达式搜索是经典。在 CLR 中很容易暴露,在直接的 T-SQL 中很难做到。

    请参阅 this link 了解实施细节和微基准 (SQLCLR is only 47 milliseconds compared to 6.187 seconds for the T-SQL UDF)。

    【讨论】:

      【解决方案2】:

      已经提到了字符串操作(正则表达式),还有 DateTime 算法,当然还有另一个大问题 - 调用外部 Web 服务。

      【讨论】:

      • 嗨,Marc,你能举一个例子来说明你可以通过在 CLR proc 中访问外部 Web 服务来解决的问题吗? +1 肯定有用。
      • 很多东西 - 例如。获取最新的货币汇率,获取最新的股票信息等等
      【解决方案3】:
      • 自定义聚合
      • 字符串操作
      • 自定义数据类型

      说实话,我只看到了字符串处理,其中包括将 CSV 拆分为行。

      除非我是从事 DBA 类型工作的 DBA,否则我认为任何需要超过默认信任级别的东西都超出了界限。

      来自 MSDN 的 RegEx 和 RSS 提要示例:Using CLR Integration in SQL Server 2005

      【讨论】:

        【解决方案4】:

        许多需要非规范化和/或顺序操作的问题都可以由 CLR 处理得非常好,并且可以用来显着提高性能而不会牺牲 SQL 端的可用性(很多)。您可以采用混合方法,将基于集合的解决方案用于大型运输,并切换到紧密循环的迭代模型,而不是完全依赖基于集合或迭代操作。

        SQL Server 2008 中内置的hierarchyid 和地理空间(即geography)类型是非规范化问题的好例子。两者都包含(几乎)任意大量的数据,这些数据难以在不影响性能的情况下进行标准化 - 您需要使用递归或游标来对它们进行任何有意义的工作,或者使用老鼠巢的触发器和/或计划任务来维护一个非规范化表。

        我用 CLR 类型解决的另一个问题是内联压缩。这听起来像是毫无意义或学术性的练习,但是当您的完全规范化的数据进入 TB 级时,大小减少 80-90% 意味着很多。 SQL 现在有自己的内置压缩,SQL 2005 有 vardecimal,这些也是很好的工具,但是域感知“最小化”算法在 CPU 负载和压缩率方面的效率可以提高几倍。显然这并不适用于所有问题,但它适用于某些问题。

        在这个网站上经常发现的另一个非常常见的问题是动态生成序列 - 例如连续日期的序列。常见的解决方案是递归 CTE、静态序列表和鲜为人知的 spt_values 表,但简单的 CLR UDF 比它们中的任何一个都执行得更好,并且提供了更多的灵活性。

        我的列表中的最后一个:用户定义的流式聚合也非常有用,尤其是对于任何与统计相关的内容。有些东西你根本无法从内置 SQL 聚合中组合出来,例如中位数、加权移动平均线等。UDA 也可以接受多个参数,因此你可以将它们参数化;从技术上讲,不能保证聚合在当前版本的 SQL Server 中以任何特定顺序接收数据,但是您可以通过将 ROW_NUMBER 作为附加参数提供给它并使用它来实现几乎任何窗口函数来解决该限制(让聚合吐出一个 UDT,然后可以将其转换为表格)。

        真正有用的 SQL-CLR 应用程序的示例很少,这实际上非常令人沮丧。在 Google 上搜索,你会得到 1000 万条结果,其中每一条都是一些愚蠢的字符串连接或正则表达式。这些很有用,但需要花几分钟时间来了解 SQL UDT 和 UDA,尤其是您将开始在自己的应用程序中看到它们的大量用途。当然,不要发疯 - 仔细考虑在纯 SQL 中是否有更好的解决方案 - 但也不要打折扣。

        【讨论】:

        • 这是我读过的信息量最大的帖子之一。谢谢。
        【解决方案5】:

        这是我使用 CLR procs 的一个例子,我认为它很简洁:

        使用 CLR 存储过程和 SQL 作业从外部 Web 服务定时更新数据。

        我们有一个应用程序可以将它跟踪的一些数据与外部行业数据馈送同步。每周同步运行所有内容,也按需运行单个更新,因此我有一个现有的 Web 服务 API 来访问它。 Windows 服务已经安排了事情,但我想为什么不能像我们的其他 SQL 作业一样安排它们?

        我创建了一个引用应用程序 Web 服务 API 的 CLR 存储过程。然后我为 @RecordID 添加了一些参数以支持单同步,并将其安排在企业管理器 SQL 作业中。

        现在我可以使用 Job 运行 dB 同步或使用其他 SQL proc 或 Trigger 中的 proc 来更新来自外部提要的数据。

        以后把应用webservice API去掉,直接使用外部webservice可能会更干净。不过就目前而言,这实现起来非常快,而且是一种将功能扩展到 SQL 组的好方法。

        【讨论】:

          【解决方案6】:

          对于从不提供传统 SQL 接口或供应商对该接口的实现低于标准的系统中提取数据非常有用。

          我们有一个在旧 MUMPS 平台上构建的核心应用程序,在 Intersystems Cache 数据库上运行。数据是分层的,而不是本质上的关系。主全局数组(即表)具有多个数据级别和元素,所有这些都按帐号分组在一起。即使扫描一列也需要从磁盘加载整个全局,并且需要 8 多个小时。供应商确实提供了 ODBC 驱动程序和全局映射,但它通常会导致扫描和极慢的查询。

          我构建了一个表值函数,它采用 ObjectScript(MUMPS 的系统间方言)程序,在缓存服务器上执行它并将输出行作为数据行返回。我可以在 MUMPS 端对数据访问路径进行微观管理(这确实是获得有效数据访问所需要的),方法是提供一个在该端执行的特定程序,然后轻松地将 MSSQL 中的数据作为临时内联数据源导入。

          我可以使用 TVF 来驱动数据选择或使用CROSS APPLY 在另一端进行查找,而且效率相当高。如果我强制 MSSQL 使用并行执行计划,我什至可以在远程端并行运行多个查询。

          【讨论】:

          • > "并将输出行作为数据行返回。"您是否先将数据放入 System.Data.DataTable 中?我有一些辅助函数来编写数据表,但想知道如何使用 IEnumerable 来完成。
          • 有一个带有流式表值函数的 FillRow 方法,它具有固定的行投影。在原始版本中,我从查询中返回了最多 8 个字符字段,如 F1、F2、F3...
          • 谢谢 - 我认为相关的例子:stackoverflow.com/questions/6901811/…
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-01-05
          • 1970-01-01
          • 2023-03-06
          • 2010-11-03
          • 2010-09-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多