Aracılığıyla paylaş


Kullanıcı tanımlı türler kodlama

Kullanıcı tanımlı türü (udt) tanımı kodlama olup sizin udt bir sınıf ya da bir yapı olarak yanı sıra seçtiğiniz biçim ve seri hale getirme seçenekleri uygulama bağlı çeşitli özelliklerini uygulamak gerekir.

Bu bölümde yer alan örnek uygulama gösterilmektedir bir Pointudt olarak bir struct(veya StructureVisual Basic). Pointudt oluşur x ve y koordinatları olarak uygulanan özellik yordamlarını.

Aşağıdaki ad alanları bir udt tanımlarken gereklidir:

Imports System
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Imports System
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

Microsoft.SqlServer.ServerAd, sizin udt çeşitli öznitelikler için gereken nesneleri içerir ve System.Data.SqlTypesad alanını temsil eden sınıfları içeren SQL Serverderlemesi için yerel veri tiplerinin. Tabii düzgün çalışabilmesi için montaj gerektiren ek ad boşlukları olabilir. Pointudt da kullandığı System.Textdizelerle çalışmak için ad alanı.

[!NOT]

Visual c++ veritabanı nesneleri, derlenmiş UDTs gibi /clr:pureyürütülmesi için desteklenmiyor.

Öznitelikleri belirtme

Öznitelikleri seri hale getirme değeri istemciye aktarmasını UDTs için ve UDTs depolama gösterimini oluşturmak için nasıl kullanıldığını belirler.

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttributeGerekiyor. SerializableÖzniteliği isteğe bağlı. Ayrıca Microsoft.SqlServer.Server.SqlFacetAttributebir udt dönüş türü hakkında bilgi sağlamak için. Daha fazla bilgi için, bkz. clr yordamları için özel öznitelikleri.

Noktası udt öznitelikleri

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttributeDepolama biçimini ayarlar Pointiçin udt Native. IsByteOrderedayarı true, hangi sanki aynı karşılaştırma yönetilen kod yer almıştı karşılaştırma sonuçlarını aynı SQL Server olduğunu garanti. udt uygulayan System.Data.SqlTypes.INullablearabirimi udt boş farkında olun.

Aşağıdaki kod bölümü özniteliklerini gösterir Pointudt.

<Serializable(), SqlUserDefinedTypeAttribute(Format.Native, _
  IsByteOrdered:=True)> _
  Public Structure Point
    Implements INullable
<Serializable(), SqlUserDefinedTypeAttribute(Format.Native, _
  IsByteOrdered:=True)> _
  Public Structure Point
    Implements INullable
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native,
  IsByteOrdered=true)]
public struct Point : INullable
{
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native,
  IsByteOrdered=true)]
public struct Point : INullable
{

Nullability uygulama

Sizin udt öznitelikleri, derlemeler için doğru belirtmenin yanı sıra, nullability de desteklemelidir. UDTs yüklenen SQL Serverboş tanıyan, ancak boş değer tanımak udt amacıyla, udt uygulamak gerekir System.Data.SqlTypes.INullablearabirimi.

Adında bir özellik oluşturmak gerekir IsNull, hangi değer clr kodu içinde gelen boş olup olmadığını belirlemek için gereklidir. Ne zaman SQL Serverbir udt udt boş bir örneğini normal null işleme yöntemleri kullanarak kalıcı bulur. Sunucu zaman seri hale getirilirken ya da eğer o yok ve boş bir udt depolamak için alan atık değil udt kaldırmada atık değil. udt clr, o kullanarak anlamına gelir getirdi her zaman bu denetimi için Boşlara ver gerçekleştirilir Transact-SQLboş UDTs için denetlemek için IS null inşa etmek-meli her zaman iş. IsNullÖzelliği de örneği boş olup olmadığını sınamak için sunucu tarafından kullanılır. Bir kez sunucu udt boş olduğunu belirleyen, onun yerli null işleme kullanabilirsiniz.

get()Yöntemi IsNullherhangi bir şekilde özel kasalı değil. Eğer bir Pointdeğişken @polan Null, sonra @p.IsNullvarsayılan olarak, "null", yok "1" değerlendirecek. Bunun sebebi SqlMethod(OnNullCall)özniteliği IsNull get()yöntemi varsayılan değeri False'tur. Nesne olduğundan Null, nesne değil serisi, özellik istendiğinde yöntemi olarak değil, "null" varsayılan değeri döndürülür.

Örnek

Aşağıdaki örnekte, is_Nulldeğişken özel ve devlet NULL udt örnek için tutar. Kodunuzu uygun bir değer sağlamalıdır is_Null. udt adında bir statik özellik de olmalıdır Nulludt boş değer bir örneğini döndürür. Bu örneği gerçekten veritabanında null ise null değeri döndürmek udt sağlar.

Private is_Null As Boolean

Public ReadOnly Property IsNull() As Boolean _
   Implements INullable.IsNull
    Get
        Return (is_Null)
    End Get
End Property

Public Shared ReadOnly Property Null() As Point
    Get
        Dim pt As New Point
        pt.is_Null = True
        Return (pt)
    End Get
End Property
Private is_Null As Boolean

Public ReadOnly Property IsNull() As Boolean _
   Implements INullable.IsNull
    Get
        Return (is_Null)
    End Get
End Property

Public Shared ReadOnly Property Null() As Point
    Get
        Dim pt As New Point
        pt.is_Null = True
        Return (pt)
    End Get
End Property
private bool is_Null;

public bool IsNull
{
    get
    {
        return (is_Null);
    }
}

public static Point Null
{
    get
    {
        Point pt = new Point();
        pt.is_Null = true;
        return pt;
    }
}
private bool is_Null;

public bool IsNull
{
    get
    {
        return (is_Null);
    }
}

public static Point Null
{
    get
    {
        Point pt = new Point();
        pt.is_Null = true;
        return pt;
    }
}

null rakip olduğunu.IsNull

Şema noktaları (ID int, konum noktası), nerede içeren bir tabloyu düşünün Pointclr udt ve aşağıdaki sorgular:

--Query 1
SELECT ID
FROM Points
WHERE NOT (location IS NULL) -- Or, WHERE location IS NOT NULL

--Query 1
SELECT ID
FROM Points
WHERE NOT (location IS NULL) -- Or, WHERE location IS NOT NULL

--Query 2:
SELECT ID
FROM Points
WHERE location.IsNull = 0

--Query 2:
SELECT ID
FROM Points
WHERE location.IsNull = 0

Sigara ile Puan kimliklerini hem sorguları döndürür- Null Mekanlar. Sorgu 1, normal null işleme kullanılır ve orada hiçbir seri kaldırma UDTs gereklidir. Sorgu 2, Öte yandan, her sigara serisini vardır- Null nesne ve arama değerini elde etmek için clr IsNullözellik. Açıkçası, kullanarak IS NULLdaha iyi bir performans sergileyecek ve asla okumak için bir neden olmalı IsNullözelliği UDT Transact-SQLkod.

Kullanımı nedir yani, IsNullözelliği? İlk olarak, bir değer olup olmadığını belirlemek için gereken Nullgelen clr içinde kod. İkinci olarak, sunucu örneği olup olmadığını sınamak için bir yol gerekir Null, bu nedenle bu özellik sunucu tarafından kullanılır. O belirler sonra Null, sonra onun yerli boş görüneceği şekilde işlemek için işleme kullanabilirsiniz

Ayrıştırma yöntemini uygulama

ParseVe ToStringyöntemleri izin dönüştürmeleri dize temsilini udt gelen ve. ParseYöntemi bir udt Dönüştürülecek dize verir. Olarak bildirilmelidir static(veya SharedVisual Basic) ve bir parametre türü System.Data.SqlTypes.SqlString.

Aşağıdaki kod Implements Parseyöntemi Pointx ve y koordinatları ayıran udt. ParseYöntemi tek bir bağımsız değişken türü olan System.Data.SqlTypes.SqlStringve x ve y değerleri virgülle sınırlandırılmış bir dize olarak sunulan varsayar. Ayar Microsoft.SqlServer.Server.SqlMethodAttribute.OnNullCallözniteliği falseönler Parsegelen boş bir noktası örneğinden çağrılan yöntemi.

<SqlMethod(OnNullCall:=False)> _
Public Shared Function Parse(ByVal s As SqlString) As Point
    If s.IsNull Then
        Return Null
    End If

    ' Parse input string here to separate out points.
    Dim pt As New Point()
    Dim xy() As String = s.Value.Split(",".ToCharArray())
    pt.X = Int32.Parse(xy(0))
    pt.Y = Int32.Parse(xy(1))
    Return pt
End Function
<SqlMethod(OnNullCall:=False)> _
Public Shared Function Parse(ByVal s As SqlString) As Point
    If s.IsNull Then
        Return Null
    End If

    ' Parse input string here to separate out points.
    Dim pt As New Point()
    Dim xy() As String = s.Value.Split(",".ToCharArray())
    pt.X = Int32.Parse(xy(0))
    pt.Y = Int32.Parse(xy(1))
    Return pt
End Function
[SqlMethod(OnNullCall = false)]
public static Point Parse(SqlString s)
{
    if (s.IsNull)
        return Null;

    // Parse input string to separate out points.
    Point pt = new Point();
    string[] xy = s.Value.Split(",".ToCharArray());
    pt.X = Int32.Parse(xy[0]);
    pt.Y = Int32.Parse(xy[1]);
    return pt;
}
[SqlMethod(OnNullCall = false)]
public static Point Parse(SqlString s)
{
    if (s.IsNull)
        return Null;

    // Parse input string to separate out points.
    Point pt = new Point();
    string[] xy = s.Value.Split(",".ToCharArray());
    pt.X = Int32.Parse(xy[0]);
    pt.Y = Int32.Parse(xy[1]);
    return pt;
}

ToString yöntemini uygulama

ToStringYöntemi dönüştürür Pointdize değeri udt. Bu durumda, "null" dizesini bir Null örneği için döndürülen Pointtürü. ToStringYöntemi tersine çevirir Parseyöntemini kullanarak bir System.Text.StringBuildervirgül ayraçlı dönmek için System.Stringx ve y koordinat değerlerini oluşan. Çünkü InvokeIfReceiverIsNull varsayılan değeri False'tur, boş bir örneğini denetleme Pointgereksiz.

Private _x As Int32
Private _y As Int32

Public Overrides Function ToString() As String
    If Me.IsNull Then
        Return "NULL"
    Else
        Dim builder As StringBuilder = New StringBuilder
        builder.Append(_x)
        builder.Append(",")
        builder.Append(_y)
        Return builder.ToString
    End If
End Function
Private _x As Int32
Private _y As Int32

Public Overrides Function ToString() As String
    If Me.IsNull Then
        Return "NULL"
    Else
        Dim builder As StringBuilder = New StringBuilder
        builder.Append(_x)
        builder.Append(",")
        builder.Append(_y)
        Return builder.ToString
    End If
End Function
private Int32 _x;
private Int32 _y;

public override string ToString()
{
    if (this.IsNull)
        return "NULL";
    else
    {
        StringBuilder builder = new StringBuilder();
        builder.Append(_x);
        builder.Append(",");
        builder.Append(_y);
        return builder.ToString();
    }
}
private Int32 _x;
private Int32 _y;

public override string ToString()
{
    if (this.IsNull)
        return "NULL";
    else
    {
        StringBuilder builder = new StringBuilder();
        builder.Append(_x);
        builder.Append(",");
        builder.Append(_y);
        return builder.ToString();
    }
}

udt özellikler açığa

Pointx ve y koordinatları, türü ortak okuma-yazma özellikleri olarak uygulanan udt sunar System.Int32.

Public Property X() As Int32
    Get
        Return (Me._x)
    End Get

    Set(ByVal Value As Int32)
        _x = Value
    End Set
End Property

Public Property Y() As Int32
    Get
        Return (Me._y)
    End Get

    Set(ByVal Value As Int32)
        _y = Value
    End Set
End Property
Public Property X() As Int32
    Get
        Return (Me._x)
    End Get

    Set(ByVal Value As Int32)
        _x = Value
    End Set
End Property

Public Property Y() As Int32
    Get
        Return (Me._y)
    End Get

    Set(ByVal Value As Int32)
        _y = Value
    End Set
End Property
public Int32 X
{
    get
    {
        return this._x;
    }
    set 
    {
        _x = value;
    }
}

public Int32 Y
{
    get
    {
        return this._y;
    }
    set
    {
        _y = value;
    }
}
public Int32 X
{
    get
    {
        return this._x;
    }
    set 
    {
        _x = value;
    }
}

public Int32 Y
{
    get
    {
        return this._y;
    }
    set
    {
        _y = value;
    }
}

udt değerleri doğrulanıyor

udt verilerle çalışırken SQL Server Veritabanı Altyapısıotomatik olarak ikili değerlerini udt değerlere dönüştürür. Bu dönüşüm süreci değerlerin türü seri hale getirme biçimi uygun olduğunu kontrol etmek ve değeri doğru serisi sağlanması içerir. Bu değeri ikili formuna geri dönüştürülebilir sağlar. UDTs bayt sipariş durumunda, bu da ortaya çıkan ikili değeri özgün ikili değerini eşleşen sağlar. Bu geçersiz değer veritabanında kalıcı engeller. Bazı durumlarda, denetimi bu düzeyi yetersiz olabilir. udt değerleri bir beklenen etki alanı ya da aralıkta olması için gerekli olan ek doğrulama gerekli olabilir. Örneğin, bir Tarih uygulayan bir udt belirli bir geçerli değer aralığı içinde düşer pozitif bir sayı olarak gün değeri gerektirebilir.

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.ValidationMethodNameÖzelliği Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute, veriler için udt atanan veya udt için dönüştürülmüş sunucu çalışan bir doğrulama yöntemi adını vermesini sağlar. ValidationMethodNamebcp yardımcı programı, bulk INSERT, dbcc checkdb, dbcc CHECKFILEGROUP, dbcc checktable, dağıtılmış sorgu ve sekmeli veri akışı (tds) uzaktan yordam çağrısı (rpc) Operasyon çalıştırılırken olarak da adlandırılır. Varsayılan değeri ValidationMethodNameno doğrulama yöntemi olduğunu belirten NULL.

Örnek

Aşağıdaki kod parçasını bildirimi gösterir Pointbelirten sınıfı, bir ValidationMethodName, ValidatePoint.

<Serializable(), SqlUserDefinedTypeAttribute(Format.Native, _
  IsByteOrdered:=True, _
  ValidationMethodName:="ValidatePoint")> _
  Public Structure Point
<Serializable(), SqlUserDefinedTypeAttribute(Format.Native, _
  IsByteOrdered:=True, _
  ValidationMethodName:="ValidatePoint")> _
  Public Structure Point
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native,
  IsByteOrdered=true, 
  ValidationMethodName = "ValidatePoint")]
public struct Point : INullable
{
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native,
  IsByteOrdered=true, 
  ValidationMethodName = "ValidatePoint")]
public struct Point : INullable
{

Bir doğrulama yöntemi belirtilmezse, aşağıdaki kod parçası gibi görünen bir imza olmalıdır.

Private Function ValidationFunction() As Boolean
    If (validation logic here) Then
        Return True
    Else
        Return False
    End If
End Function
Private Function ValidationFunction() As Boolean
    If (validation logic here) Then
        Return True
    Else
        Return False
    End If
End Function
private bool ValidationFunction()
{
    if (validation logic here)
    {
        return true;
    }
    else
    {
        return false;
    }
}
private bool ValidationFunction()
{
    if (validation logic here)
    {
        return true;
    }
    else
    {
        return false;
    }
}

Doğrulama yöntemi herhangi bir kapsama sahip olabilir ve -meli dönmek truedeğeri geçerliyse ve falseaksi. Yöntem ise falseya da bir özel durum atar, bir değer kabul geçerli değil ve bir hata ortaya çıkar.

Aşağıdaki örnekte, kodu yalnızca değerleri sıfır ya da daha x ve y koordinatları sağlar.

Private Function ValidatePoint() As Boolean
    If (_x >= 0) And (_y >= 0) Then
        Return True
    Else
        Return False
    End If
End Function
Private Function ValidatePoint() As Boolean
    If (_x >= 0) And (_y >= 0) Then
        Return True
    Else
        Return False
    End If
End Function
private bool ValidatePoint()
{
    if ((_x >= 0) && (_y >= 0))
    {
        return true;
    }
    else
    {
        return false;
    }
}
private bool ValidatePoint()
{
    if ((_x >= 0) && (_y >= 0))
    {
        return true;
    }
    else
    {
        return false;
    }
}

Doğrulama yöntemi sınırlamaları

Veri bireysel özelliklerini ayarlayarak veya verileri kullanarak takıldığında değil takıldığında sunucu dönüşümleri gerçekleştirirken sunucu doğrulama yöntemini çağıran bir Transact-SQLINSERT deyimi.

Açıkça özelliği belirleyiciler doğrulama yöntemini çağırmanız gerekir ve ayrıştırma bütün durumlarda yürütmek için doğrulama yöntemi isterseniz yöntemi. Bu bir zorunluluk değildir ve bazı durumlarda bile arzu olmayabilir.

Ayrıştırma doğrulaması örneği

Emin olmak için ValidatePoint yöntemi çağrılan içinde noktası sınıfı, sen ondan çağrı gerekir ayrıştırma yöntemi özelliğinden yordamların x ve y değerleri koordine. Aşağıdaki kod bölümü çağrı gösterilmiştir ValidatePoint doğrulama yönteminden ayrıştırma işlevi.

<SqlMethod(OnNullCall:=False)> _
Public Shared Function Parse(ByVal s As SqlString) As Point
    If s.IsNull Then
        Return Null
    End If

    ' Parse input string here to separate out points.
    Dim pt As New Point()
    Dim xy() As String = s.Value.Split(",".ToCharArray())
    pt.X = Int32.Parse(xy(0))
    pt.Y = Int32.Parse(xy(1))

    ' Call ValidatePoint to enforce validation
    ' for string conversions.
    If Not pt.ValidatePoint() Then
        Throw New ArgumentException("Invalid XY coordinate values.")
    End If
    Return pt
End Function
<SqlMethod(OnNullCall:=False)> _
Public Shared Function Parse(ByVal s As SqlString) As Point
    If s.IsNull Then
        Return Null
    End If

    ' Parse input string here to separate out points.
    Dim pt As New Point()
    Dim xy() As String = s.Value.Split(",".ToCharArray())
    pt.X = Int32.Parse(xy(0))
    pt.Y = Int32.Parse(xy(1))

    ' Call ValidatePoint to enforce validation
    ' for string conversions.
    If Not pt.ValidatePoint() Then
        Throw New ArgumentException("Invalid XY coordinate values.")
    End If
    Return pt
End Function
[SqlMethod(OnNullCall = false)]
public static Point Parse(SqlString s)
{
    if (s.IsNull)
        return Null;

    // Parse input string to separate out points.
    Point pt = new Point();
    string[] xy = s.Value.Split(",".ToCharArray());
    pt.X = Int32.Parse(xy[0]);
    pt.Y = Int32.Parse(xy[1]);

    // Call ValidatePoint to enforce validation
    // for string conversions.
    if (!pt.ValidatePoint()) 
        throw new ArgumentException("Invalid XY coordinate values.");
    return pt;
}
[SqlMethod(OnNullCall = false)]
public static Point Parse(SqlString s)
{
    if (s.IsNull)
        return Null;

    // Parse input string to separate out points.
    Point pt = new Point();
    string[] xy = s.Value.Split(",".ToCharArray());
    pt.X = Int32.Parse(xy[0]);
    pt.Y = Int32.Parse(xy[1]);

    // Call ValidatePoint to enforce validation
    // for string conversions.
    if (!pt.ValidatePoint()) 
        throw new ArgumentException("Invalid XY coordinate values.");
    return pt;
}

Özellik doğrulaması örneği

Aşağıdaki kod bölümü çağrı gösterilmiştir ValidatePoint x ve y koordinatları ayarlanan özellik yordamlarını doğrulama yöntemi.

Public Property X() As Int32
    Get
        Return (Me._x)
    End Get

    Set(ByVal Value As Int32)
        Dim temp As Int32 = _x
        _x = Value
        If Not ValidatePoint() Then
            _x = temp
            Throw New ArgumentException("Invalid X coordinate value.")
        End If
    End Set
End Property

Public Property Y() As Int32
    Get
        Return (Me._y)
    End Get

    Set(ByVal Value As Int32)
        Dim temp As Int32 = _y
        _y = Value
        If Not ValidatePoint() Then
            _y = temp
            Throw New ArgumentException("Invalid Y coordinate value.")
        End If
    End Set
End Property
Public Property X() As Int32
    Get
        Return (Me._x)
    End Get

    Set(ByVal Value As Int32)
        Dim temp As Int32 = _x
        _x = Value
        If Not ValidatePoint() Then
            _x = temp
            Throw New ArgumentException("Invalid X coordinate value.")
        End If
    End Set
End Property

Public Property Y() As Int32
    Get
        Return (Me._y)
    End Get

    Set(ByVal Value As Int32)
        Dim temp As Int32 = _y
        _y = Value
        If Not ValidatePoint() Then
            _y = temp
            Throw New ArgumentException("Invalid Y coordinate value.")
        End If
    End Set
End Property
    public Int32 X
{
    get
    {
        return this._x;
    }
    // Call ValidatePoint to ensure valid range of Point values.
    set 
    {
        Int32 temp = _x;
        _x = value;
        if (!ValidatePoint())
        {
            _x = temp;
            throw new ArgumentException("Invalid X coordinate value.");
        }
    }
}

public Int32 Y
{
    get
    {
        return this._y;
    }
    set
    {
        Int32 temp = _y;
        _y = value;
        if (!ValidatePoint())
        {
            _y = temp;
            throw new ArgumentException("Invalid Y coordinate value.");
        }
    }
}
    public Int32 X
{
    get
    {
        return this._x;
    }
    // Call ValidatePoint to ensure valid range of Point values.
    set 
    {
        Int32 temp = _x;
        _x = value;
        if (!ValidatePoint())
        {
            _x = temp;
            throw new ArgumentException("Invalid X coordinate value.");
        }
    }
}

public Int32 Y
{
    get
    {
        return this._y;
    }
    set
    {
        Int32 temp = _y;
        _y = value;
        if (!ValidatePoint())
        {
            _y = temp;
            throw new ArgumentException("Invalid Y coordinate value.");
        }
    }
}

Kodlama udt yöntemleri

Kodlama udt yöntemleri kullanılan algoritma belki zamanla değişebilir mi dikkate alın. Öyleyse, sizin udt yöntemleri için ayrı bir sınıf oluşturma kullanır dikkate isteyebilirsiniz. Algoritma değişirse, yeni kod sınıf derlemeniz ve içine derleme yükleme SQL Serverudt etkilemeden. Birçok durumda UDTs kullanarak yeniden Transact-SQLalter assembly deyimi, ama potansiyel olarak mevcut verilerle sorunlara neden. Örneğin, para udt dahil ile AdventureWorks örnek veritabanını kullanır bir ConvertCurrency da ayrı bir sınıfta uygulanan para birimi değerleri dönüştürmek için işlevi. Dönüştürme algoritmaları beklenmedik şekillerde gelecekte değişebilir veya bu yeni işlevsellik gerekli olabilir mümkündür. Ayıran ConvertCurrency gelen işlev para udt uygulaması, gelecekteki değişiklikler için planlama yaparken daha fazla esneklik sağlar.

Örnek

Noktası sınıfı, uzaklığı hesaplamak için üç basit yöntem içerir: mesafe, DistanceFrom ve DistanceFromXY. Her döndürür bir doublemesafe hesaplama Pointsıfır için belirli bir mesafeden gelin Point, ve mesafe belirlenen x ve y koordinatları için Point. Mesafe ve DistanceFrom her arama DistanceFromXYve nasıl farklı değişkenleri her yöntemin kullanıldığını göstermektedir.

' Distance from 0 to Point.
<SqlMethod(OnNullCall:=False)> _
Public Function Distance() As Double
    Return DistanceFromXY(0, 0)
End Function

' Distance from Point to the specified point.
<SqlMethod(OnNullCall:=False)> _
Public Function DistanceFrom(ByVal pFrom As Point) As Double
    Return DistanceFromXY(pFrom.X, pFrom.Y)
End Function

' Distance from Point to the specified x and y values.
<SqlMethod(OnNullCall:=False)> _
Public Function DistanceFromXY(ByVal ix As Int32, ByVal iy As Int32) _
    As Double
    Return Math.Sqrt(Math.Pow(ix - _x, 2.0) + Math.Pow(iy - _y, 2.0))
End Function
' Distance from 0 to Point.
<SqlMethod(OnNullCall:=False)> _
Public Function Distance() As Double
    Return DistanceFromXY(0, 0)
End Function

' Distance from Point to the specified point.
<SqlMethod(OnNullCall:=False)> _
Public Function DistanceFrom(ByVal pFrom As Point) As Double
    Return DistanceFromXY(pFrom.X, pFrom.Y)
End Function

' Distance from Point to the specified x and y values.
<SqlMethod(OnNullCall:=False)> _
Public Function DistanceFromXY(ByVal ix As Int32, ByVal iy As Int32) _
    As Double
    Return Math.Sqrt(Math.Pow(ix - _x, 2.0) + Math.Pow(iy - _y, 2.0))
End Function
// Distance from 0 to Point.
[SqlMethod(OnNullCall = false)]
public Double Distance()
{
    return DistanceFromXY(0, 0);
}

// Distance from Point to the specified point.
[SqlMethod(OnNullCall = false)]
public Double DistanceFrom(Point pFrom)
{
    return DistanceFromXY(pFrom.X, pFrom.Y);
}

// Distance from Point to the specified x and y values.
[SqlMethod(OnNullCall = false)]
public Double DistanceFromXY(Int32 iX, Int32 iY)
{
    return Math.Sqrt(Math.Pow(iX - _x, 2.0) + Math.Pow(iY - _y, 2.0));
}
// Distance from 0 to Point.
[SqlMethod(OnNullCall = false)]
public Double Distance()
{
    return DistanceFromXY(0, 0);
}

// Distance from Point to the specified point.
[SqlMethod(OnNullCall = false)]
public Double DistanceFrom(Point pFrom)
{
    return DistanceFromXY(pFrom.X, pFrom.Y);
}

// Distance from Point to the specified x and y values.
[SqlMethod(OnNullCall = false)]
public Double DistanceFromXY(Int32 iX, Int32 iY)
{
    return Math.Sqrt(Math.Pow(iX - _x, 2.0) + Math.Pow(iY - _y, 2.0));
}

SqlMethod öznitelikleri kullanma

Microsoft.SqlServer.Server.SqlMethodAttributeSınıf yöntem tanımlarını işaretlemek için determinizm, boş arama davranışını belirtmek için ve bir mutator yöntemi olup olmadığını belirlemek için kullanılabilecek özel öznitelikleri sağlar. Bu özellikleri için varsayılan değerleri kabul edilir ve özel öznitelik yalnızca bir varsayılan olmayan değer gerektiğinde kullanılır.

[!NOT]

SqlMethodAttributeSınıf devralır SqlFunctionAttributesınıf, bunu SqlMethodAttributedevralan FillRowMethodNameve TableDefinitionalanlardan SqlFunctionAttribute. Bu durumda değil bir tablo valued yöntem yazmak mümkün olduğunu ima ediyor. Yöntem derler ve derleme dağıtır, bir hata hakkında IEnumerabletürü aşağıdaki iletiyle zamanında geçirilen dönmek: "yöntem, özellik veya alan '<ad>' sınıfta<sınıfı>' Meclisi '<Meclis>' geçersiz dönüş türü var."

Aşağıdaki tabloda ilgili açıklar Microsoft.SqlServer.Server.SqlMethodAttribute, özelliklerin udt yöntemleri kullanılabilir ve varsayılan değerleri listeler.

  • DataAccess
    İşlev içinde yerel örneği depolanan kullanıcı veri erişim içerir olup olmadığını gösterir SQL Server. Varsayılan DataAccessKind.None.

  • IsDeterministic
    İster işlevi aynı çıkış değerleri aynı giriş değerleri ve aynı veritabanı durumunu göz önüne alındığında üretir gösterir. Varsayılan false.

  • IsMutator
    Yöntem udt örnek bir durum değişikliği neden olup olmadığını gösterir. Varsayılan false.

  • IsPrecise
    İşlev kayan nokta işlemleri gibi imprecise hesaplamaları içerir olup olmadığını gösterir. Varsayılan false.

  • OnNullCall
    Null başvuru giriş bağımsız değişkeni belirtildiğinde yöntemin çağrıldığı olup olmadığını gösterir. Varsayılan true.

Örnek

Microsoft.SqlServer.Server.SqlMethodAttribute.IsMutatorÖzelliği udt örnek durumunda bir değişiklik izin veren bir yöntem işaretlemek sağlar. Transact-SQLbir update deyimi set yan tümcesinde iki udt özellikler ayarlamanıza izin vermez. Ancak, iki üye değiştiren bir mutator işaretlenmiş bir yöntem olabilir.

[!NOT]

Mutator yöntemi sorgularda izin verilmez. Onlar sadece atama deyimleri ya da veri değişikliği deyimleri içinde çağrılabilir. Mutator değil dönmek gibi bir yöntem işaretliyse void(ya da değil bir SubVisual Basic), create type bir hata ile başarısız.

Aşağıdaki ifadeyi varlığını varsayar bir Trianglesolan udt bir Rotateyöntemi. Aşağıdaki Transact-SQLupdate deyimi çalıştırır Rotateyöntemi:

UPDATE Triangles SET t.RotateY(0.6) WHERE id=5

UPDATE Triangles SET t.RotateY(0.6) WHERE id=5

RotateYöntemi ile dekore edilmiş SqlMethodöznitelik ayarı IsMutatoriçin trueki SQL Serveryöntemi mutator yöntemi olarak işaretleyebilirsiniz. Ayarlar kodu da OnNullCalliçin false, hangi gösterir sunucusuna yöntemi null başvuru döndürür ( Nothing Visual Basic) Eğer herhangi bir giriş parametreleri null başvuru.

<SqlMethod(IsMutator:=True, OnNullCall:=False)> _
Public Sub Rotate(ByVal anglex as Double, _
  ByVal angley as Double, ByVal anglez As Double) 
   RotateX(anglex)
   RotateY(angley)
   RotateZ(anglez)
End Sub
<SqlMethod(IsMutator:=True, OnNullCall:=False)> _
Public Sub Rotate(ByVal anglex as Double, _
  ByVal angley as Double, ByVal anglez As Double) 
   RotateX(anglex)
   RotateY(angley)
   RotateZ(anglez)
End Sub
[SqlMethod(IsMutator = true, OnNullCall = false)]
public void Rotate(double anglex, double angley, double anglez) 
{
   RotateX(anglex);
   RotateY(angley);
   RotateZ(anglez);
}
[SqlMethod(IsMutator = true, OnNullCall = false)]
public void Rotate(double anglex, double angley, double anglez) 
{
   RotateX(anglex);
   RotateY(angley);
   RotateZ(anglez);
}

udt ile kullanıcı tanımlı bir biçim uygulama

udt kullanıcı tanımlı bir biçim ile uygulama uygulamak gerekir Readve Writeseri hale getiriliyor ve udt veri serisi kaldırılırken ele Microsoft.SqlServer.Server.IBinarySerialize arabirimini uygulayan yöntemleri. Ayrıca belirtmeniz gerekir MaxByteSizeözelliği Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.

udt para

Currencyudt o-ebilmek var olmak installed ile clr örnekleri ile birlikte SQL Server, ile başlayan SQL Server 2005. clr örnekleri yükleme hakkında daha fazla bilgi için bkz: Creating a User-Defined Type.

Currencyudt destekler işleme miktarlarda parasal sistemde belirli bir kültür. İki alanı tanımlamalısınız: bir stringiçin CultureInfo, kim para verilen belirten (tr-bize, örneğin) ve bir decimaliçin CurrencyValue, para.

Sunucu tarafından karşılaştırmalar, gerçekleştirmek için kullanılmaz, ancak Currencyudt uygulayan System.IComparablearabirimi olan bir tek yöntem sunar, System.IComparable.CompareTo. Bu, istemci tarafında arzu doğru karşılaştırmak veya sipariş para birimi değerlerini kültürler içinde olduğu durumlarda kullanılır.

clr içinde çalışan kod kültürü ayrı ayrı para birimi değeri karşılaştırır. İçin Transact-SQLkodu, aşağıdaki eylemleri belirleyen karşılaştırma:

  1. Set IsByteOrderedözniteliği true, hangi söyler SQL Serverkarşılaştırmalar için kalıcı ikili gösterimini kullanmak için.

  2. Kullanım Writeyöntemi Currencyudt udt nasıl kalıcı belirlemek için disk ve bu nedenle udt değerlerin nasıl karşılaştırılır ve sipariş için Transact-SQLOperasyon.

  3. Kaydet CurrencyAşağıdaki ikili biçimi kullanarak udt:

    1. Kültür, utf-16 kodlanmış dizesi için bayt boş karakterler ile sağ doldurma 0-19 olarak kaydedin.

    2. 20 Bayt kullanır ve para birimi ondalık değeri içeren için yukarıdaki.

Doldurma amacı ne zaman karşı başka bir udt karşılaştırıldığında böylece kültür para birimi değeri, tamamen ayrılır sağlamaktır Transact-SQLkodu, Kültür bayt Kültür bayt karşı karşılaştırılır ve para birimi bayt değerleri para birimi bayt değerlerini karşı karşılaştırılır.

İçin listeleme tamamlandı kodu için Currencyudt clr örnekleri yükleme yönergeleri, Installing Samples.

Para birimi öznitelikleri

Currencyudt tanımlanan aşağıdaki özniteliklerle.

<Serializable(), Microsoft.SqlServer.Server.SqlUserDefinedType( _
    Microsoft.SqlServer.Server.Format.UserDefined, _
    IsByteOrdered:=True, MaxByteSize:=32), _
    CLSCompliant(False)> _
Public Structure Currency
Implements INullable, IComparable, _
Microsoft.SqlServer.Server.IBinarySerialize
<Serializable(), Microsoft.SqlServer.Server.SqlUserDefinedType( _
    Microsoft.SqlServer.Server.Format.UserDefined, _
    IsByteOrdered:=True, MaxByteSize:=32), _
    CLSCompliant(False)> _
Public Structure Currency
Implements INullable, IComparable, _
Microsoft.SqlServer.Server.IBinarySerialize
[Serializable]
[SqlUserDefinedType(Format.UserDefined, 
    IsByteOrdered = true, MaxByteSize = 32)]
    [CLSCompliant(false)]
    public struct Currency : INullable, IComparable, IBinarySerialize
    {
[Serializable]
[SqlUserDefinedType(Format.UserDefined, 
    IsByteOrdered = true, MaxByteSize = 32)]
    [CLSCompliant(false)]
    public struct Currency : INullable, IComparable, IBinarySerialize
    {

Okuma ve yazma yöntemleri IBinarySerialize ile oluşturma

Seçtiğinizde UserDefinedseri hale getirme biçimi, sen de uygulamak gerekir IBinarySerializearayüz ve kendi oluşturmak Readve Writeyöntemleri. Aşağıdaki yordamlardan Currencyudt kullanın System.IO.BinaryReaderve System.IO.BinaryWriterokuma ve yazma için udt.

' IBinarySerialize methods
' The binary layout is as follow:
'    Bytes 0 - 19: Culture name, padded to the right with null
'    characters, UTF-16 encoded
'    Bytes 20+: Decimal value of money
' If the culture name is empty, the currency is null.
Public Sub Write(ByVal w As System.IO.BinaryWriter) _
  Implements Microsoft.SqlServer.Server.IBinarySerialize.Write
    If Me.IsNull Then
        w.Write(nullMarker)
        w.Write(System.Convert.ToDecimal(0))
        Return
    End If

    If cultureName.Length > cultureNameMaxSize Then
        Throw New ApplicationException(String.Format(CultureInfo.CurrentUICulture, _
           "{0} is an invalid culture name for currency as it is too long.", cultureNameMaxSize))
    End If

    Dim paddedName As String = cultureName.PadRight(cultureNameMaxSize, CChar(vbNullChar))

    For i As Integer = 0 To cultureNameMaxSize - 1
        w.Write(paddedName(i))
    Next i

    ' Normalize decimal value to two places
    currencyVal = Decimal.Floor(currencyVal * 100) / 100
    w.Write(currencyVal)
End Sub

Public Sub Read(ByVal r As System.IO.BinaryReader) _
  Implements Microsoft.SqlServer.Server.IBinarySerialize.Read
    Dim name As Char() = r.ReadChars(cultureNameMaxSize)
    Dim stringEnd As Integer = Array.IndexOf(name, CChar(vbNullChar))

    If stringEnd = 0 Then
        cultureName = Nothing
        Return
    End If

    cultureName = New String(name, 0, stringEnd)
    currencyVal = r.ReadDecimal()
End Sub
' IBinarySerialize methods
' The binary layout is as follow:
'    Bytes 0 - 19: Culture name, padded to the right with null
'    characters, UTF-16 encoded
'    Bytes 20+: Decimal value of money
' If the culture name is empty, the currency is null.
Public Sub Write(ByVal w As System.IO.BinaryWriter) _
  Implements Microsoft.SqlServer.Server.IBinarySerialize.Write
    If Me.IsNull Then
        w.Write(nullMarker)
        w.Write(System.Convert.ToDecimal(0))
        Return
    End If

    If cultureName.Length > cultureNameMaxSize Then
        Throw New ApplicationException(String.Format(CultureInfo.CurrentUICulture, _
           "{0} is an invalid culture name for currency as it is too long.", cultureNameMaxSize))
    End If

    Dim paddedName As String = cultureName.PadRight(cultureNameMaxSize, CChar(vbNullChar))

    For i As Integer = 0 To cultureNameMaxSize - 1
        w.Write(paddedName(i))
    Next i

    ' Normalize decimal value to two places
    currencyVal = Decimal.Floor(currencyVal * 100) / 100
    w.Write(currencyVal)
End Sub

Public Sub Read(ByVal r As System.IO.BinaryReader) _
  Implements Microsoft.SqlServer.Server.IBinarySerialize.Read
    Dim name As Char() = r.ReadChars(cultureNameMaxSize)
    Dim stringEnd As Integer = Array.IndexOf(name, CChar(vbNullChar))

    If stringEnd = 0 Then
        cultureName = Nothing
        Return
    End If

    cultureName = New String(name, 0, stringEnd)
    currencyVal = r.ReadDecimal()
End Sub
// IBinarySerialize methods
// The binary layout is as follow:
//    Bytes 0 - 19:Culture name, padded to the right 
//    with null characters, UTF-16 encoded
//    Bytes 20+:Decimal value of money
// If the culture name is empty, the currency is null.
public void Write(System.IO.BinaryWriter w)
{
    if (this.IsNull)
    {
        w.Write(nullMarker);
        w.Write((decimal)0);
        return;
    }

    if (cultureName.Length > cultureNameMaxSize)
    {
        throw new ApplicationException(string.Format(
            CultureInfo.InvariantCulture, 
            "{0} is an invalid culture name for currency as it is too long.", 
            cultureNameMaxSize));
    }

    String paddedName = cultureName.PadRight(cultureNameMaxSize, '\0');
    for (int i = 0; i < cultureNameMaxSize; i++)
    {
        w.Write(paddedName[i]);
    }

    // Normalize decimal value to two places
    currencyValue = Decimal.Floor(currencyValue * 100) / 100;
    w.Write(currencyValue);
}
public void Read(System.IO.BinaryReader r)
{
    char[] name = r.ReadChars(cultureNameMaxSize);
    int stringEnd = Array.IndexOf(name, '\0');

    if (stringEnd == 0)
    {
        cultureName = null;
        return;
    }

    cultureName = new String(name, 0, stringEnd);
    currencyValue = r.ReadDecimal();
}
// IBinarySerialize methods
// The binary layout is as follow:
//    Bytes 0 - 19:Culture name, padded to the right 
//    with null characters, UTF-16 encoded
//    Bytes 20+:Decimal value of money
// If the culture name is empty, the currency is null.
public void Write(System.IO.BinaryWriter w)
{
    if (this.IsNull)
    {
        w.Write(nullMarker);
        w.Write((decimal)0);
        return;
    }

    if (cultureName.Length > cultureNameMaxSize)
    {
        throw new ApplicationException(string.Format(
            CultureInfo.InvariantCulture, 
            "{0} is an invalid culture name for currency as it is too long.", 
            cultureNameMaxSize));
    }

    String paddedName = cultureName.PadRight(cultureNameMaxSize, '\0');
    for (int i = 0; i < cultureNameMaxSize; i++)
    {
        w.Write(paddedName[i]);
    }

    // Normalize decimal value to two places
    currencyValue = Decimal.Floor(currencyValue * 100) / 100;
    w.Write(currencyValue);
}
public void Read(System.IO.BinaryReader r)
{
    char[] name = r.ReadChars(cultureNameMaxSize);
    int stringEnd = Array.IndexOf(name, '\0');

    if (stringEnd == 0)
    {
        cultureName = null;
        return;
    }

    cultureName = new String(name, 0, stringEnd);
    currencyValue = r.ReadDecimal();
}

İçin listeleme tamamlandı kodu için Currencyudt görmek, Installing Samples.

Ayrıca bkz.

Diğer Kaynaklar

Bir kullanıcı tanımlı türü oluşturma