Erstellen benutzerdefinierter Typen
Gilt für: SQL Server
Um einen benutzerdefinierten Typ (USER-Defined Type, UDT) zu erstellen, der in SQL Server installiert werden kann, müssen Sie zunächst eine Klasse in einer der unterstützten .NET Framework-Programmiersprachen erstellen, z. B. Visual C# oder Visual Basic, die den Spezifikationen für das Erstellen von UDTs entsprechen. Die Klasse kann dann als Dynamic Link Library (DLL) kompiliert werden, die in SQL Server geladen werden kann. Sie können UDTs auch mit Visual Studio erstellen und bereitstellen.
Die Möglichkeit zum Ausführen von CLR-Code (Common Language Runtime) ist standardmäßig in SQL Server auf OFF festgelegt. Die CLR kann mithilfe der gespeicherten sp_configure Systemprozedur aktiviert werden, wie in den folgenden Transact-SQL-Anweisungen gezeigt:
sp_configure 'clr enabled', 1
Reconfigure
In diesem Abschnitt
Anforderungen für den benutzerdefinierten Typ
Beschreibt die Anforderungen an die Programmierung benutzerdefinierter Typen
Programmieren benutzerdefinierter Typen
Veranschaulicht Programmiertechniken, die bei der Erstellung benutzerdefinierter Typen relevant sind.
Beispiel
In der folgenden Codeauflistung wird das Point UDT definiert, das im Detail in "Codieren von benutzerdefinierten Typen" beschrieben wird.
C#
using System;
using System.Data;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text;
[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native,
IsByteOrdered=true, ValidationMethodName = "ValidatePoint")]
public struct Point : INullable
{
private bool is_Null;
private Int32 _x;
private Int32 _y;
public bool IsNull
{
get
{
return (is_Null);
}
}
public static Point Null
{
get
{
Point pt = new Point();
pt.is_Null = true;
return pt;
}
}
// Use StringBuilder to provide string representation of UDT.
public override string ToString()
{
// Since InvokeIfReceiverIsNull defaults to 'true'
// this test is unnecessary if Point is only being called
// from SQL.
if (this.IsNull)
return "NULL";
else
{
StringBuilder builder = new StringBuilder();
builder.Append(_x);
builder.Append(",");
builder.Append(_y);
return builder.ToString();
}
}
[SqlMethod(OnNullCall = false)]
public static Point Parse(SqlString s)
{
// With OnNullCall=false, this check is unnecessary if
// Point only called from SQL.
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;
}
// X and Y coordinates exposed as properties.
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.");
}
}
}
// Validation method to enforce valid X and Y values.
private bool ValidatePoint()
{
// Allow only zero or positive integers for X and Y coordinates.
if ((_x >= 0) && (_y >= 0))
{
return true;
}
else
{
return false;
}
}
// Distance from 0 to Point method.
[SqlMethod(OnNullCall = false)]
public Double Distance()
{
return DistanceFromXY(0, 0);
}
// Distance from Point to the specified point method.
[SqlMethod(OnNullCall = false)]
public Double DistanceFrom(Point pFrom)
{
return DistanceFromXY(pFrom.X, pFrom.Y);
}
// Distance from Point to the specified x and y values method.
[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));
}
}
Visual Basic
Option Explicit On
Option Strict On
Imports System
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Imports System.Text
<Serializable(), SqlUserDefinedTypeAttribute(Format.Native, _
IsByteOrdered:=True, _
ValidationMethodName:="ValidatePoint")> _
Public Structure Point
Implements INullable
Private is_Null As Boolean
Private _x As Int32
Private _y As Int32
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
' Use StringBuilder to provide string representation of UDT.
Public Overrides Function ToString() As String
' Since InvokeIfReceiverIsNull defaults to 'true'
' this test is unnecessary if Point is only being called
' from SQL.
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
<SqlMethod(OnNullCall:=False)> _
Public Shared Function Parse(ByVal s As SqlString) As Point
' With OnNullCall=False, this check is unnecessary if
' Point only being called from SQL.
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
' X and Y coordinates are exposed as properties.
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
' Validation method to enforce valid X and Y values.
Private Function ValidatePoint() As Boolean
' Allow only zero or positive integers for X and Y coordinates.
If (_x >= 0) And (_y >= 0) Then
Return True
Else
Return False
End If
End Function
' Distance from 0 to Point method.
<SqlMethod(OnNullCall:=False)> _
Public Function Distance() As Double
Return DistanceFromXY(0, 0)
End Function
' Distance from Point to the specified point method.
<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 method.
<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
End Structure