【问题标题】:What is the purpose and risks of enabling SQL CLR?启用 SQL CLR 的目的和风险是什么?
【发布时间】:2018-06-08 11:27:27
【问题描述】:

我们希望使用 tSQLt 测试框架来实施单元测试。前提条件是必须使用此命令启用 SQL CLR:

EXEC sp_configure 'clr enabled', 1; RECONFIGURE;

我很想知道 SQL CLR 的目的是什么以及在生产环境中启用它的风险?

【问题讨论】:

  • 当单独的 T-SQL 不足以满足所需功能时,需要 SQLCLR。在 tSQLt 的情况下,它使用 CLR 对象来提供 T-SQL 语言无法实现的单元测试功能。启用 CLR 确实会增加表面积,因此只应在需要时启用它。不过,不确定为什么要在生产中运行单元测试。最好在 prod 中禁用它并在测试环境中运行单元测试。
  • 我完全同意@DanGuzman re:不在生产环境中进行单元测试。这似乎是一个等待发生的问题,不管 SQLCLR。

标签: sql-server sqlclr tsqlt


【解决方案1】:

目的

SQLCLR 允许执行以下任一操作:

  1. 不能在 T-SQL 中完成,或者
  2. 无法像在 T-SQL 中那样高效地完成

两者都可以做很多事情,而 T-SQL 实际上更擅长这些事情。在这些情况下,不恰当地使用 SQLCLR 来执行这些操作,因此最好先进行研究以确保该操作无法在 T-SQL 中完成,或者肯定会更慢。

以性能为例,T-SQL 标量 UDF 会阻止并行执行计划。但是 SQLCLR 标量 UDF,只要没有数据访问并且它们被标记为 IsDeterministic=true,就不会阻止并行执行计划。

有关 SQLCLR 是什么和不是什么的更多详细信息,请参阅我为 SQL Server Central 撰写的Stairway to SQLCLR 系列中的第一篇文章:

Stairway to SQLCLR Level 1: What is SQLCLR?

或者,要了解可以在 SQLCLR 中做什么,请查看我的 SQL# 项目,这是一个包含 320 多个存储过程和函数的库,其中许多在免费版本中,其中许多可以工作在SAFE 模式下:SQLsharp.com

风险

风险因大会标记为的PERMISSION_SET(即SAFEEXTERNAL_ACCESSUNSAFE)以及正在执行的操作而异。可以在 UNSAFE 程序集中执行常规 T-SQL 中无法完成的操作(除了许多危险的操作已经可以通过一些扩展存储过程、xp_cmdshell 和 OLE 自动过程完成——sp_OA*) .标记为 SAFE 的程序集无法到达数据库外部,因此通常非常安全,但是您仍然可以通过公开“灾难性回溯”的正则表达式锁定系统(当然,这可以从 .NET Framework 开始缓解4.5,因此 SQL Server 2012 和更新版本,通过设置 RegEx 操作的最大时间限制)。标记为UNSAFE 的程序集可以写入静态变量,在 SQLCLR 使用的共享应用程序域模型的上下文中,这些变量允许会话之间共享内存。这可以允许缓存,但如果使用不当,很容易导致竞争条件。

测试

至于 tSQLt,我认为您不需要使用 SQLCLR 组件。我以为我看到它只是启用了一些扩展功能。无论哪种方式,源代码都可以在 GitHub 上获得,因此您可以查看它以了解它在做什么。我已经有一段时间没有看到它了,但据我记得,它不应该对它正在做的小事带来太大的风险(尤其是在开发 / QA 环境中)。

另一个不使用 SQLCLR 的选项是 DbFit。我一直更喜欢 DbFit,因为它完全在数据库之外。它基于 FitNesse 框架,用 Java 编写,您可以通过 wiki 样式的页面管理测试。默认情况下,它将测试包装在事务中,并在测试完成时回滚所有内容(即清理)。值得一看。

下载:DbFit project on GitHub
教程:Using the DbFit Framework for Data Warehouse Regression Testing

【讨论】:

  • 如何查看权限集值?
  • 另外,我们认为 DbFit 可以很好地用于生产数据库吗?
  • 1) 您可以使用以下查询检查 PERMISSION_SET 值:SELECT * FROM sys.assemblies;2) DbFit 是“更好的”(在我看来),因为它不会向它正在测试的服务器或数据库添加任何东西。但是,无论您选择哪种方法,您都应该永远在生产环境中进行测试。
【解决方案2】:

SQLCLR 允许您在 SQL Server 中创建 .NET 程序集并在其中运行代码。

根据程序集的权限,风险会有所不同。风险是这样的:

权限集:风险 SAFE 除了在 T-SQL 中可以做的事情之外,您不能做任何事情。所以还算安全。

EXTERNAL ACCESS你可以调用微软认可的.NET程序集中的代码,比如ADO.NET。相当安全,但仍有风险。

UNSAFE 您几乎可以做任何 .NET 框架允许您做的事情。实际上,除非您知道自己在做什么,否则请朝自己的头部开枪。

【讨论】:

  • 如何查看权限集值?
  • 正如@Solomon Rutzky 上面评论的那样,您可以通过以下方式检查权限值:SELECT permission_set_desc FROM sys.assemblies WHERE name = 'some_assembly_name'
猜你喜欢
  • 2011-07-20
  • 2011-03-14
  • 2011-11-09
  • 2011-12-30
  • 2010-11-19
  • 2013-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多