为什么我们使用 CLR 程序。CLR 程序或任何 CLR 程序是唯一解决方案的示例是否有任何意义?
5 回答
假设您想使用正则表达式验证 SQL Server 中的某些数据字段。直到今天,即使在 SQL Server 2008 R2 中,仅使用 T-SQL 代码也几乎不可能。
但是,在 CLR 存储过程或存储函数的帮助下,这将是小菜一碟。
T-SQL 在处理数据集方面非常强大 - 使用它。
CLR 在其他领域非常强大,例如字符串和日期操作、调用外部服务(WCF、Web 服务)。
因此,T-SQL 存储过程和 CLR 存储过程是一个很好的补充——它们各自解决了对方并不擅长的特定挑战。
有一些事情不能在 SQL Server 中完成(或者在某些情况下,在托管代码中做得不好)。
- CLR 有RegEx。
- 您可以调用网络服务。
- CLR 具有更好的性能(例如,如果您必须对每一行进行大量数学运算)
- 代码重用
- 用您习惯的语言(VB.Net、C# 等)编写。
我对类似问题发布了以下答案:SQL SERVER CLR 的优势。不过,鉴于至少 2 个答案中提到了某些内容,我将在此处添加:C# / VB.net / etc 作为一种比 T-SQL 更适合的语言,不应成为在 T-SQL 上使用 SQLCLR 的理由。如果有人不知道如何在 T-SQL 中完成某事,请首先寻求帮助以找到 T-SQL 解决方案。如果不存在,则走 CLR 路线。
SQL Server 中的 SQLCLR / CLR 集成只是帮助解决某些(不是全部)问题的另一种工具。有些事情它比纯 T-SQL 做得更好,有些事情只能通过 SQLCLR 完成。我为 SQL Server Central 写了一篇文章,Stairway to SQLCLR Level 1:什么是 SQLCLR?(需要免费注册才能阅读那里的文章),这解决了这个问题。基础知识是(有关详细信息,请参阅链接的文章):
- 流表值函数 (sTVF)
- 动态 SQL(在函数和触发器内——可以访问
inserted
和deleted
表) - 更好地访问外部资源/替换 xp_cmdshell
- 传入数据更容易
- 取回结果集的多列更容易
- 没有外部依赖(例如 7zip.exe)
- 通过模拟提高安全性
- 多线程能力
- 错误处理(函数内)
- 自定义聚合
- 自定义类型
- 修改状态(在函数内且不带
OPENQUERY
/OPENROWSET
) - 执行存储过程(只读;在函数内且不带
OPENQUERY
/OPENROWSET
) - 性能(注意:这并不是在所有情况下都有意义,但在某些情况下肯定取决于操作的类型和复杂性)
- 计算/字符串操作
- SQLCLR UDF,如果标有
DataAccess = None
,可用于并行执行计划,而 T-SQL UDF 阻止并行计划
- 可以捕获输出(即发送到 SSMS 中的“消息”选项卡的内容)(例如,
PRINT
严重性= 0 到 10)——我忘了在文章中提到这一点 ;-)。RAISERROR
要考虑的另一件事是,有时能够在应用程序和数据库之间共享代码是有益的,这样数据库就可以深入了解某些业务逻辑,而无需构建自定义的、仅限内部的屏幕来访问该应用程序代码。例如,我曾在一个系统上工作,该系统从客户那里导入数据文件,并使用大多数字段的自定义哈希并将该值保存到数据库中的行中。这允许在再次导入数据时轻松跳过行,因为应用程序将对输入文件中的值进行哈希处理并与存储在行上的哈希值进行比较。如果它们相同,那么我们立即知道所有字段都没有改变,所以我们进入下一行,这是一个简单的 INT 比较。但是用于进行哈希的算法仅在应用程序代码中,因此无论是用于调试客户案例还是通过标记至少有一个字段发生更改的行(来自我们的应用程序的更改)来寻找将某些处理卸载到后端服务的方法与在较新的导入文件中查找更改相反),我无能为力。这将是一个在数据库中拥有相当简单的业务逻辑的绝佳机会,即使不是用于正常处理;在数据库中拥有相当于编码值而无法理解其含义的内容使得解决问题变得非常困难。这将是一个在数据库中拥有相当简单的业务逻辑的绝佳机会,即使不是用于正常处理;在数据库中拥有相当于编码值而无法理解其含义的内容使得解决问题变得非常困难。这将是一个在数据库中拥有相当简单的业务逻辑的绝佳机会,即使不是用于正常处理;在数据库中拥有相当于编码值而无法理解其含义的内容使得解决问题变得非常困难。
如果有兴趣在不编写任何代码的情况下查看其中的一些功能,SQL#的免费版本(我是它的作者)有 RegEx 函数、自定义聚合 (UDA)、自定义类型 (UDT) 等。
好吧,如果你想:
- 对数据进行复杂的操作,以及
- 想要接近数据(即不在 ASP.NET 或 Winforms 应用程序中),并且
- 您更喜欢用 C# 编写代码而不是 SQL。
当您使用 CLR 过程时就是这种情况。我没有一个例子,但应该可以想象一个。
- 编辑:
一个想象的可能是将数据转换为数据仓库类型的结构。在这种情况下,您可能希望重新格式化并运行一些分析。那么它可能适合在 CLR 中进行。(我不建议这正是我会做的,但可以考虑)。
如果您想做一些重要的数学计算,或调用外部 Web 服务或类似的东西,您无法从 T-SQL 中进行,而 .Net 存储过程或函数将非常有助于解决这些问题。
您还可以使用 CLR 过程编写聚合函数,这在 T-SQL 中是无法做到的。
当然,对于数据操作,T-SQL 存储过程会执行得更好,并且更容易编写。