程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> SQL Server 2005中的CLR總結和自定義類型(UDT)

SQL Server 2005中的CLR總結和自定義類型(UDT)

編輯:關於SqlServer
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

我們看一下執行的結果

 

和我們想的是一樣的,呵呵用法 基本上就是這樣,如果要使用更高級點的功能大家自己動手吧;

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved