CLR的最後一節,之前我寫過關於自定義函數和XP的小例子,中間有朋友說不太合理,我也承認,呵呵 ,因為我當時也沒有想起來用什麼來說明它們的作用,不過功能相信大家都 明白了,有朋友問自定義類型是怎麼回事,在這裡我做個簡單的介紹吧;
1.用戶定義的類型 (簡稱UDT)
在早期的2000版本中也存在著這樣的功能,使用用戶定義的類型 (UDT),可以擴展數據庫的標量類型系統(不僅僅為系統類型定義您自己的別名,這在 SQL Server 以前的版本中一直可用)這是官方給下的定義,呵呵,說到這裡不知道 大家有沒有在數據裡使用過UDT,如果有的話好最好,如果沒有的話建議大家使用一下,可以根據向導來創建,在Sql2005裡的可編輯性---類型--用戶自定義類型,右擊就可以看到創建功能了,定義 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)
這些格式 相信只要使用Sql創建過UDT的朋友都會很熟悉的;
在創建之前我們應該先了解另外的一個概念(標量類型系統)標量類型系統包括 SQLServer 附帶的列類型(如 int、nvarchar 和 uniqueidentifIEr 等類型)。例如,使用 UDT,可以定義您自己的、用於列定義的類型。如果您的類型確實是一個適合建模為列的原子值,這個時候就可以使用UDT了;
UDT不是在任何時候都可以使用的,請要使用 UDT 來對復雜的業務對象(如雇員、聯系人或客戶)進行建模。您將會陷入 UDT 的所有列限制(如,8KB 大小限制、索引限制)和在更新 UDT 值時更新整個值的不利方面。對於復雜類型,UDT 不是合適的數據建模抽象;因此對於這種情況,最好使用中間層對象相關映射技術。這點我測試過,如果你你部署過的類型需要更新的話,則數據庫就不能有正在使用這個類型的表,如果有的話會提示更新不成功的;要把所有使用它的地方都修改過來才能部署,所以很不方便,部署完了,還要再修改為這個UPT才能生效;所以經常改動的類型或是增長的類型就不要使用UDT了;
UDT 上的每個操作(除了比較)都要求 UDT 的值反序列化,接著進行方法調用。這種模式有與之相關的固定開銷。如果要將類型建模為 UDT(相對於表中的列),則在訪問類型屬性(相對於表中的列)時應該考慮這種差別。如果類型上的行為非常復雜,則應該考慮使用 UDT。如果類型沒有任何與之相關的行為,則應該考慮將數據存儲為表中的列。
下面我以一個例子的形式來說明它的功能吧, 也許我的例子不是很合適,但是說明功能應該是沒有問題的,我們來定義一個這樣的類型,如果你輸入的值是數字而為1,否則為0,這樣一個UDT,下面我們看一下過程 吧;
我們要可以打開之前的項目,單擊項目添加新建項
我們的自定義類型名稱 是INullable,單擊添加,我們看一下生成的代碼如下
這是Ms一個Hello的程序,我們只要稍加改動就可以實現 我們的功能 ,我們先得定義一個方法來實現 驗證是否為數字 的,我選擇正則表達式;
代碼
using System;
using System.Data;
using System.Data.SqlClIEnt;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native)]
public struct isNumber : INullable
{
public override string ToString()
{
// 用您的代碼替換下列代碼
return "";
}
public bool IsNull
{
get
{
// 在此處放置代碼
return m_Null;
}
}
public static isNumber Null
{
get
{
isNumber h = new isNumber();
h.m_Null = true;
return h;
}
}
public static isNumber Parse(SqlString s)
{
if (s.IsNull)
return Null;
isNumber u = new isNumber();
// 在此處放置代碼
return u;
}
// 這是占位符方法
public string Method1()
{
//在此處插入方法代碼
return "Hello";
}
// 這是占位符靜態方法
public static SqlString Method2()
{
//在此處插入方法代碼
return new SqlString("Hello");
}
// 這是占位符字段成員
public int var1;
// 私有成員
private bool m_Null;
}
代碼
/// <summary>
/// 是否數字字符串
/// </summary>
/// <param name="inputData">輸入字符串</param>
/// <returns></returns>
public static bool IsNumber(string inputData)
{
Regex RegNumber = new Regex("^[0-9]+$");
Match m = RegNumber.Match(inputData);
return m.Success;
}
大家也可以采用其它的方法,我來看要怎麼實現 ,我們先要在返回值的函數裡實現,返回類型,我們可以看到上面的類裡的 public override string ToString()
方法返回的是一個NUll值
我們讓它返回為變量
// 這是占位符字段成員
public int var1;
的值,這時我們還要修改一個返回前的方法
修改後的方法如下
代碼
public static isNumber Parse(SqlString s)
{
if (s.IsNull)
return Null;
isNumber u = new isNumber();
// 返回int類型在這裡
if (IsNumber(s.ToString().Trim()))
{
u.var1 = 1;
}
else
{
u.var1 = 0;
}
// 在此處放置代碼
return u;
}
好了代碼就這些下面是所有代碼附上
代碼 SQL Server 2005中的CLR(1) ),可以在Sql2005 裡看到
using System;
using System.Data;
using System.Data.SqlClIEnt;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text.RegularExpressions;
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native)]
public struct isNumber : INullable
{
public override string ToString()
{
// 用您的代碼替換下列代碼
return var1.ToString();
}
public bool IsNull
{
get
{
// 在此處放置代碼
return m_Null;
}
}
public static isNumber Null
{
get
{
isNumber h = new isNumber();
h.m_Null = true;
return h;
}
}
public static isNumber Parse(SqlString s)
{
if (s.IsNull)
return Null;
isNumber u = new isNumber();
// 返回int類型在這裡
if (IsNumber(s.ToString().Trim()))
{
u.var1 = 1;
}
else
{
u.var1 = 0;
}
// 在此處放置代碼
return u;
}
/// <summary>
/// 是否數字字符串
/// </summary>
/// <param name="inputData">輸入字符串</param>
/// <returns></returns>
public static bool IsNumber(string inputData)
{
Regex RegNumber = new Regex("^[0-9]+$");
Match m = RegNumber.Match(inputData);
return m.Success;
}
// 這是占位符方法
public string Method1()
{
//在此處插入方法代碼
return "Hello";
}
// 這是占位符靜態方法
public static SqlString Method2()
{
//在此處插入方法代碼
return new SqlString("Hello");
}
// 這是占位符字段成員
public int var1;
// 私有成員
private bool m_Null;
}
下一步我們部署一下就行了,方法請參考(
我們可以修改這個表,這個時候我們就能看到自己的數據類型了,
效果如下圖
選擇我們的類型保存就可以了
下面我在表裡寫一些數據大家看一下
按我們的方法列type3就是UDT,我們要吧看的出來如果正常的話,前兩行應該是0,而第三行是1,第四行和第五行應該是0,最後一行是1
我們看一下執行的結果
和我們想的是一樣的,呵呵用法 基本上就是這樣,如果要使用更高級點的功能大家自己動手吧;