Erstellen benutzerdefinierter Typen: Anforderungen

Gilt für:SQL Server

Sie müssen mehrere wichtige Entwurfsentscheidungen treffen, wenn Sie einen benutzerdefinierten Typ (UDT) erstellen, der in Microsoft SQL Server installiert werden soll. Für die meisten UDTs wird das Erstellen als Struktur empfohlen, obwohl auch das Erstellen als Klasse möglich ist. Die UDT-Definition muss den Spezifikationen zum Erstellen von UDTs entsprechen, damit sie bei SQL Server registriert werden kann.

Anforderungen für das Implementieren von UDTs

Um in SQL Server auszuführen, muss Ihr UDT die folgenden Anforderungen in der UDT-Definition implementieren:

Die UDT muss das Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute angeben. Die Verwendung von System.SerializableAttribute ist optional, wird jedoch empfohlen.

  • Die UDT muss die System.Data.SqlTypes.INullable-Schnittstelle in der Klasse oder Struktur implementieren, indem sie eine öffentliche statischeNull-Methode (Shared in Microsoft Visual Basic) erstellt. SQL Server ist standardmäßig NULL-fähig. Dies ist notwendig für Code, der im UDT ausgeführt wird, um in der Lage zu sein, einen NULL-Wert zu erkennen.

  • Die UDT muss eine öffentliche statische (oder Shared)-Analysemethode enthalten, die die Analyse von unterstützt, und eine öffentliche ToString-Methode für die Konvertierung in eine Zeichenfolgendarstellung des Objekts.

  • Ein UDT mit einem benutzerdefinierten Serialisierungsformat muss die System.Data.IBinarySerialize-Schnittstelle implementieren und eine Read - und eine Write-Methode bereitstellen.

  • Die UDT muss System.Xml implementieren. Serialization.IXmlSerializable oder alle öffentlichen Felder und Eigenschaften müssen von Typen sein, die xml serialisierbar sind oder mit dem XmlIgnore-Attribut versehen sind, wenn die Standardserialisierung überschrieben werden muss.

  • Es darf nur eine Serialisierung eines UDT-Objekts geben. Die Überprüfung schlägt fehl, wenn die Serialisierungs- oder Deserialisierungsroutinen mehr als eine Darstellung eines bestimmten Objekts erkennen.

  • SqlUserDefinedTypeAttribute.IsByteOrdered muss true sein, um Daten in Bytereihenfolge zu vergleichen. Wenn die IComparable-Schnittstelle nicht implementiert ist und SqlUserDefinedTypeAttribute.IsByteOrderedfalse ist, schlagen Bytereihenfolgevergleiche fehl.

  • Ein in einer Klasse definierter UDT muss über einen öffentlichen Konstruktor verfügen, der keine Argumente verwendet. Sie können optional zusätzliche überladene Klassenkonstruktoren erstellen.

  • Der UDT muss Datenelemente als öffentliche Felder oder Eigenschaftenprozeduren verfügbar machen.

  • Öffentliche Namen dürfen nicht länger als 128 Zeichen sein und müssen den SQL Server Benennungsregeln für Bezeichner entsprechen, die in Datenbankbezeichnern definiert sind.

  • sql_variant Spalten dürfen keine Instanzen eines UDT enthalten.

  • Auf geerbte Member kann nicht über Transact-SQL zugegriffen werden, da das SQL Server Typsystem die Vererbungshierarchie zwischen UDTs nicht kennt. Sie können Vererbung allerdings verwenden, wenn Sie Klassen strukturieren, und Sie können diese Methoden in der verwalteten Codeimplementierung des Typs aufrufen.

  • Mit Ausnahme des Klassenkonstruktors können Member nicht überladen werden. Wenn Sie eine überladene Methode erstellen, wird kein Fehler ausgelöst, wenn Sie die Assembly registrieren oder den Typ in SQL Server erstellen. Erkennung der überladenen Methode tritt zur Laufzeit auf, nicht beim Erstellen des Typs. Überladene Methoden können in der Klasse vorhanden sein, solange sie nie aufgerufen werden. Sobald Sie eine überladene Methode aufrufen, wird ein Fehler ausgelöst.

  • Alle statischen (oder freigegebenen) Member müssen als Konstanten oder als schreibgeschützt deklariert werden. Statische Member können nicht änderbar sein.

  • Wenn das Feld SqlUserDefinedTypeAttribute.MaxByteSize auf -1 festgelegt ist, kann die serialisierte UDT so groß sein wie das Größenlimit für große Objekte (lob) (derzeit 2 GB). Die Größe des UDT darf den im Feld MaxByteSized angegebenen Wert nicht überschreiten.

Hinweis

Obwohl sie vom Server nicht zum Durchführen von Vergleichen verwendet wird, können Sie optional die System.IComparable-Schnittstelle implementieren, die eine einzelne Methode verfügbar macht, CompareTo. Diese Methode wird auf Clientseite in Situationen verwendet, in denen UDT-Werte präzise verglichen oder geordnet werden sollen.

Systemeigene Serialisierung

Die Auswahl der richtigen Serialisierungsattribute für den UDT hängt vom Typ des UDTs ab, den Sie erstellen möchten. Das native Serialisierungsformat verwendet eine sehr einfache Struktur, die es SQL Server ermöglicht, eine effiziente native Darstellung der UDT auf dem Datenträger zu speichern. Das native Format wird empfohlen, wenn die UDT einfach ist und nur Felder der folgenden Typen enthält:

bool, byte, sbyte, short, ushort, int, uint, long, ulong, float, double, SqlByte, SqlInt16, SqlInt32, SqlInt64, SqlDateTime, SqlSingle, SqlDouble, SqlMoney, SqlBoolean

Werttypen, die aus Feldern der oben genannten Typen bestehen, sind gute Kandidaten für das native Format, z. B . Strukturen in Visual C# (oder Strukturen , wie sie in Visual Basic bekannt sind). Beispielsweise kann ein udT, der mit dem nativen Serialisierungsformat angegeben wurde, ein Feld eines anderen UDT enthalten, das ebenfalls mit dem nativen Format angegeben wurde. Wenn die UDT-Definition komplexer ist und Datentypen enthält, die nicht in der obigen Liste enthalten sind, müssen Sie stattdessen das Serialisierungsformat UserDefined angeben.

Für das native Format gelten die folgenden Anforderungen:

  • Der Typ darf keinen Wert für Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.MaxByteSize angeben.

  • Alle Felder müssen serialisierbar sein.

  • System.Runtime.InteropServices.StructLayoutAttribute muss als StructLayout.LayoutKindSequential angegeben werden, wenn die UDT in einer Klasse und nicht in einer Struktur definiert ist. Dieses Attribut steuert das physische Layout der Datenfelder und wird verwendet, um zu erzwingen, dass die Elemente in der Reihenfolge angeordnet werden, in der sie erscheinen. SQL Server verwendet dieses Attribut, um die Feldreihenfolge für UDTs mit mehreren Werten zu bestimmen.

Ein Beispiel für eine mit nativer Serialisierung definierte UDT finden Sie unter Point UDT in Coding User-Defined Types.

UserDefined-Serialisierung

Die Einstellung UserDefined-Format für das Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute-Attribut gibt dem Entwickler die vollständige Kontrolle über das Binärformat. Wenn Sie die Eigenschaft Format-Attribut als UserDefined angeben, müssen Sie in Ihrem Code die folgenden Schritte ausführen:

  • Geben Sie die optionale Eigenschaft des IsByteOrdered-Attributs an. Der Standardwert ist false.

  • Geben Sie die MaxByteSize-Eigenschaft von Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute an.

  • Schreiben Sie Code, um Lese- und Schreibmethoden für die UDT zu implementieren, indem Sie die System.Data.Sql.IBinarySerialize-Schnittstelle implementieren.

Ein Beispiel für eine udT, die mit userDefined-Serialisierung definiert ist , finden Sie unter Currency UDT in Coding User-Defined Types.

Hinweis

Für UDT-Felder muss die systemeigene Serialisierung verwendet werden, oder die Felder müssen erhalten bleiben, um indiziert zu werden.

Serialisierungsattribute

Attribute bestimmen, wie die Serialisierung verwendet wird, um die Speicherdarstellung von UDTs zu erstellen und um UDTs durch Werte an den Client zu übertragen. Sie müssen beim Erstellen des UDT das Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute angeben. Das Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute-Attribut gibt an, dass die Klasse ein UDT ist, und gibt den Speicher für die UDT an. Sie können optional das Serializable-Attribut angeben, obwohl SQL Server dies nicht erfordert.

Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute verfügt über die folgenden Eigenschaften.

Format
Gibt das Serialisierungsformat an, das je nach Datentypen des UDT nativ oder UserDefined sein kann.

IsByteOrdered
Ein boolescher Wert, der bestimmt, wie SQL Server Binärvergleiche auf dem UDT durchführt.

IsFixedLength
Gibt an, ob alle Instanzen dieses UDTs dieselbe Länge haben.

MaxByteSize
Die maximale Größe der Instanz in Byte. Sie müssen MaxByteSize mit dem Serialisierungsformat UserDefined angeben. Bei einer UDT mit angegebener benutzerdefinierter Serialisierung bezieht sich MaxByteSize auf die Gesamtgröße des UDT in seiner serialisierten Form, wie vom Benutzer definiert. Der Wert von MaxByteSize muss im Bereich von 1 bis 8000 liegen oder auf -1 festgelegt sein, um anzugeben, dass der UDT größer als 8000 Bytes ist (die Gesamtgröße darf die maximale LOB-Größe nicht überschreiten). Betrachten Sie eine UDT mit einer Eigenschaft einer Zeichenfolge von 10 Zeichen (System.Char). Wenn der UDT anhand eines BinaryWriter serialisiert wird, beträgt die Gesamtgröße der serialisierten Zeichenfolge 22 Byte: 2 Byte pro Unicode-UTF-16-Zeichen, multipliziert mit der maximalen Anzahl von Zeichen, plus 2 Kontrollzeichen, die beim Serialisieren eines binären Datenstroms zusätzlich anfallen. Daher muss bei der Bestimmung des Werts von MaxByteSize die Gesamtgröße des serialisierten UDT berücksichtigt werden: die Größe der in binärer Form serialisierten Daten plus der durch die Serialisierung verursachten Mehraufwand.

ValidationMethodName
Der Name der Methode, mit der Instanzen des UDTs überprüft werden.

Einstellung 'IsByteOrdered'

Wenn die Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute.IsByteOrdered-Eigenschaft auf true festgelegt ist, stellen Sie tatsächlich sicher, dass die serialisierten Binärdaten für die semantische Reihenfolge der Informationen verwendet werden können. So kann jede Instanz eines UDT-Objekts mit Bytereihenfolge nur eine einzige serialisierte Darstellung haben. Wenn ein Vergleichsvorgang in SQL Server für die serialisierten Bytes ausgeführt wird, sollten die Ergebnisse identisch sein, als ob derselbe Vergleichsvorgang in verwaltetem Code stattgefunden hätte. Die folgenden Features werden auch unterstützt, wenn IsByteOrdered auf true festgelegt ist:

  • Die Fähigkeit zum Erstellen von Indizes für Spalten dieses Typs

  • Die Fähigkeit, für Spalten dieses Typs Primär- und Fremdschlüssel sowie die Einschränkungen CHECK und UNIQUE zu erstellen

  • Die Möglichkeit, Transact-SQL-Klauseln ORDER BY, GROUP BY und PARTITION BY zu verwenden. In diesen Fällen wird die binäre Darstellung des Typs verwendet, um die Reihenfolge zu bestimmen

  • Die Möglichkeit, Vergleichsoperatoren in Transact-SQL-Anweisungen zu verwenden.

  • Die Fähigkeit, berechnete Spalten dieses Typs persistent zu speichern

Beachten Sie, dass sowohl das Native - als auch das UserDefined-Serialisierungsformat die folgenden Vergleichsoperatoren unterstützen, wenn IsByteOrdered auf true festgelegt ist:

  • Gleich (=)

  • Ungleich (!=)

  • Größer als (>)

  • Kleiner als (<)

  • Größer als oder gleich (>=)

  • Kleiner als oder gleich (<=)

Implementieren von NULL-Zulässigkeit

Zusätzlich zum ordnungsgemäßen Angeben der Attribute für die Assemblys muss die Klasse auch NULL-Zulässigkeit unterstützen. In SQL Server geladene UDTs sind NULL-fähig. Damit der UDT jedoch einen NULL-Wert erkennt, muss die Klasse die INullable-Schnittstelle implementieren. Weitere Informationen und ein Beispiel für die Implementierung der NULL-Zulässigkeit in einem UDT finden Sie unter Codieren User-Defined Typen.

Zeichenfolgenkonvertierungen

Um die Zeichenfolgenkonvertierung in und aus udT zu unterstützen, müssen Sie eine Parse-Methode und eine ToString-Methode in Ihrer Klasse bereitstellen. Mit der Parse-Methode kann eine Zeichenfolge in eine UDT konvertiert werden. Sie muss als statisch (oder in Visual Basic freigegeben ) deklariert werden und einen Parameter vom Typ System.Data.SqlTypes.SqlString annehmen. Weitere Informationen und ein Beispiel für die Implementierung der Methoden Parse und ToString finden Sie unter Codieren User-Defined Typen.

XML-Serialisierung

UDTs müssen die Konvertierung in und aus dem xml-Datentyp unterstützen, indem sie dem Vertrag für die XML-Serialisierung entsprechen. Die System.Xml. Der Serialisierungsnamespace enthält Klassen, die zum Serialisieren von Objekten in Dokumente oder Streams im XML-Format verwendet werden. Sie können die XML-Serialisierung mithilfe der IXmlSerializable-Schnittstelle implementieren, die benutzerdefinierte Formatierung für die XML-Serialisierung und -Deserialisierung bereitstellt.

Neben expliziten Konvertierungen von UDT in XML ermöglicht die XML-Serialisierung Folgendes:

  • Verwenden Sie Xquery für Werte von UDT-Instanzen nach der Konvertierung in den xml-Datentyp .

  • Verwenden Sie UDTs in parametrisierten Abfragen und Webmethoden mit nativen XML-Webdiensten in SQL Server.

  • Verwenden von UDTs, um ein Massenladen von XML-Daten durchzuführen.

  • Serialisieren von DataSets, die Tabellen mit UDT-Spalten enthalten.

UDTs werden nicht in FOR XML-Abfragen serialisiert. Um eine FOR XML-Abfrage auszuführen, die die XML-Serialisierung von UDTs anzeigt, konvertieren Sie jede UDT-Spalte explizit in den xml-Datentyp in der SELECT-Anweisung. Sie können die Spalten auch explizit in varbinary, varchar oder nvarchar konvertieren.

Weitere Informationen

Erstellen eines User-Defined-Typs