提高你的数据库编程效率:Microsoft CLR Via Sql Server

你还在为数据库编程而抓狂吗?那些恶心的脚本拼接,低效的脚本调试的日子将会与我们越来越远啦。现在我们能用支持.NET的语言来开发数据库中的对象,如:存储过程,函数,触发器,集合函数已及复杂的类型。看到这些你还能淡定吗?哈哈,不仅仅是这些。那些能被.NET支持的第三方扩展通过该技术统统都能应用在数据库编程上,如:正则表达式,.NET庞大的加密解密库,以及各种.NET集成的排序和搜索算法。

下面我就来一一介绍怎么使用该技术来解放我们的双手!

实现存储过程

[csharp] view plaincopyprint?

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.SqlServer.Server;
  6. using System.Data;
  7. using System.Data.SqlClient;
  8. using System.Data.SqlTypes;
  9. using System.Collections;
  10. public class SampleStoreProcedure
  11. {
  12. [SqlProcedure]
  13. public static void PrintStudentDetail()
  14. {
  15. SqlConnection conn = new SqlConnection("Context connection=true");
  16. conn.Open();
  17. SqlCommand cmd = new SqlCommand("select * from student", conn);
  18. SqlCommand cmd2 = new SqlCommand("insert into studentdetail values(@detail)");
  19. SqlDataReader reader;
  20. string tmpData=string.Empty;
  21. ArrayList tmpDataArray=new ArrayList();
  22. reader = cmd.ExecuteReader();
  23. while (reader.Read())
  24. {
  25. for (int i = 0; i < reader.FieldCount; i++)
  26. {
  27. tmpData += reader[i].ToString();
  28. }
  29. tmpDataArray.Add(tmpData);
  30. }
  31. reader.Close();
  32. cmd2.Connection = conn;
  33. foreach (string tmp in tmpDataArray)
  34. {
  35. cmd2.Parameters.Clear();
  36. cmd2.Parameters.AddWithValue("@detail", tmp);
  37. cmd2.ExecuteNonQuery();
  38. }
  39. conn.Close();
  40. //conn2.Close();
  41. }
  42. [SqlProcedure]
  43. public static void GetStudentDetail(int id)
  44. {
  45. SqlConnection conn = new SqlConnection("Context connection=true");
  46. SqlCommand cmd = new SqlCommand("select * from student where [email protected]", conn);
  47. SqlDataReader reader;
  48. cmd.Parameters.AddWithValue("@id", id);
  49. try
  50. {
  51. conn.Open();
  52. reader = cmd.ExecuteReader();
  53. SqlPipe pipe = SqlContext.Pipe;
  54. pipe.Send(reader);
  55. reader.Close();
  56. }
  57. catch
  58. {
  59. conn.Close();
  60. }
  61. finally
  62. {
  63. }
  64. }
  65. };

部署步骤

[sql] view plaincopyprint?

  1. 1.编译项目,获取生成的DLL文件。
  2. 2.在数据库中输入命令sp_configure [clr enabled],1 reconfigure --开启对程序集的信任权限。
  3. 3.输入命令:create assembly chapter34_UDT from ‘c:\chapter34_UDT.dll‘ 注册程序集
  4. 4.输入命令:
  5. <p>--注册存储过程
  6. create procedure PrintStudentDetail
  7. as
  8. external name chapter34_UDT.SampleStoreProcedure.PrintStudentDetail</p><p>--注册带参数的存储过程
  9. create procedure GetStudentDetail
  10. (
  11. @Id int
  12. )
  13. as
  14. external name chapter34_UDT.SampleStoreProcedure.GetStudentDetail</p>

执行结果

[sql] view plaincopyprint?

  1. exec PrintStudentDetail
  2. exec GetStudentDetail 1

存储过程PrintStudentDetail执行结果

存储过程GetStudentDetail执行的结果

实现函数

[csharp] view plaincopyprint?

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Data;
  6. using System.Data.SqlClient;
  7. using System.Data.SqlTypes;
  8. using Microsoft.SqlServer.Server;
  9. using System.Security;
  10. using System.Security.Cryptography;
  11. public class SampleFunction
  12. {
  13. public SampleFunction()
  14. {
  15. }
  16. [SqlFunction]
  17. public static SqlString Hash(SqlString data)
  18. {
  19. SHA1 sha1 = SHA1.Create();
  20. byte[] tmp = Encoding.ASCII.GetBytes(data.Value);
  21. string result= Convert.ToBase64String(sha1.ComputeHash(tmp));
  22. return new SqlString(result);
  23. }
  24. }

部署步骤

[sql] view plaincopyprint?

  1. 1.编译项目,获取生成的DLL文件。
  2. 2.在数据库中输入命令:
  3. sp_configure [clr enabled],1 reconfigure --开启对程序集的信任权限。
  4. 3.输入命令:
  5. create assembly chapter34_UDT from ‘c:\chapter34_UDT.dll‘ 注册程序集
  6. --如果上述步骤已经做了就忽略
  7. <p>4.输入命令:</p>
  8. --注册函数
  9. create function HashSomeThing(@data nvarchar) returns nvarchar
  10. as
  11. external name chapter34_UDT.SampleFunction.[Hash]

执行结果

[sql] view plaincopyprint?

  1. <p>输入调用命令:</p>select dbo.HashSomeThing(name) from Student

实现表值函数

[csharp] view plaincopyprint?

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Data;
  6. using System.Data.SqlClient;
  7. using System.Data.SqlTypes;
  8. using Microsoft.SqlServer.Server;
  9. using System.Text.RegularExpressions;
  10. using System.Xml.Linq;
  11. using System.Xml;
  12. using System.IO;
  13. using System.Collections;
  14. public class SampleTableValueFunction
  15. {
  16. ///
  17. /// 表值函数的主体,该函数需要结合“内容填充函数”才能发挥功能。这里的“内容填充函数”是通过
  18. /// 属性“FillRowMethodName”属性来指定的。属性“TableDefinition”用来定义返回表格的格式。
  19. ///
  20. [SqlFunction(TableDefinition = "tmp_value nvarchar(max)", FillRowMethodName = "FillRow")]
  21. public static IEnumerable PrintOneToTen()
  22. {
  23. IList<string> result2 = new List<string>();
  24. var matches = new string[]{
  25. "one",
  26. "two",
  27. "three",
  28. "four",
  29. "five",
  30. "six",
  31. "seven",
  32. "eight",
  33. "nine",
  34. "ten"
  35. };
  36. return matches.AsEnumerable();
  37. }
  38. public static void FillRow(object obj, out SqlString tmp)
  39. {
  40. tmp = new SqlString(obj.ToString());
  41. }
  42. }

部署步骤

[sql] view plaincopyprint?

  1. 1.编译项目,获取生成的DLL文件。
  2. 2.在数据库中输入命令:
  3. sp_configure [clr enabled],1 reconfigure --开启对程序集的信任权限。
  4. 3.输入命令:
  5. create assembly chapter34_UDT from ‘c:\chapter34_UDT.dll‘ 注册程序集
  6. --如果上述步骤已经做了就忽略
  7. 4.输入命令:
  8. create function SampleTableValueFunction() returns table(tmp_value nvarchar(max) null)
  9. as
  10. external name chapter34_UDT.SampleTableValueFunction.PrintOneToTen

执行结果

实现触发器

[csharp] view plaincopyprint?

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.SqlServer.Server;
  6. using System.Data;
  7. using System.Data.SqlClient;
  8. using System.Data.SqlTypes;
  9. public class SampleTrigger
  10. {
  11. public SampleTrigger()
  12. {
  13. }
  14. [SqlTrigger(Event = "For Insert,Update,Delete", Name = "PrintInfo", Target = "Student")]
  15. public static void PrintInfo()
  16. {
  17. SqlTriggerContext triggerContext = SqlContext.TriggerContext;
  18. SqlConnection conn = new SqlConnection("Context connection=true");
  19. SqlCommand cmd = new SqlCommand();
  20. cmd.Connection = conn;
  21. switch (triggerContext.TriggerAction)
  22. {
  23. case TriggerAction.Insert:
  24. cmd.CommandText = "insert into StudentDetail values(‘insert operation!‘)";
  25. break;
  26. case TriggerAction.Delete:
  27. cmd.CommandText = "insert into StudentDetail values(‘delete operation!‘)";
  28. break;
  29. case TriggerAction.Update:
  30. cmd.CommandText = "insert into StudentDetail values(‘update operation!‘)";
  31. break;
  32. default:
  33. break;
  34. }
  35. try
  36. {
  37. conn.Open();
  38. cmd.ExecuteNonQuery();
  39. }
  40. catch
  41. {
  42. }
  43. finally
  44. {
  45. conn.Close();
  46. }
  47. }
  48. [SqlTrigger(Name="InsertSomething",Target="chapter30.dbo.Student",Event="FOR INSERT")]
  49. public static void InsertSomething()
  50. {
  51. SqlTriggerContext triggerContext = SqlContext.TriggerContext;
  52. if (triggerContext.TriggerAction == TriggerAction.Insert)
  53. {
  54. var conn = new SqlConnection("Context connection=true");
  55. var cmd = new SqlCommand();
  56. cmd.Connection = conn;
  57. cmd.CommandText = "Insert into StudentDetail values(‘insert event‘)";
  58. conn.Open();
  59. cmd.ExecuteNonQuery();
  60. conn.Close();
  61. }
  62. }
  63. }

部署步骤

[sql] view plaincopyprint?

  1. 1.编译项目,获取生成的DLL文件。
  2. 2.在数据库中输入命令:
  3. sp_configure [clr enabled],1 reconfigure --开启对程序集的信任权限。
  4. 3.输入命令:
  5. create assembly chapter34_UDT from ‘c:\chapter34_UDT.dll‘ 注册程序集
  6. --如果上述步骤已经做了就忽略
  7. 4.输入命令:
  8. --注册触发器
  9. create trigger PrintSomething on Student
  10. for insert,update,delete
  11. as
  12. external name  chapter34_UDT.SampleTrigger.PrintInfo

执行结果

[sql] view plaincopyprint?

  1. 输入命令:
  2. insert into Student values(12345,‘tmp‘,‘11‘,‘11‘)
  3. update Student set Name=‘new‘+Name where Id=12345
  4. delete from Student where Id=12345
  5. select * from StudentDetail

实现聚合函数

[csharp] view plaincopyprint?

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.SqlServer.Server;
  6. using System.Data;
  7. using System.Data.SqlClient;
  8. using System.Data.SqlTypes;
  9. [Serializable]
  10. [SqlUserDefinedAggregate(Format.Native)]
  11. public struct SampleSum
  12. {
  13. private int sum;
  14. public void Init()
  15. {
  16. sum = 0;
  17. }
  18. public void Accumulate(SqlInt32 Value)
  19. {
  20. sum += Value.Value;
  21. }
  22. public void Merge(SampleSum Group)
  23. {
  24. sum += Group.sum;
  25. }
  26. public SqlInt32 Terminate()
  27. {
  28. return new SqlInt32(sum);
  29. }
  30. }

部署步骤

[sql] view plaincopyprint?

  1. 1.编译项目,获取生成的DLL文件。
  2. 2.在数据库中输入命令:
  3. sp_configure [clr enabled],1 reconfigure --开启对程序集的信任权限。
  4. 3.输入命令:
  5. create assembly chapter34_UDT from ‘c:\chapter34_UDT.dll‘ 注册程序集
  6. --如果上述步骤已经做了就忽略
  7. 4.输入命令:
  8. --注册聚合函数
  9. create aggregate SampleSum(@value int) returns int
  10. external name [chapter34_UDT].SampleSum

执行结果

[sql] view plaincopyprint?

  1. 输入命令:
  2. select dbo.SampleSum(TAggregate) from TAggregate
  3. select Sum(TAggregate) from TAggregate

实现类型

[csharp] view plaincopyprint?

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Microsoft.SqlServer.Server;
  6. using System.Data.SqlTypes;
  7. using System.Data;
  8. using System.Data.SqlClient;
  9. [Serializable]
  10. [Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native)]
  11. public struct Facade : INullable
  12. {
  13. public bool isNull;
  14. int hairColor;
  15. int tall;
  16. int skin;
  17. int country;
  18. public Facade(int hairColor, int tall, int skin, int country)
  19. {
  20. isNull = false;
  21. this.hairColor = hairColor;
  22. this.tall = tall;
  23. this.skin = skin;
  24. this.country = country;
  25. }
  26. public static Facade Null
  27. {
  28. get
  29. {
  30. return new Facade { isNull = true };
  31. }
  32. }
  33. public override string ToString()
  34. {
  35. StringBuilder sb = new StringBuilder();
  36. sb.AppendFormat("{0};", hairColor);
  37. sb.AppendFormat("{0};", tall);
  38. sb.AppendFormat("{0};", skin);
  39. sb.AppendFormat("{0}", country);
  40. return sb.ToString();
  41. }
  42. public static Facade Parse(SqlString data)
  43. {
  44. if (data.IsNull)
  45. {
  46. return new Facade { isNull = true };
  47. }
  48. Facade result;
  49. string[] tmpData = data.Value.Split(‘;‘);
  50. result = new Facade(int.Parse(tmpData[0]), int.Parse(tmpData[1]), int.Parse(tmpData[2]), int.Parse(tmpData[3]));
  51. return result;
  52. }
  53. public bool IsNull
  54. {
  55. get { return isNull; }
  56. }
  57. }

部署步骤

[sql] view plaincopyprint?

  1. 1.编译项目,获取生成的DLL文件。
  2. 2.在数据库中输入命令:
  3. sp_configure [clr enabled],1 reconfigure --开启对程序集的信任权限。
  4. 3.输入命令:
  5. create assembly chapter34_UDT from ‘c:\chapter34_UDT.dll‘ 注册程序集
  6. --如果上述步骤已经做了就忽略
  7. 4.输入命令:
  8. create type Facade external name
  9. [chapter34_UDT].Facade

执行结果

小结

CLR Sql Server 的推出大大的提高了Sql Server的脚本编程效率问题,并且这项技术给了我们很大的相信空间。现在我们就来用有限的手段实现无限的可能吧!

reference from : http://blog.csdn.net/ghostbear/article/details/7333189

时间: 2024-11-08 22:34:09

提高你的数据库编程效率:Microsoft CLR Via Sql Server的相关文章

(在数据库中调用webservices。)SQL Server 阻止了对组件 &#39;Ole Automation Procedures&#39; 的 过程&#39;sys.sp_OACreate&#39; 的访问

--开启 Ole Automation Procedures sp_configure 'show advanced options', 1; GO RECONFIGURE; GO sp_configure 'Ole Automation Procedures', 1; GO RECONFIGURE; GO EXEC sp_configure 'Ole Automation Procedures'; GO --关闭 Ole Automation Procedures sp_configure '

mysql数据库数据能不能导入到sql server中

当然可以了. 一.为 MySQL安装ODBC驱动 下载MySQL ODBC Connector,下载:http://dev.mysql.com/downloads/connector 从控制面板-管理工具,打开你的 数据源(ODBC),选 系统DNS ,点添加.   在 创建新数据源对话框中,选择MySQL ODBC 5.1 Driver ,点完成. 完成后会出现MySQL 链接对话框,添加你的 MySQL 数据库账号信息,并确认"root"账号是否有全部的权限,如果你安装MySQL

Excel VBA 连接各种数据库(三) VBA连接SQL Server数据库

本文主要涉及: VBA中的SQL Server环境配置 VBA连接SQL Server数据库 VBA读写SQL Server数据 如何安装SQL Client 系统环境: Windows 7 64bit Excel 2016 64bit 1. VBA连接SQL Server前的环境配置 在Excel这边,需要先在VBE中启动数据库连接支持.按下Alt+F11打开VBE,在菜单栏选择“工具”-“引用”,在弹出的引用窗口中,找到"Microsoft ActiveX Data Objects 6.1

轻松提高千万级数据库查询效率

优化数据库设计 1.数据字段类型使用varchar/nvarchar 替换 char/nchar,变长字段存储空间小,节省存储空间.在查询的时候小的空间字段搜索效率更高. 2.查询的时候避免全表扫描,可以在where和order by 的字段上建立索引. 3.where 查询子句中不对null值做判断,会导致检索引擎放弃使用索引而使用全表扫描,如:select id,name from user where age is null 可以设置age 的默认值为0,保证没有null值,修改后的sql

App_Data 目录中的数据库位置指定了一个本地 SQL Server

<configuration> <system.web> <compilation debug="true" targetFramework="4.5.2"/> <httpRuntime targetFramework="4.5.2"/> <membership defaultProvider="DefaultConnectionProvider"> <prov

中文编程不是解决中国程序员编程效率的银弹

按照<人月神话>的定义,软件工程中的银弹指的是软件生产效率有指数级提高的方法. 像我题目中所说的那样,我认为,中文编程并不能使中国中国程序员的编程效率有指数级的提高 首先,从一个大的逻辑角度来看.中文编程对中国程序员的意义和英文编程对英语国家程序员的意义是一样的,无非就是使用自己的母语进行程序编写.那么在英语国家的程序员使用英语(现在的高级编程语言接近英语的表达习惯)编程的效率还没有显著地高于我们非英语国家的程序员,那又为什么说中文程序员使用中文编程后编程效率就会显著的提高呢?而且在实际情况中

“中文编程”是否所谓解决中国程序员编程效率的“银弹”的讨论

所谓“银弹”,最初是指指由纯银质或镀银的子弹.在欧洲民间传说及19世纪以来哥特小说风潮的影响下,银色子弹往往被描绘成具有驱魔功效的武器,是针对狼人等超自然怪物的特效武器.而后延伸为致命武器的代名词,被比喻为具有极端有效性的解决方法. 那么“中文编程”是否能成为提高中国程序员编程效率的“银弹”呢?个人认为,这是不现实的. 首先编程是一门技术活,而技术活可以做到熟能生巧.其实现在所普及使用的编程语言都是英文,但是其在程序中的语法跟我们平常使用的语法完全不一样, 可以说是一种颠覆.即使对英文不是很了解

QT开发(四十六)——QT数据库编程基础

QT开发(四十六)--QT数据库编程基础 一.Qt SQL模块简介 1.Qt SQL模块简介 QT通过Qt SQL模块提供了对SQL数据库的支持,Qt SQL模块中的API分为三层:驱动层.SQL接口层.用户接口层. 如果要使用Qt SQL模块中的类,需要在工程文件(.pro文件)中添加QT += sql代码. 2.驱动层 驱动层为具体的数据库和SQL接口层之间提供了底层的桥梁,主要类包括Qt SQL模块中的QSqlDriver.QSqlDriverCreator.QSqlDriverCreat

数据库编程--&gt;SqlServer示例

准备工作 1:微软官网下载jdbc包.解压得到如下文件: 注:我下的是6.0版本 其中jre8和jre7中包含了sqljdbc42.jar包和sqljdbc41.jar包(会用到) 准备工作 2 :配置端口协议 找到  运行 开始 → 所有程序 → Microsoft SQL Server 2016 → 配置工具 →SQL Server配置管理器,如下图所示: 配置如下图: . 激动人心的时候到了: 1: 打开数据库SqlServer2016,创建一个数据库demo 2:打开eclipse新建一