通过CLR同步SQL Server和Sharepoint List数据(一)

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:

写在前面

    本系列文章一共分为四部分:

        1. CLR概述。

        2. 在Visual Studio中进行CLR集成编程并部署到SQL Server,包括存储过程、触发器、自定义函数、自定义类型和聚合。

        3. CLR集成编程的调试和所遇到的问题。

        4. 利用CLR同步SQL Server表和Sharepoint List(来源于实际项目应用)。

    本系列文章建立在以下软件环境的基础上:

  • Windows Server 2003 Enterprise Edition Service Pack 2
  • Microsoft Visual Studio Team System 2008
  • Microsoft SQL Server 2008
  • Microsoft Office Sharepoint Server 2007

 

前言

    CLR(Common Language Runtime)公共语言运行时是Microsoft在.NET出来之后创造出来的一个概念,它是.NET架构中重要的组成部分,为所有.NET Framework代码提供执行环境。在CLR中运行的代码称为托管代码。CLR提供执行程序所需的各种函数和服务,包括实时(JIT)编译、分配和管理内存、强制类型安全、异常处理、线程管理和安全性等。相信读者已经在任何一本介绍.NET的书中对它进行了了解,并且深知CLR的工作原理。本文要介绍的不仅仅是.NET架构中的CLR,更多的则是有关CLR的集成编程。事实上,Microsoft在公共语言运行时(CLR)集成编程上已经做了很多准备了,以至于用户现在可以用.NET的任何一种语言将自己编写好的功能安插在微软的任何一款产品上(可能有些夸张了),例如SQL Server、Office产品等,本文正是针对CLR在SQL Server上的应用进行介绍。有关CLR在其它产品上的应用,我将在其它系列文章中再做介绍(如VSTO等)。

    从SQL Server 2005开始,Microsoft就已经在其中集成了公共语言运行时(CLR)组件,只不过当时的应用可能还不太广泛(也许我当时还并没有怎么听说),使用的用户不多。但是,这也就意味着用户已经可以使用.NET的任何一种语言(如VB.NET和C#.NET等)来为数据库编写存储过程、触发器、用户定义类型、用户定义函数、用户定义聚合和流式表函数等等数据库对象了。这个消息听起来着实让人很兴奋,这让那些许多年来都十分保守的DBA、DEV(数据库开发人员)们有了更多的选择,同时也让许多单纯的SDE(软件开发人员)可以尝试数据库开发,从而让程序和后台的数据库结合得更加紧密,开发人员之间的协作更加顺畅。

 

公共语言运行时(CLR)集成概述

    Microsoft SQL Server已经具备了与.NET Framework的公共语言运行时(CLR)组件集成的功能。CLR为托管代码提供服务,例如跨语言集成、代码访问安全性、对象生存期管理以及调试和分析支持,它具有以下一些特点:

  • 更好的编程模型。.NET Framework语言在许多方面都比 Transact-SQL丰富,它为SQL Server开发人员提供了以前没有的构造和功能。开发人员还可以利用 .NET Framework 库的功能,它提供了大量可用于快速有效地解决编程问题的类。
  • 改进了安全和安全性。托管代码在数据库引擎承载的公共语言运行时环境中运行。SQL Server利用这一特点为在 SQL Server 早期版本中提供的扩展存储过程提供更安全更可靠的替代方法。
  • 能够定义数据类型和聚合函数。 用户定义类型和用户定义聚合是两个新的托管数据库对象,这两个对象扩展了SQL Server的存储和查询功能。
  • 通过标准化环境简化了开发。数据库开发集成到将来版本的Microsoft Visual Studio .NET开发环境中。开发人员在开发和调试数据库对象和脚本时所使用的工具与他们编写中间层或客户端层的 .NET Framework组件和服务时所使用的工具相同。
  • 具备改善性能和可扩展性的潜力。在多数情况下,.NET Framework语言编译和执行模型通过Transact-SQL提高性能。

    托管代码使用代码访问安全性(CAS)来使程序集无法执行某些操作。SQL Server使用CAS来帮助保护托管代码,并阻止对操作系统或数据库服务器的侵害。

CLR集成的优点

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

选择Transact-SQL还是托管代码

    如果代码主要执行没有或只有很少过程逻辑的数据访问,请使用Transact-SQL。如果要编写有复杂逻辑并且CPU占用量大的函数和过程,或者想使用.NET Framework的BCL,则使用托管代码。

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

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

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

    可以生成扩展存储过程来执行使用Transact-SQL存储过程无法实现的功能。但是,扩展存储过程可能有损于SQL Server进程的完整性,而经过验证确定为类型安全的托管代码则不会。进一步来说,在CLR的托管代码与SQL Server之间更深入地集成了内存管理、线程及纤程的调度以及同步服务。如果所编写的存储过程需要执行在Transact-SQL中不可能完成的任务,则CLR集成有比扩展存储过程更安全的方式来实现它。

 

公共语言运行时(CLR)集成性能

    现在开发人员可以自由选择Transact-SQL或者CLR进行SQL Server数据库开发,但是两者在性能方面各有优缺点,针对于不同类型的运算和数据库对象,下表给出了两者之间的区别。

类型

Transact_SQL

CLR

用户定义函数 执行数据访问时更有效。 适用于过程代码、计算和字符串操作以及需要大量计算和不执行数据访问的部分。
用户定义聚合 非基于游标的本机内置聚合函数的性能高于CLR方式。 性能高于基于游标的聚合,但执行速度较慢。
流式表值函数(TVF函数)

托管TVF的性能优于可比扩展存储过程实现的性能,它返回IEnumerable接口的托管函数。
数组与游标 游标的性能低于CLR中的数组 当Transact-SQL游标必须遍历更容易表示为数组的数据时,使用托管代码可以显著提高性能。
字符串数据 char或varchar数据类型。 托管函数中可以是SqlString或 SqlChars类型。
扩展存储过程 无法查看或控制扩展存储过程的资源使用情况。 可以使用托管代码对给定的线程进行检测。

 

公共语言运行时(CLR)集成安全性

    与.NET Framework公共语言运行时 (CLR) 集成的SQL Server的安全模式用于管理和保护SQL Server内运行的不同类型CLR对象和非CLR对象之间的访问。这些对象可能由Transact-SQL语句或服务器上运行的其他CLR对象调用。对象之间的调用称为链接。对这些对象执行的安全检查类型取决于相关的链接类型。CLR集成安全模式可实现以下目的:

  • 默认情况下,在SQL Server中运行托管用户代码不应当损害SQL Server的完整性和稳定性。如果执行有可能损害 SQL Server可靠性的操作,则应当受到适当的高级权限的保护。
  • 托管用户代码不应当获得对数据库中用户数据或其他用户代码的未经授权访问。用户定义代码应当在调用该代码的用户会话的安全上下文中运行,且拥有该安全上下文的正确特权。
  • 应当有控制来限制用户代码不得访问服务器以外的任何资源,而只能用于本地数据访问和计算。
  • 用户定义代码不应能通过在SQL Server进程中运行而获得对系统资源的未经授权访问。

    SQL Server已经集成了SQL Server基于用户的安全模式和CLR基于代码访问的安全模式。SQL Server主机策略级别授予程序集的代码访问安全性权限集由创建该程序集时指定的权限集决定。有三个权限集:SAFE、EXTERNAL_ACCESS和UNSAFE。

SAFE 最具限制性的权限集,只允许内部计算和本地数据访问,无法访问外部系统资源,如文件、网络、环境变量或注册表。并且只能使用上下文连接字符串指定数据库连接,即context connection=truecontext connection=yes
EXTERNAL_ACCESS 与SAFE具有相同的权限,但允许访问外部系统资源。
UNSAFE 允许程序集不受限制地访问SQL Server内部和外部的资源,此时程序集被授予FullTrust。

    一般情况下,在不使用SQL Server外部系统资源时建议采用SAFE方式的程序集,如果在程序集中需要访问外部系统资源,推荐使用EXTERNAL_ACCESS,而不是UNSAFE,后者将允许程序集中的代码对SQL Server进程空间进行非法操作,可能会损害SQL Server的健壮性和可靠性。EXTERNAL_ACCESS程序集默认情况下将以SQL Server的当前服务账户运行,它可以显示模拟调用方的Windows身份验证安全上下文,这也就是我在后面使用SQL CLR连接Sharepoint List时为什么要将程序集设置为EXTERNAL_ACCESS

 

结语

    总之,公共语言运行时(CLR)为使用C# Custom程序集连接SQL Server和外部资源(诸如Sharepoint List、网络资源、文件系统等),以及SQL Server本身数据运算提供了良好的基础和更好的便利性。在下一篇文章中我将介绍如何在SQL Server 2008中开启CLR并编写CLR使之在SQL Server中成功运行,当中可能会遇到很多小的问题,到时我会一一给出解决办法。

1 2 3 4


本文转自Jaxu博客园博客,原文链接:http://www.cnblogs.com/jaxu/archive/2009/03/20/1415358.html,如需转载请自行联系原作者


相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
SQL 数据库
Powerdesigner 16.5 从SQL Server 2012做逆向工程时提示:Unable to list tables问题
原文:Powerdesigner 16.5 从SQL Server 2012做逆向工程时提示:Unable to list tables问题 公司深圳团队开发有一套系统在华北区这边推向客户,在一次更新补丁时,由于发生了数据字典的变更,但深圳团队并未给出数据库的更新脚本,只给了新版本的数据库创建脚本,为了保证客户方系统中已有数据不丢失,只能自己想办法了:用Powerdesigner把新版本数据库逆向过来后,将此模型Apply到已有数据库中,此时Powerdesigner会比较两个版本的差异,只更新差异而不会丢失数据了。
1044 0
|
1月前
|
存储 安全 Java
java集合框架及其特点(List、Set、Queue、Map)
java集合框架及其特点(List、Set、Queue、Map)
|
3月前
|
Java 程序员
Java集合框架:List、Set、Map类型及泛型详解
Java集合框架:List、Set、Map类型及泛型详解
|
25天前
|
Java
Java使用List去重的四中方式
Java使用List去重的四中方式
19 6
|
1月前
|
Java
JAVA——List中剔除空元素(null)的三种方法汇总
JAVA——List中剔除空元素(null)的三种方法汇总
|
1月前
|
安全 Java API
Java并发 - J.U.C并发容器类 list、set、queue
Queue API 阻塞是通过 condition 来实现的,可参考 Java 并发 - Lock 接口 ArrayBlockingQueue 阻塞 LinkedBlockingQueue 阻塞 ArrayQueue 非阻塞 LinkedQueue 非阻塞
|
1月前
|
存储 安全 Java
【Java】集合(一)单列集合List
【Java】集合(一)单列集合List
22 0
|
1月前
|
Java API
java 对象list 使用stream进行过滤
在Java中,你可以使用Stream API对对象列表进行过滤。假设你有一个`List<MyObject>`,并且你想根据某些条件过滤出特定的对象。以下是一个示例: ```java import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<MyObject> myObjects = ... // 初始化你的对象列表 List<MyObject> filter
|
1月前
|
算法 安全 Java
java将list中的某个元素移动位置
【2月更文挑战第12天】
|
2月前
|
Java 索引
java list中包含某个字符串
【2月更文挑战第9天】