C# 使用CLR存储过程可以解决哪些好问题?

C# 使用CLR存储过程可以解决哪些好问题?,c#,.net,sql-server,vb.net,sqlclr,C#,.net,Sql Server,Vb.net,Sqlclr,我在SQLServer中使用CLR存储过程已经有一段时间了,但我仍然想知道使用它们的最佳情况是什么 MSDN提供了一些使用指南,比如重字符串操作(regex),或者替换声明大量表变量和游标的T-SQL。我很想知道用户使用CLR存储的进程以及示例/基准测试解决了哪些问题 例如,我发现CLR存储过程+SSR是一种很好的方法,可以将数据操作逻辑从SSR和T-SQL中提取出来,并将其放入易于阅读和操作的托管代码中。字符串操作-正则表达式搜索是一种经典方法。在CLR中很容易公开,在直接T-SQL中很难公开

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

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


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

字符串操作-正则表达式搜索是一种经典方法。在CLR中很容易公开,在直接T-SQL中很难公开

有关实现和微基准测试的详细信息,请参见(
SQLCLR仅为47毫秒,而T-sqludf为6.187秒)。

已经提到了字符串操作(regexes),但也提到了日期时间算法,当然还有另一个大问题——调用外部web服务。

  • 自定义聚合
  • 字符串操作
  • 自定义数据类型
老实说,我只看到字符串处理,其中包括将CSV拆分成行

我会考虑需要更多的东西,然后默认的信任级别超出界限,除非我是做DBA类型的DBA。


从带有RegEx和RSS提要的MSDN示例中可以看出:

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

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

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

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

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


事实上,真正有用的SQL-CLR应用程序的例子太少了,这让人非常沮丧;在谷歌上搜索,你会得到1000万个结果,每一个结果都是一些愚蠢的字符串连接或正则表达式。这些都很有用,但要花几分钟的时间来学习SQL UDT和UDA,你会开始看到大量的用途在您自己的应用程序中使用它们。当然,不要发疯-仔细考虑纯SQL中是否有更好的解决方案-但也不要低估它们。

以下是我使用CLR procs的一个示例,我认为它很简洁:

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

我们有一个应用程序,可以将它跟踪的一些数据与外部行业数据源同步。同步每周都会运行,并且会按需进行单个更新,因此我有一个现有的webservice API来访问它。事情已经由windows服务安排好了,但我想为什么不能像其他SQL作业那样安排它们呢

我创建了一个引用应用程序的webservice API的CLR存储过程。然后我为@RecordID添加了几个参数以支持单一同步,并将其安排在Enterprise manager SQL作业中

现在,我可以使用该作业运行数据库同步,或者在其他SQL过程或触发器中使用该过程来更新外部提要中的数据


将来使用应用程序webservice API并直接使用外部webservice可能会更干净。不过,就目前而言,这实现起来非常快,是将功能扩展到SQL组的一种很酷的方式。

这对于从不提供传统SQL接口或供应商支持的系统中提取数据非常有用s对该接口的实现是不合格的

我们有一个核心应用程序,建立在旧的腮腺炎平台上,运行在系统间缓存数据库上。数据是分层的,本质上不是关系型的。主全局数组(即表)有多个数据级别,所有元素都分组在一起