用户自定义类型是SQL Server 2005的新特性。和前几篇文章介绍的SQLCLR相比,UDT相对有此复杂。UDT也有许多限制和必须遵守UDT规范。UDT的二进制不能超过8000个字节,必须包含一个null值表示,因为SQLServer的数据类型是允许null值的。
UDT可以是结构或类。如果是类的话需加[StructLayout(LayoutKind.Sequential)]
标签(属性),这是保证序列化时不改变属性的次序。
现在看一段代码

using System;
using System.IO;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.UserDefined, MaxByteSize 
= 1024)]
public struct Person : INullable, IBinarySerialize
{
    
public override string ToString()
    
{
        
// 用您的代码替换下列代码
        return FormatU();
    }


    
public bool IsNull
    
{
        
get
        
{
            
// 在此处放置代码
            return m_Null;
        }

    }


    
public static Person Null
    
{
        
get
        
{
            Person h 
= new Person();
            h.m_Null 
= true;
            
return h;
        }

    }


    
public static Person Parse(SqlString s)
    
{
        
if (s.IsNull)
            
return Null;

        Person u 
= new Person();
        
string value = s.Value;
        
if (value == "null"return Null;

        
string[] parts = value.Split(',');
        u.name 
= parts[0];
        u.age 
= ParseAge(parts[1]);
        u.sex 
= parts[2];
        
return u;
    }


    
// 这是占位符方法
    public string FormatU()
    
{
        
//在此处插入方法代码
        return string.Format("名称:{0},年龄:{1},性别:{2}", name, age, sex);
    }


    
// 这是占位符静态方法
    public static int ParseAge(string str)
    
{
        
//在此处插入方法代码
        return int.Parse(str.Substring(0, str.LastIndexOf("")));
    }


    
// 这是占位符字段成员
    private int age;
    
public int Age
    
{
        
get return age; }
        
set { age = value; }
    }


    
private string name;
    
public string Name
    
{
        
get return name; }
        
set { name = value; }
    }


    
private string sex;
    
public string Sex
    
{
        
get return sex; }
        
set { sex = value; }
    }


    
// 私有成员
    private bool m_Null;
    
public byte[] b;

    
public void Read(BinaryReader r)
    
{
        name 
= r.ReadString();
        sex 
= r.ReadString();
        age 
= r.ReadInt32();
        m_Null 
= r.ReadBoolean();
    }

    
public void Write(BinaryWriter w)
    
{
        w.Write(name);
        w.Write(sex);
        w.Write(age);
        w.Write(m_Null);
    }

}




部署后在SQL Server 2005中执行下面的语句
create table UdtTest (Id int not null, p Person not null)
insert into UdtTest values(1'David,24岁,男')
select id, convert(nvarchar(25),p) from UdtTest
drop table UdtTest

结果如下

想看清楚SQLCLR在对UDT处理机制可以将项目附加到SQL Server 2005进程,在相应的方法设置断点。
 
附:我在写随笔查阅资料时,无意中发现的用VB.NET讲解SQLCLR的PDF文档,相信对用VB.NET的兄弟会有些帮助/Files/DavidFan/HOL067.rar