SQL Server 2005中,支持用.net 写一个类型。并且可以在表中应用。这就是UDT(用户定义类型).
下面简单讲下UDT的创建:
1。VS中建一个项目。类库吧!本人用C#,所以就是C#类库项目了。
2。添加一个类。名子就跟你需要了。这次说明用一个Name类
3。添加要用的库。(是库吧,基础不深,叫什么就不知了);
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
至于新建类的时候有什么就记不清了。反正没的就加上去吧!要实现其他功能就自已加吧!
因为是UDT就是在SQL2005中序列化和反序列化。自动的。所以要加个
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.n,IsByteOrdered=true,MaxByteSize=8000)]
Format有三个的。分别是Native,UnKnown和UserDefined。
简单说明一下:
Native是简单的。由CLR控制。虽然支持大多数系统类型,但就是不支持string。所以这次就不用了。因为我就想试试string
UserDefined是由程序员完全控制的。如果选用UerDefined,IsByteOrdered就要为true,说明是用户自已控制摆放的顺序。MaxByteSize是大小。但有个最大值(8000),所以如果你的UDT可能超过这个数,你就要在转换的时候控制一下罗!用这种要实现IBinarySerialize接口,实现Read和Write方法。其实只是在排数据的时候交你控制吗,到读数据的时候又交给你自已读。实现的时候先实现Write再实现Read,那思路会清析点!
UnKnown 唉,我都不知道,因为没有研究!
哦,对了。还要实现个INullable接口。实现IsNull属性。这个属性告诉SQL这个对像是不是NULL的,是的就不工作了(反序列化)。帮助上大概就是这个意思。
下面是代码
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.n,IsByteOrdered=true,MaxByteSize=8000)]
public class Name : INullable,IBinarySerialize
...{
private bool is_Null;
![]()
private String lastname;
private String fristname;
public Name(int i)
...{
![]()
}
public Name()
...{
![]()
}
public bool IsNull
...{
get
...{
return (is_Null);
}
}
![]()
public static Name Null
...{
get
...{
Name name = new Name();
name.is_Null = true;
name.FristName = "";
name.lastname = "";
return name;
}
}
public override string ToString()
...{
if(this.IsNull)
return "NULL";
else...{
return (this.fristname + " " + this.lastname);
}
}
[SqlMethod(OnNullCall = false)]
public static Name Parse(SqlString s)
...{
if (s.IsNull)
return Null;
Name name = new Name();
string[] fl = s.Value.Split(" ".ToCharArray());
name.FristName = fl[0];
name.LastName = fl[1];
return name;
}
public String FristName
...{
get
...{
![]()
return this.fristname;
}
set
...{
this.fristname = value;
}
}
public String FullName
...{
get
...{
if (is_Null)
return Null.ToString() ;
return (this.lastname + " " + this.fristname);
}
}
public String LastName
...{
get
...{
return this.lastname;
}
set
...{
this.lastname = value;
![]()
}
![]()
}
IBinarySerialize 成员#region IBinarySerialize 成员
public void Read(System.IO.BinaryReader r)
...{
//char[] ch = r.ReadChars(20);
//this.fristname = new String(ch, 0, 10);
//this.lastname = new String(ch, 10, 10);
this.fristname = r.ReadString();
this.lastname = r.ReadString();
this.is_Null = r.ReadBoolean();
//throw new Exception("The method or operation is not implemented.");
}
public void Write(System.IO.BinaryWriter w)
...{
if (this.is_Null)
...{
w.Write("");
w.Write("");
w.Write(this.is_Null);
![]()
}
if (this.fristname.Length>10)
...{
throw new Exception("The method or operation is not implemented.");
}
w.Write(fristname);
w.Write(lastname);
//String fn = w.Write(this.fristname);
//String fl = this.lastname.PadRight(9, ' ');
//this.WriteString(w, fn);
//this.WriteString(w, fl);
w.Write(this.is_Null);
![]()
![]()
}
private void WriteString(System.IO.BinaryWriter w, String s)
...{
for (int i = 0; i < s.Length; i++)
...{
w.Write(s[i]);
}
}
#endregion
}
这么多,看到有点晕。
但重点有几个:
一,Parse方法。这个方法是转换。要如何转,如何换,自已写吧!
二,ToString().这个意思吗!就是字面的意思,不过,Select语句的时候不会调用,要显式调用。还要大小写符合哦!
三,IsNull这个是属性,是不是空的交给你告诉别人。是就true,否就false吧!
四,Write()和Read()就是给你在序列化的时候排数据,和读数据的。如三个成员,a1,a2,a3,写的时候就123的写进去,读的时候就123的读出来,不过,有一点。写的时候方法都重载了,所以不用理会是啥Type,但读的时候就要了,有ReadString,ReadInt,基本类型都有了,所以写Read()的时候要注意Write时的顺序,还要对应成员的类型。
后话:
还可以添加其它一些函数的,在Select的时候就“列名.函数名”罗,但这无实现了。
但如果你想加的话,有一个是要知道的。[SqlMethod(OnNullCall = false)]
在声明函数前加这一句,当然是一个函数加一个罗(你想加就加吧),这个告诉SQL对象引用为null的时候不调用。。
搞完这个还是有一些疑问的,MaxByteSize是不是可以动态改变呢。如果设了8000是不是SQL就留8000出来呢!
是MS藏招了还是啥,MSDN,上我就看不到解答。可能是我眼大睇过龙(广东话)。知情人事,望请告知

本文介绍如何使用.NET在SQL Server 2005中创建用户定义类型(UDT),包括类库项目的建立、类的定义及序列化接口的实现。



}
}
803

被折叠的 条评论
为什么被折叠?



