e股脑电脑教程网
  • 首 页
  • 操作系统
  • 应用软件
  • 下载工具
  • 影音视频
  • 办公软件
  • 媒体制作
  • 网站建设
  • 平面设计
  • 数据库
  • 程序开发
  • 视频教程
编辑推荐: | 文章搜索:
您现在的位置: e股脑 >> 数据库 >> Mssql教程 >> 使用 SQL Server 2005中的 CLR 集成 >> 教程正文
 
教程搜索
 
 
相关教程
  • 你知道MySQL10条鲜为人知的技巧吗?
  • 你应该知道的10个MySQL客户启动选项
  • 用特殊的MySQL运算符获得更多数据比较
  • MySQL数据库中与 NULL值有关的几个问题
  • 教你快速了解公共MySQL的数据库服务器
  • MySQL 5.0在windows上的安装详细介绍
  • MySQL查询的性能优化
  • Linux操作系统中如何安装MySQL数据库
  • 23道安全门加铸MySQL数据库
  • MySQL 5.0 数据库新特性的存储过程
  • 从Windows命令行启动MySQL
  • 连接MySQL数据库失败频繁的原因
  • 加速动态网站 MySQL索引分析和优化
  • 轻松掌握如何保护MySQL中的重要数据
  • 快速掌握MySQL数据库中Show命令的用法
  • MySQL数据库的安全配置实用技巧
 
 

图文教程


  • Windows抢了谁的饭碗 非主流操作系统To

  • 地球还是火星 平常心看“非主流”

  • 综合运用Office 2007批量制作奖状

  • 没有系统盘如何才能修复受损系统?

  • 巧妙运用Excel中边界的附加功能!
 
 
赞 助 商
 
 
使用 SQL Server 2005中的 CLR 集成
  • 来源:e股脑
  • 点击次数:
  • 更新时间:2007-8-9
_iRow == m_strlist.Length) return false; return true; } //Column getters //Implement Get<SqlTypeName> for each column produced by //the TVF; in this case just one. public SqlChars GetSqlChars(int i) { if (i == 0) return new SqlChars(m_strlist[m_iRow]); else throw new NotImplementedException(); } //Methods not used by SqlServer omitted; //Actual implementation should provide an empty //implementation. ... } // public class MySqlReader } // class StringFunctions;


假定 GetStrings 方法注册为具有相同名称的 TVF。下面是存储过程的代码片段,它使用此 TVF 从定单中提取表形式的行项目。

CREATE PROCEDURE Insert_Order @cust_id int, @lineitems nvarchar(8000) AS BEGIN ... INSERT LineItems SELECT * FROM dbo.GetStrings(@lineitems) ... END

对数据进行自定义聚合

在许多情况下,您可能需要对数据进行聚合。这包括执行统计计算(如 avg、stddev 等等)。如果所需的聚合函数不是作为内置聚合函数直接支持的,SQL Server 2005 中有三种方法可以进行这样的自定义聚合:

•

将聚合编写为用户定义的聚合 (UDA)。

•

使用 CLR 存储过程编写聚合。

•

使用服务器端光标。

让我们在一个称为 PRODUCT(int) 的简单聚合函数的上下文中检查这三种替代方法,该聚合函数计算一组给定值的乘积。

作为用户定义的聚合函数实现的 PRODUCT

下面是此函数的主干 C# 代码示例。所有的积累逻辑都在 Accumulate 函数中(为了简单起见,其他函数显示为 {...})。

[SqlUserDefinedAggregate(Format.Native)] public struct Product { public void Accumulate(SqlInt32 Value) { m_value *= Value; } public void Init() {...} public void Merge(Product Group) {...} public SqlInt32 Terminate() {...} }

在定义类型、创建程序集和注册到 SQL Server 之后,就可以通过以下方式使用 T-SQL中的聚合函数:

SELECT dbo.Product(intcol) FROM tbl GROUP BY col

作为使用 SqlDataReader 的托管存储过程实现的 PRODUCT

可以创建存储过程来执行查询和循环访问结果,以执行计算。这种循环访问是通过使用 SqlDataReader 类完成的。

[SqlProcedure] public static void Product(out SqlInt32 value) { SqlCommand cmd = SqlContext.GetCommand(); cmd.CommandText = "select intcolumn from tbl"; SqlDataReader r = cmd.ExecuteReader(); bool first = true; using (r) { while (r.Read()) //skip to the next row { if (first) { value = r.GetSqlInt32(0); first = false; } else { value *= r.GetSqlInt32(0); } } } }


可以使用 EXEC 语句来调用这一过程

EXEC Product @p OUTPUT

作为使用光标的 T-SQL 存储过程实现的 PRODUCT

可以创建 T-SQL 存储过程来执行查询和通过使用 T-SQL 光标循环访问结果,以执行计算。

create procedure TSQL_ProductProc (@product int output) as begin declare @sales int declare c insensitive cursor for select intcolumn from tbl open c fetch next from c into @sales if @@FETCH_STATUS = 0 set @product = @sales while @@FETCH_STATUS = 0 begin fetch next from c into @sales set @product = @product * @sales end close c deallocate c end

决定是使用 UDA 还是使用其他某种解决方案来产生结果取决于几个因素:

•

可组合性要求。UDA 实际上是独立的对象,可以用于任何 T-SQL 查询,通常用在可以使用系统聚合函数的任何相同的地方。不需要假定它所操作的查询。例如,可以将其包括在视图定义(不过,索引视图中不支持 UDA)和标量子查询中。

•

聚合算法细节。在 Order By 子句(如果查询中有)之前可能对 UDA 进行求值,因此不能保证传递给聚合函数的值的顺序。如果聚合算法需要按照特定的顺序使用值,则不能使用 UDA。同样地,UDA 从整组中使用值并且返回单一值。如果需要必须为组中的每个值返回值的聚合函数,则应该考虑使用存储过程或流表值函数来编写您的函数。详细信息请参见本文中的“产生结果”一节。

•

对副作用和数据访问的需要。不允许 UDA 进行数据访问或有副作用。如果您的函数需要保留大量的数据作为聚合的中间状态,或因为其他某种原因需要进行数据访问,则必须使用过程。

使用 UDA 的第一种方法在这三个选择中可能提供最好的性能。通常,如果没有碰到上面所列的限制,就应该尝试将聚合函数编写为 UDA。如果无法使用 UDA 方法,则使用 SqlReader 的托管代码方法可能比 T-SQL 光标方法执行得更好。

可以用 UDA 方法编写的有用的聚合的示例还包括:找到每组中第 N 大(或第 N 小)值,找到每组中前 N 个最大值的平均值或总和,等等。

用户定义的类型 (UDT)

现在,我们来讲 SQL Server 2005 中功能更强大但是经常被错误理解的一个功能。使用用户定义的类型 (UDT),可以扩展数据库的标量类型系统(不仅仅为系统类型定义您自己的别名,这在 SQL Server 以前的版本中一直可用)。定义 UDT 就像用托管代码编写类,创建程序集,然后使用“create type”语句在 SQL Server 中注册该类型一样简单。下面是实现 UDT 的主干代码:

[SqlUserDefinedTypeAttribute(Format.Native)] public struct SimpleUdt: INullable { public override string ToString() {...} public bool IsNull { get; } public static SimpleUdt Null { get; } public static SimpleUdt Parse(SqlString s) {...} ... } create type simpleudt from [myassembly].[SimpleUdt] create table t (mycolumn simpleudt)


何时创建 UDT

SQL Server 2005 中的 UDT 不是对象相关的扩展性机制。它们是扩展数据库的标量类型系统的一种方法。标量类型系统包括 SQLServer 附带的列类型(如 int、nvarchar 和 uniqueidentifier 等类型)。例如,使用 UDT,可以定义您自己的、用于列定义的类型。如果您的类型确实是一个适合建模为列的原子值,请创建 UDT。

如果需要定义您自己的标量类型,请使用 UDT。这种类型的示例情况包括各种日历中的自定义日期/时间数据类型和货币数据类型。使用 UDT,可以创建单个对象来公开类型上可用的所有行为,并且封装或隐藏该类型所存储的基础数据。需要访问数据的每个人都必须使用 UDT 的编程接口。如果能够利用 .NET Framework 中现有的功能(如国际化或日历功能),这实际上又是考虑将类型实现为 UDT 的一个很好的理由。

何时不创建 UDT

不要使用 UDT 来对复杂的业务对象(如雇员、联系人或客户)进行建模。您将会陷入 UDT 的所有列限制(如,8KB 大小限制、索引限制)和在更新 UDT 值时更新整个值的不利方面。对于复杂类型,UDT 不是合适的数据建模抽象;因此对于这种情况,最好使用中间层对象相关映射技术。

设计 UDT 时需要考虑的因素

因为它们是列形式的,所以可以定义整个 UDT 值的索引,并且创建参考完整性约束(如 UDT 列的唯一性)。还可以在比较和排序方案中使用 UDT。

比较 UDT 值是通

上一页  1 2 3 4 5 6 7 8 下一页
  • 上一篇教程: 在 SQL Server 2005 Beta 2 中编辑 Transact-SQL 代码
  • 下一篇教程: SQL Server 2005 数据转换服务的常见设计问题
  •  

    关于本站 | 广告联系 | 版权声明 | 使用帮助

    Copyright © 2004-2008 www.egunao.com All rights reserved.