知识大全 使用 SQL Server 2005中的 CLR 集成(3)
Posted 函数
篇首语:惜时专心苦读是做学问的一个好方法。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 使用 SQL Server 2005中的 CLR 集成(3)相关的知识,希望对你有一定的参考价值。
使用 SQL Server 2005中的 CLR 集成(3) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
将标量分解为行 经常需要在应用程序中传送多值参数 例如 在定单处理系统中 可能需要编写存储过程来将定单插入到 Orders 表中 存储过程中的参数之一可能是定单中的行项目 在这种情况下 您会遇到 T SQL 限制 它不支持表值参数或缺乏集合数据类型(如数组) 解决这个问题的一种方法是 将集合编码为一个标量值(如 nvarchar 或 xml) 然后将其作为参数传递给存储过程 在存储过程内 可以使用表值函数来接受标量输入 并将其转换成一组行 然后将这些行插入到 LineItems 表中 虽然可以用 T SQL 编写表值函数 但是用 CLR 实现它有两个好处 System Text 命名空间中的字符串处理函数使得编写表值函数更加容易 CLR TVF 提供了更有效的流实现 这避免了将结果加载到工作表中 下面的代码片段显示了如何实现一个表值函数 它接受以 ; 分隔的一组值作为输入字符串 并且以一组行(字符串中的每个值一行)的形式返回该字符串 请注意 MySqlReader 类的构造函数实现了大部分工作 它使用 System String Split 方法将输入字符串分解为数组 // TVF that cracks a ; separated list of strings into a result // set of nvarchar( )column called Value public static ISqlReader GetStrings(SqlString str) return (ISqlReader)new MySqlReader(str); public class MySqlReader : ISqlReader private string[] m_strlist; private int m_iRow = ; // # rows read //The core methods //Initialize list public MySqlReader(SqlString str) //Split input string if not database NULL; //else m_strlist remains NULL if (!str IsNull) m_strlist = str Value Split( ; ); // SECTION: Metadata related: Provide # names types of // result columns public int FieldCount get return ; public SqlMetaData GetSqlMetaData(int FieldNo) if (FieldNo== ) return new SqlMetaData( Value SqlDbType NVarChar ); else throw new NotImplementedException(); // SECTION: Row navigation Read is called until it returns // false After each Read call Get<TypeName> for each // column is called public bool Read() //Return empty result set if input is DB NULL //and hence m_strlist is uninitialized if (m_strlist==null) return false; m_iRow++; if (m_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 == ) 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( ) AS BEGIN INSERT LineItems SELECT * FROM dbo GetStrings(@lineitems) END 对数据进行自定义聚合 在许多情况下 您可能需要对数据进行聚合 这包括执行统计计算(如 avg stddev 等等) 如果所需的聚合函数不是作为内置聚合函数直接支持的 SQL Server 中有三种方法可以进行这样的自定义聚合 将聚合编写为用户定义的聚合 (UDA) 使用 CLR 存储过程编写聚合 使用服务器端光标 让我们在一个称为 PRODUCT(int) 的简单聚合函数的上下文中检查这三种替代方法 该聚合函数计算一组给定值的乘积 作为用户定义的聚合函数实现的 PRODUCT 下面是此函数的主干 C# 代码示例 所有的积累逻辑都在 Accumulate 函数中(为了简单起见 其他函数显示为 ) [SqlUserDefinedAggregate(Format Native)] public struct Product public void Accumulate(SqlInt Value) m_value *= Value; public void Init() public void Merge(Product Group) public SqlInt Terminate() 在定义类型 创建程序集和注册到 SQL Server 之后 就可以通过以下方式使用 T SQL中的聚合函数 SELECT dbo Product(intcol) FROM tbl GROUP BY col 作为使用 SqlDataReader 的托管存储过程实现的 PRODUCT 可以创建存储过程来执行查询和循环访问结果 以执行计算 这种循环访问是通过使用 SqlDataReader 类完成的 [SqlProcedure] public static void Product(out SqlInt 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 GetSqlInt ( ); first = false; else value *= r GetSqlInt ( ); 可以使用 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 = set @product = @sales while @@FETCH_STATUS = 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 中功能更强大但是经常被错误理解的一个功能 使用用户定义的类型 (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 tab cha138/Article/program/SQLServer/201311/22103相关参考
知识大全 使用 SQL Server 2005中的 CLR 集成(1)
使用SQLServer2005中的CLR集成(1) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
SQL2005CLR函数扩展-关于山寨索引 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!本文只是一
SQL2005CLR函数扩展-繁简转换的实现代码 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
SQL2005CLR函数扩展-解析天气服务的实现 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
SQL2005CLR函数扩展-数据导出的实现详解 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
SQL2005CLR函数扩展-深入环比计算的详解 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!环比
解析SQL2005中如何使用CLR函数获取行号 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! S
知识大全 SQL Server 2005数据库中的Output子句
SQLServer2005数据库中的Output子句 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 如何用SQL SERVER 2005连接SQL SERVER 2008
如何用SQLSERVER2005连接SQLSERVER2008 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来
知识大全 SQL Server 2005和SQL Server 2000数据的相互导入
SQLServer2005和SQLServer2000数据的相互导入 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快