SQL Server CLR 极速入门,启用、设计、部署、运行 10分钟内搞定
2010-04-26 09:19
513 查看
首先总结:SQLServerCLR设计简单,部署方便,效率很高,很安全,随数据库移动。
测试用例,视频演示在此下载:http://download.csdn.net/source/2279319
环境:SQLServer2005/2008,VisualStudio2005/2008
这时,系统会生成一个示例文件Function1.cs内容:
usingSystem;
usingSystem.Data;
usingSystem.Data.SqlClient;
usingSystem.Data.SqlTypes;
usingMicrosoft.SqlServer.Server;
publicpartialclassUserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
publicstaticSqlStringFunction1()
{
//在此处放置代码
returnnewSqlString("Hello");
}
}
现在可以直接右击解决方案,选择“部署”,状态栏里显示“部署已成功”
这个函数你可以在“数据库-->可编程性-->函数-->标量值函数”里看到
OK,这就是整个流程,VeryEasy.
柳永法(yongfa365)的用途:
去年给公司设计了个OA系统,公司的一些文件内容都非常长,所以选择了varchar(max),初期感觉查询速度还挺快,后来觉得越来越慢。
初步分析结果显示:
数据有近8000条
有3000多条数据len(txtContent)得到结果在4000字符以上
使用“数据库引擎优化顾问”,对其优化提速为"0%"
SQL语句类似:SELECT*FROMdbo.ArticlesWHEREtxtContentLIKE'%柳永法%'
以前做过的所有系统,从没有遇到这种问题
近一步分析结果:
数据条数很少,速度却这么慢,分析可能是数据库引擎问题换台机器试问题依旧,排除
like效率问题,以前的系统都是条数多,而这次遇到的是每条数据里字段内容很长,like除了在数据条数大时会出现性能问题外,还跟每条的字段内容长度有关。在网上查询并测试确认,确实是数据内容长度问题,而这个系统里是不可能使用like'柳永法%'这样可以使用索引的查询的。
想来想去只能是使用全文索引,但总会有一些记录查不出来,而这个要求就这么高,所以暂时放弃。这时想到了SQLServerCLR,以前只是听过,觉得可能有用,都收藏了起来,现在打开Chrome,把GoogleBookmark上收藏的关于SQLServer的CLR的链接全部打开研究了几分钟,自己写了个函数,部署,测试,哈哈……。忒玄妙了,以前的txtContentLIKE'%柳永法%'用时10到12秒,而用我写的SQLServerCLR函数dbo.ContainsOne(txtContent,'柳永法')=1只用了1秒左右,够神奇吧。
执行以下语句三次,相当于8年后数据量,有6万多条数据
INSERTdbo.Articles(txtTitle,txtContent)SELECTtxtTitle,txtContentFROMdbo.Articles
再执行测试,一般的like用时82秒,而clr用时5秒,够有看头吧。
函数及测试语句如下:
1[Microsoft.SqlServer.Server.SqlFunction]
2publicstaticSqlBooleanContainsOne(SqlCharsinput,stringsearch)
3{
4returnnewstring(input.Value).Contains(search);
5}
6
7SELECTCOUNT(*)FROMdbo.ArticlesWHEREdbo.ContainsOne(txtContent,'柳永法')=1
8
另外,我比较热衷于正则表达式,所以我还想给SQLServer增加一个正则表达式替换的功能,写起来也非常容易:
1[Microsoft.SqlServer.Server.SqlFunction]
2publicstaticSqlStringRegexReplace(SqlCharsinput,SqlStringpattern,SqlStringreplacement)
3{
4returnRegex.Replace(newstring(input.Value),pattern.Value,replacement.Value,RegexOptions.Compiled);
5}
娃哈哈,一切都这么的顺利,这么的得心应手,怎能不让我推荐,在此贴上我写的一此函数:
1usingSystem;
2usingSystem.Data;
3usingSystem.Data.SqlClient;
4usingSystem.Data.SqlTypes;
5usingMicrosoft.SqlServer.Server;
6usingSystem.Text.RegularExpressions;
7usingSystem.Collections.Generic;
8usingSystem.IO;
9
10/*
11请先在SQLServer里执行以下命名,来启用CLR
12execsp_configure'clrenabled',1--1,启用clr0,禁用clr
13reconfigure
14*/
15
16publicpartialclassUserDefinedFunctions
17{
18///<summary>
19///SQLCLR使用正则表达式替换,eg:
20///selectdbo.RegexReplace('<span>柳永法http://www.yongfa365.com/</span>','<.+?>','')
21///updateArticlessettxtContent=dbo.RegexReplace(txtContent,'<.+?>','')
22///--结果:柳永法http://www.yongfa365.com/
23///</summary>
24///<paramname="input">源串,或字段名</param>
25///<paramname="pattern">正则表达式</param>
26///<returns>替换后结果</returns>
27[Microsoft.SqlServer.Server.SqlFunction]
28publicstaticSqlStringRegexReplace(SqlCharsinput,SqlStringpattern,SqlStringreplacement)
29{
30returnRegex.Replace(newstring(input.Value),pattern.Value,replacement.Value,RegexOptions.Compiled);
31}
32
33
34
35
36///<summary>
37///SQLCLR使用正则表达式替换,eg:
38///selectdbo.RegexSearch('<span>柳永法</span>','<.+?>','')
39///select*fromArticleswheredbo.RegexSearch(txtContent,'柳永法')=1;
40///</summary>
41///<paramname="input">源串,或字段名</param>
42///<paramname="pattern">正则表达式</param>
43///<returns>查询结果,1,0</returns>
44[Microsoft.SqlServer.Server.SqlFunction]
45publicstaticSqlBooleanRegexSearch(SqlCharsinput,stringpattern)
46{
47returnRegex.Match(newstring(input.Value),pattern,RegexOptions.Compiled).Success;
48}
49
50///<summary>
51///SQLCLR使用.net的Contains查找是否满足条件,eg:
52///selectdbo.ContainsOne('我是柳永法,','柳永法');
53///select*fromArticleswheredbo.ContainsOne(txtContent,'柳永法')=1;
54///</summary>
55///<paramname="input">源串,或字段名</param>
56///<paramname="search">要搜索的字符串</param>
57///<returns>返回是否匹配,1,0</returns>
58[Microsoft.SqlServer.Server.SqlFunction]
59publicstaticSqlBooleanContainsOne(SqlCharsinput,stringsearch)
60{
61returnnewstring(input.Value).Contains(search);
62}
63
64
65///<summary>
66///SQLCLR使用.net的Contains查找是否满足其中之一的条件,eg:
67///selectdbo.ContainsAny('我是柳永法,','柳,永,法');
68///select*fromArticleswheredbo.ContainsAny(txtContent,'柳,永,法')=1;
69///</summary>
70///<paramname="input">源串,或字段名</param>
71///<paramname="search">要搜索的字符串,以","分隔,自己处理空格问题</param>
72///<returns>返回是否匹配,1,0</returns>
73[Microsoft.SqlServer.Server.SqlFunction]
74publicstaticSqlBooleanContainsAny(SqlCharsinput,stringsearch)
75{
76stringstrTemp=newstring(input.Value);
77foreach(stringiteminsearch.Split(','))
78{
79if(strTemp.Contains(item))
80{
81returntrue;
82}
83}
84returnfalse;
85}
86
87///<summary>
88///SQLCLR使用.net的Contains查找是否满足所有的条件,eg:
89///selectdbo.ContainsAll('我是柳永法,','柳,永,法');
90///select*fromArticleswheredbo.ContainsAll(txtContent,'柳,永,法')=1;
91///</summary>
92///<paramname="input">源串,或字段名</param>
93///<paramname="search">要搜索的字符串,以","分隔,自己处理空格问题</param>
94///<returns>返回是否匹配,1,0</returns>
95[Microsoft.SqlServer.Server.SqlFunction]
96publicstaticSqlBooleanContainsAll(SqlCharsinput,stringsearch)
97{
98stringstrTemp=newstring(input.Value);
99foreach(stringiteminsearch.Split(','))
100{
101if(!strTemp.Contains(item))
102{
103returnfalse;
104}
105}
106returntrue;
107}
108
109};
110
重要提示:
官方说明里有其dll部署方法,比较麻烦,推荐直接用VisualStudio部署,方便快捷。
SQLServerCLR部署到某个数据库后,便成为那个数据库的一部分,即便备份及还原到其它机器上,它依然具有CLR带来的功能。
SqlString数据类型转换成nvarchar(4,000),而SqlChars转换成nvarchar(max)。尽可能使用nvarchar(max)并且最大程度地保证灵活性。然而,如果所有相关字符串包含的字符都少于4,000个,使用nvarchar(4,000)则性能可得到显著改善。
CLR里返回的bool对应SQLServer里的bit,即:1/0/Null,而不是true/false,所以,没法直接用dbo.ContainsOne(txtContent,'柳永法')实现bool形,而得这么用:dbo.ContainsOne(txtContent,'柳永法')=1
参考:
SQLServerCLR集成简介:http://msdn.microsoft.com/zh-cn/library/ms254498(VS.80).aspx
SQLServer2005正则表达式使模式匹配和数据提取变得更容易:http://msdn.microsoft.com/zh-cn/magazine/cc163473.aspx
SQLCLR(一)入门:/article/5193623.html
应用C#和SQLCLR编写SQLServer用户定义函数:http://blog.csdn.net/zhzuo/archive/2009/05/24/4212982.aspx#mark4
此文同时在SQLServerCLR极速入门,启用、设计、部署、运行上发表
测试用例,视频演示在此下载:
环境:SQLServer2005/2008,VisualStudio2005/2008
在SQLServer里启用CLR:
在SQLServer里执行以下命名,来启用CLRexecsp_configure'clrenabled',1--1,启用clr0,禁用clr
reconfigure
用VisualStudio设计功能,并部署到相关数据库:
打开VisualStudio-->新建项目-->数据库-->SQLServer项目-->添加数据库引用里新建链接(一会将会把CLR部署到这个数据库上)-->右击解决方案,添加“用户自定义函数”这时,系统会生成一个示例文件Function1.cs内容:
usingSystem;
usingSystem.Data;
usingSystem.Data.SqlClient;
usingSystem.Data.SqlTypes;
usingMicrosoft.SqlServer.Server;
publicpartialclassUserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
publicstaticSqlStringFunction1()
{
//在此处放置代码
returnnewSqlString("Hello");
}
}
usingSystem;
usingSystem.Data;
usingSystem.Data.SqlClient;
usingSystem.Data.SqlTypes;
usingMicrosoft.SqlServer.Server;
publicpartialclassUserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
publicstaticSqlStringFunction1()
{
//在此处放置代码
returnnewSqlString("Hello");
}
}
现在可以直接右击解决方案,选择“部署”,状态栏里显示“部署已成功”
在SQLServer里执行我们部署的CLR函数:
再次进入SQLServer,进入到相关数据库,执行Selectdbo.Function1(),全显示执行结果:"Hello"这个函数你可以在“数据库-->可编程性-->函数-->标量值函数”里看到
OK,这就是整个流程,VeryEasy.
更高级应用:
当然我们用CLR不是只为了让他生成一个Hello就完事的,这里来说明一下去年给公司设计了个OA系统,公司的一些文件内容都非常长,所以选择了varchar(max),初期感觉查询速度还挺快,后来觉得越来越慢。
初步分析结果显示:
数据有近8000条
有3000多条数据len(txtContent)得到结果在4000字符以上
使用“数据库引擎优化顾问”,对其优化提速为"0%"
SQL语句类似:SELECT*FROMdbo.ArticlesWHEREtxtContentLIKE'%柳永法%'
以前做过的所有系统,从没有遇到这种问题
近一步分析结果:
数据条数很少,速度却这么慢,分析可能是数据库引擎问题换台机器试问题依旧,排除
like效率问题,以前的系统都是条数多,而这次遇到的是每条数据里字段内容很长,like除了在数据条数大时会出现性能问题外,还跟每条的字段内容长度有关。在网上查询并测试确认,确实是数据内容长度问题,而这个系统里是不可能使用like'柳永法%'这样可以使用索引的查询的。
想来想去只能是使用全文索引,但总会有一些记录查不出来,而这个要求就这么高,所以暂时放弃。这时想到了SQLServerCLR,以前只是听过,觉得可能有用,都收藏了起来,现在打开Chrome,把GoogleBookmark上收藏的关于SQLServer的CLR的链接全部打开研究了几分钟,自己写了个函数,部署,测试,哈哈……。忒玄妙了,以前的txtContentLIKE'%柳永法%'用时10到12秒,而用我写的SQLServerCLR函数dbo.ContainsOne(txtContent,'柳永法')=1只用了1秒左右,够神奇吧。
执行以下语句三次,相当于8年后数据量,有6万多条数据
INSERTdbo.Articles(txtTitle,txtContent)SELECTtxtTitle,txtContentFROMdbo.Articles
INSERTdbo.Articles(txtTitle,txtContent)SELECTtxtTitle,txtContentFROMdbo.Articles
再执行测试,一般的like用时82秒,而clr用时5秒,够有看头吧。
函数及测试语句如下:
1[Microsoft.SqlServer.Server.SqlFunction]
2publicstaticSqlBooleanContainsOne(SqlCharsinput,stringsearch)
3{
4returnnewstring(input.Value).Contains(search);
5}
6
7SELECTCOUNT(*)FROMdbo.ArticlesWHEREdbo.ContainsOne(txtContent,'柳永法')=1
8
另外,我比较热衷于正则表达式,所以我还想给SQLServer增加一个正则表达式替换的功能,写起来也非常容易:
1[Microsoft.SqlServer.Server.SqlFunction]
2publicstaticSqlStringRegexReplace(SqlCharsinput,SqlStringpattern,SqlStringreplacement)
3{
4returnRegex.Replace(newstring(input.Value),pattern.Value,replacement.Value,RegexOptions.Compiled);
5}
娃哈哈,一切都这么的顺利,这么的得心应手,怎能不让我推荐,在此贴上我写的一此函数:
1usingSystem;
2usingSystem.Data;
3usingSystem.Data.SqlClient;
4usingSystem.Data.SqlTypes;
5usingMicrosoft.SqlServer.Server;
6usingSystem.Text.RegularExpressions;
7usingSystem.Collections.Generic;
8usingSystem.IO;
9
10/*
11请先在SQLServer里执行以下命名,来启用CLR
12execsp_configure'clrenabled',1--1,启用clr0,禁用clr
13reconfigure
14*/
15
16publicpartialclassUserDefinedFunctions
17{
18///<summary>
19///SQLCLR使用正则表达式替换,eg:
20///selectdbo.RegexReplace('<span>柳永法http://www.yongfa365.com/</span>','<.+?>','')
21///updateArticlessettxtContent=dbo.RegexReplace(txtContent,'<.+?>','')
22///--结果:柳永法http://www.yongfa365.com/
23///</summary>
24///<paramname="input">源串,或字段名</param>
25///<paramname="pattern">正则表达式</param>
26///<returns>替换后结果</returns>
27[Microsoft.SqlServer.Server.SqlFunction]
28publicstaticSqlStringRegexReplace(SqlCharsinput,SqlStringpattern,SqlStringreplacement)
29{
30returnRegex.Replace(newstring(input.Value),pattern.Value,replacement.Value,RegexOptions.Compiled);
31}
32
33
34
35
36///<summary>
37///SQLCLR使用正则表达式替换,eg:
38///selectdbo.RegexSearch('<span>柳永法</span>','<.+?>','')
39///select*fromArticleswheredbo.RegexSearch(txtContent,'柳永法')=1;
40///</summary>
41///<paramname="input">源串,或字段名</param>
42///<paramname="pattern">正则表达式</param>
43///<returns>查询结果,1,0</returns>
44[Microsoft.SqlServer.Server.SqlFunction]
45publicstaticSqlBooleanRegexSearch(SqlCharsinput,stringpattern)
46{
47returnRegex.Match(newstring(input.Value),pattern,RegexOptions.Compiled).Success;
48}
49
50///<summary>
51///SQLCLR使用.net的Contains查找是否满足条件,eg:
52///selectdbo.ContainsOne('我是柳永法,','柳永法');
53///select*fromArticleswheredbo.ContainsOne(txtContent,'柳永法')=1;
54///</summary>
55///<paramname="input">源串,或字段名</param>
56///<paramname="search">要搜索的字符串</param>
57///<returns>返回是否匹配,1,0</returns>
58[Microsoft.SqlServer.Server.SqlFunction]
59publicstaticSqlBooleanContainsOne(SqlCharsinput,stringsearch)
60{
61returnnewstring(input.Value).Contains(search);
62}
63
64
65///<summary>
66///SQLCLR使用.net的Contains查找是否满足其中之一的条件,eg:
67///selectdbo.ContainsAny('我是柳永法,','柳,永,法');
68///select*fromArticleswheredbo.ContainsAny(txtContent,'柳,永,法')=1;
69///</summary>
70///<paramname="input">源串,或字段名</param>
71///<paramname="search">要搜索的字符串,以","分隔,自己处理空格问题</param>
72///<returns>返回是否匹配,1,0</returns>
73[Microsoft.SqlServer.Server.SqlFunction]
74publicstaticSqlBooleanContainsAny(SqlCharsinput,stringsearch)
75{
76stringstrTemp=newstring(input.Value);
77foreach(stringiteminsearch.Split(','))
78{
79if(strTemp.Contains(item))
80{
81returntrue;
82}
83}
84returnfalse;
85}
86
87///<summary>
88///SQLCLR使用.net的Contains查找是否满足所有的条件,eg:
89///selectdbo.ContainsAll('我是柳永法,','柳,永,法');
90///select*fromArticleswheredbo.ContainsAll(txtContent,'柳,永,法')=1;
91///</summary>
92///<paramname="input">源串,或字段名</param>
93///<paramname="search">要搜索的字符串,以","分隔,自己处理空格问题</param>
94///<returns>返回是否匹配,1,0</returns>
95[Microsoft.SqlServer.Server.SqlFunction]
96publicstaticSqlBooleanContainsAll(SqlCharsinput,stringsearch)
97{
98stringstrTemp=newstring(input.Value);
99foreach(stringiteminsearch.Split(','))
100{
101if(!strTemp.Contains(item))
102{
103returnfalse;
104}
105}
106returntrue;
107}
108
109};
110
重要提示:
官方说明里有其dll部署方法,比较麻烦,推荐直接用VisualStudio部署,方便快捷。
SQLServerCLR部署到某个数据库后,便成为那个数据库的一部分,即便备份及还原到其它机器上,它依然具有CLR带来的功能。
SqlString数据类型转换成nvarchar(4,000),而SqlChars转换成nvarchar(max)。尽可能使用nvarchar(max)并且最大程度地保证灵活性。然而,如果所有相关字符串包含的字符都少于4,000个,使用nvarchar(4,000)则性能可得到显著改善。
CLR里返回的bool对应SQLServer里的bit,即:1/0/Null,而不是true/false,所以,没法直接用dbo.ContainsOne(txtContent,'柳永法')实现bool形,而得这么用:dbo.ContainsOne(txtContent,'柳永法')=1
参考:
SQLServerCLR集成简介:
SQLServer2005正则表达式使模式匹配和数据提取变得更容易:
SQLCLR(一)入门:
应用C#和SQLCLR编写SQLServer用户定义函数:
此文同时在
相关文章推荐
- SQL Server CLR 极速入门,启用、设计、部署、运行 10分钟内搞定[转载]
- SQL Server CLR 极速入门,启用、设计、部署、运行
- SQL Server CLR 极速入门,启用、设计、部署、运行
- SQL Server CLR 极速入门,启用、设计、部署、运行
- SQL Server CLR ,启用、设计、部署、运行
- SQL Server AlwaysON从入门到进阶(4)——分析和部署Windows Server Failover Cluster
- SQL Server CLR系列(1)-创建CLR项目与自动部署
- SQL Server AlwaysON从入门到进阶(4)——分析和部署Windows Server Failover Cluster
- SQL Server CLR系列(2)-创建触发器与手动部署
- 用自定义代码扩展 Microsoft SQL Server Reporting Services (RDL设计器,RDL,扩展代码)
- Asp.net三层结构入门示例源码>>SQLserver/SQLHelper.cs
- SQL Server AlwaysOn部署
- SQL Server CLR全功略之三---CLR标量函数、表值函数和聚合函数(UDA)
- 部署 Microsoft SQL Server 2005 群集
- SqlServer SSAS IIS 部署
- SQLServer JOB无法运行的问题。
- SQL Server DB Type and CLR Type
- [PHP]折腾了一下午,终于搞定了PHP连接了MS SQL SERVER
- sql server data type and CLR data type
- Sql Server之旅——第九站 看公司这些DBA们设计的这些复合索引