在SQL Server2005中使用 .NET程序集

系统 1639 0
<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>昨天完成了一个最简单的在数据库中创建标量值函数,今天主要完成表值函数,存储过程和用户定义类型在和.NET结合下的使用方法.
1,表值函数
所谓表值函数就是说这个函数返回的结果是一个Table,而不是单个的值.
在.NET 中创建这样的函数,返回的结果是一个IEnumerable接口.这个接口非常灵活,所有.NET数组集合等都是实现了该接口的.下面我们举一个简单的例子来说明.
在VS2005中创建一个类Student,这个就是我们要返回的表的内容,类下面有属性int Age,string sName,DateTime Birthday,int SID;
然后在另外一个类UserFunction中写入如下代码:
[SqlFunction(FillRowMethodName = " FillRow " )]
public static IEnumerableGetStudent()
... {
Hashtablehash
= new Hashtable();
for ( int i = 0 ;i < 3 ;i ++ )
... {
Students
= new Student();
s.SID
= i;
...
hash.Add(i,s);
}

return hash.Values;
}

public static void FillRow( object obj, ref SqlInt32id, ref SqlStringname, ref SqlDateTimebir, ref SqlInt32age)
... {
Students
= (obj as Student);
id
= s.SID;
name
= s.sName;
bir
= s.Birthday;
age
= s.Age;

}

第一个属性中指定FillRowMethodName就是为了将返回的IEnumerable接口中的数据进行转换,将数据库无法认识的集合转换为数据库人生的字段.下面的函数FillRow就是具体转换的过程.
这样写完成以后,在数据库那边添加好这个程序集,然后就可以创建表值函数了:
create function BuildTable()
returns table (SID int , [ sName ] nvarchar ( 100 ),Birthday datetime ,Age int )
as
externalnameSQLFunction.
[ SQLFunction.UserFunction ] .GetStudent

这儿就不用太多的解释了,就是将名为SQLFunction的程序集中的[名字空间.类].方法添加到BuildTable函数中.
这儿需要说明一下就是数据库中的类型和.NET中的类型的对应问题.int,datetime就不说了,主要是.NET中的string,在数据库中没有string类型,在FillRow中指出了类型SqlString,而这个类型的对应是nchar,nvarchar.这儿不能对应char,varchar,我不知道为什么必须是对应nchar的.所以上面我们写的是[sName] nvarchar(100).
大功告成,测试一下,输入语句select * from BuildTable()看看返回你的表没有.
2.存储过程
CLR存储过程和CLR函数非常相似,不过有几点更高的能力:
CLR存储过程可以有一个返回值,也可以写输出参数,可以返回消息给客户程序,可以调用DDL和DML语句.
.NET创建存储过程要编写为静态函数,然后加上SqlProcedure属性.
比如我们写一个简单的存储过程
[SqlProcedure]
public static int Add( int a, int b)
... {
return a + b;
}

然后在数据库中写入:
create procedure Add2Num
@a int , @b int
as
externalnameSQLFunction.
[ SQLFunction.UserFunction ] . [ Add ]

整个代码我就不用解释了,和前面创建函数一样.
我们运行看看结果:
declare @a int
exec @a = Add2Num 10 , 12
print @a

3.用户定义类型(UDT)
要创建UDT类必须符合"UDT规范",.NET中的约束如下:
他们必须带SqlUserDefinedType 属性
必须带有Serializable属性
必须实现INullable接口
必须博阿訇公开和静态的Parse和ToString方法以用于转换数据类型字符串或逆向转换.
必须暴露数据元素为公开字段或公开属性.
好,那我们就创建一个简单的UDT复数类如下:
[Serializable]
[SqlUserDefinedType(Format.Native)]
[StructLayout(LayoutKind.Sequential)]
public class Complex:INullable
... {
bool isNull = false ;
double real,imag;
public bool IsNull
... {
get ... { return isNull;}
}

public double Real
... {
get ... { return real;}
set ... {real = value;}
}

public double Imag
... {
get ... { return imag;}
set ... {imag = value;}
}

public override string ToString()
... {
if (isNull)
... {
return " NULL " ;
}

else
... {
return real + " , " + imag;
}

}

public static ComplexParse(SqlStrings)
... {
if (s == null || s.IsNull)
... {
return null ;
}

else
... {
Complexc
= new Complex();
string str = Convert.ToString(s);
string []st = str.Split( ' , ' );
c.real
= Convert.ToDouble(st[ 0 ]);
c.imag
= Convert.ToDouble(st[ 1 ]);
return c;
}

}

}
编译好,在数据库中添加程序集后,我们运行如下代码:
create typeComplex
externalnameSQLFunction.
[ SQLFunction.Complex ]

这样我们就创建好了用户定义类型Complex.
数据库事例代码中有相关内容,参见:
\Program Files\Microsoft SQL Server\90\Samples\Engine\Programmability\CLR\UserDefinedDataType

在SQL Server2005中使用 .NET程序集


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论