CLR 集成 - 概述

适用于:SQL Server Azure SQL 托管实例

公共语言运行时 (CLR) 是 Microsoft .NET Framework 的核心,它为所有 .NET Framework 代码提供执行环境。 在 CLR 中运行的代码称为托管代码。 CLR 提供执行程序所需的各种函数和服务,包括实时 (JIT) 编译、分配和管理内存、强制类型安全、异常处理、线程管理和安全性。 有关详细信息,请参阅 .NET Framework SDK。

使用在 Microsoft SQL Server 中驻留的 CLR(称为 CLR 集成),可以在托管代码中编写存储过程、触发器、用户定义函数、用户定义类型和用户定义聚合。 由于托管代码在执行之前才编译为本机代码,因此在某些情形下可以大幅提高性能。

托管代码使用代码访问安全性 (CAS) 来阻止程序集执行某些操作。 SQL Server 使用 CAS 来帮助保证托管代码的安全,并避免操作系统或数据库服务器受到威胁。

CLR 集成的优点

Transact-SQL 专为数据库中的直接数据访问和操作而设计。 虽然 Transact-SQL 擅长数据访问和管理,但它不是一种全面的编程语言。 例如,Transact-SQL 不支持数组、集合、for-each 循环、位移位或类。 虽然其中一些构造可以在 Transact-SQL 中模拟,但托管代码已集成对这些构造的支持。 根据具体情况,这些功能足以为在托管代码中实现某些数据库功能提供充分理由。

Microsoft Visual Basic .NET 和 Microsoft Visual C# 提供面向对象的功能,例如包装、继承和多态性。 现在可以很容易将相关代码组织到类和命名空间中。 如果正在处理大量服务器代码,这将允许您更容易组织和维护代码。

托管代码比 Transact-SQL 更适合用于计算和复杂的执行逻辑,并且对许多复杂任务(包括字符串处理和正则表达式)的广泛支持。 使用在 .NET Framework 库中提供的功能,可以访问数千个预建的类和例程。 可以很容易从任何存储过程、触发器或用户定义函数访问它们。 基类库 (BCL) 包括可为字符串操纵、高级数学操作、文件访问、加密等提供功能的类。

注意

虽然可以在 SQL Server 中从 CLR 代码的内部使用很多这样的类,但那些不适合用于服务器端的类(例如,窗口类)将不可用。 有关详细信息,请参阅 支持的 .NET Framework 库

托管代码的一个好处是类型安全,即确保代码仅以明确定义和许可的方式访问类型。 在执行托管代码之前,CLR 将验证该代码是否安全。 例如,系统将检查代码以确保其不会读取以前未曾写入的内存。 CLR 还可以帮助确保代码不会操纵非托管内存。

CLR 集成为提高性能提供了可能。 有关信息,请参阅 CLR 集成的性能。

警告

CLR 在 .NET Framework 中使用代码访问安全性 (CAS)(不可再作为安全边界)。 使用 PERMISSION_SET = SAFE 创建的 CLR 程序集可以访问外部系统资源、调用非托管代码以及获取 sysadmin 特权。 从 SQL Server 2017 (14.x) 开始,引入了名为 clr strict securitysp_configure 选项,以增强 CLR 程序集的安全性。 默认启用 clr strict security,并将 SAFEEXTERNAL_ACCESS 程序集与标记为 UNSAFE 的程序集同等对待。 可禁用 clr strict security 选项以实现后向兼容性,但不建议这样做。 Microsoft 建议所有程序集都通过证书或非对称密钥进行签名,且该证书或非对称密钥具有已在主数据库中获得 UNSAFE ASSEMBLY 权限的相应登录名。 有关详细信息,请参阅 CLR 严格安全性

选择 Transact-SQL 还是托管代码

编写存储过程、触发器和用户定义的函数时,必须做出的一个决定是使用传统的 Transact-SQL,还是使用 Visual Basic .NET 或 Visual C# 等 .NET Framework 语言。 当代码主要执行数据访问时,使用 Transact-SQL 时,几乎没有或没有过程逻辑。 如果要编写有复杂逻辑并且 CPU 占用量大的函数和过程,或者想使用 .NET Framework 的 BCL,则使用托管代码。

选择在服务器中执行还是在客户端中执行

决定是使用 Transact-SQL 还是托管代码是希望代码驻留的位置、服务器计算机还是客户端计算机,还有另一个因素。 Transact-SQL 和托管代码都可以在服务器上运行。 这种方式可以将代码和数据靠近放在一起,并允许您利用服务器的强大处理能力。 另一方面,您可能希望避免将处理器占用量大的任务放在数据库服务器上。 目前大多数客户端计算机都有非常强大的功能,因此您可能希望通过将尽可能多的代码放在客户端上,来利用这种处理能力。 托管代码可以在客户端计算机上运行,而 Transact-SQL 则无法运行。

选择扩展存储过程还是托管代码

可以生成扩展存储过程,以执行 Transact-SQL 存储过程无法实现的功能。 但是,扩展存储过程可能会损害 SQL Server 进程的完整性,而验证为类型安全的托管代码则无法。 此外,内存管理、线程和光纤计划以及同步服务在 CLR 和 SQL Server 的托管代码之间更深入地集成。 使用 CLR 集成,可以通过比扩展存储过程更安全的方式来编写在 Transact-SQL 中无法执行的任务所需的存储过程。 有关 CLR 集成和扩展存储过程的详细信息,请参阅 CLR 集成的性能。

另请参阅

安装 .NET Framework
CLR 集成体系结构
从 CLR 数据库对象进行数据访问
CLR 集成入门