Erstellen benutzerdefinierter Typen: Anforderungen

Gilt für: SQL Server

Sie müssen beim Erstellen eines benutzerdefinierten Typs (USER-Defined Type, UDT) mehrere wichtige Entwurfsentscheidungen treffen, die in Microsoft SQL Server installiert werden sollen. 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 für das Erstellen von UDTs entsprechen, damit sie bei SQL Server registriert werden kann.

Anforderungen für das Implementieren von UDTs

Zur Ausführung in SQL Server muss Ihr UDT die folgenden Anforderungen in der UDT-Definition implementieren:

Der UDT muss microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute angeben. Die Verwendung von "System.SerializableAttribute " ist optional, wird jedoch empfohlen.

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

  • Das UDT muss eine öffentliche statische (oder shared) Parse-Methode enthalten, die die Analyse unterstützt, und eine öffentliche ToString-Methode zum Konvertieren in eine Zeichenfolgendarstellung des Objekts.

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

  • Das UDT muss System.Xml.Serialization.IXmlSerializable implementieren, oder alle öffentlichen Felder und Eigenschaften müssen typen sein, die xml serializierbar oder mit dem XmlIgnore-Attribut versehen werden können, wenn die Außerkraftsetzung der Standard serialisierung erforderlich ist.

  • 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.IsByteOrdered false 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, wie in Datenbankbezeichnern definiert.

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

  • Auf geerbte Member kann von Transact-SQL nicht 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.

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

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

Hinweis

Obwohl sie vom Server nicht zum Ausführen von Vergleichen verwendet wird, können Sie optional die System.IComparable-Schnittstelle implementieren, die eine einzelne Methode, CompareTo, verfügbar macht. 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, mit der SQL Server eine effiziente native Darstellung des UDT auf dem Datenträger speichern kann. Das systemeigene Format wird empfohlen, wenn das 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 obigen Typen bestehen, sind gute Kandidaten für das systemeigene Format, z . B. Strukturen in Visual C#, (oder Strukturen , wie sie in Visual Basic bekannt sind). Beispielsweise kann ein mit dem nativen Serialisierungsformat angegebenes UDT ein Feld eines anderen UDT enthalten, das auch 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.

Das systemeigene Format hat die folgenden Anforderungen:

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

  • Alle Felder müssen serialisierbar sein.

  • Das System.Runtime.InteropServices.StructLayoutAttribute muss als StructLayout.LayoutKindSequential angegeben werden, wenn das 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 ein UDT, das mit der nativen Serialisierung definiert ist, finden Sie unter Point UDT in Coding User-Defined Types.For an example of a UDT defined with Native serialization, see the Point UDT in Coding User-Defined Types.

UserDefined-Serialisierung

Die UserDefined-Formateinstellung für das Attribut "Microsoft.SqlServer.Server.SqlUserDefinedTypeAttribute " ermöglicht dem Entwickler die vollständige Kontrolle über das Binärformat. Wenn Sie die Format-Attributeigenschaft als UserDefined angeben, müssen Sie folgendes in Ihrem Code ausführen:

  • Geben Sie die optionale IsByteOrdered-Attributeigenschaft an. Der Standardwert ist false.

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

  • Schreiben Sie Code zum Implementieren von Lese - und Schreibmethoden für udT, indem Sie die Schnittstelle System.Data.Sql.IBinarySerialize implementieren .

Ein Beispiel für ein UDT, das mit userDefined Serialisierung definiert ist, finden Sie unter Currency UDT in Coding User-Defined Types.For an example of a UDT defined with UserDefined serialization, see the 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 den Speicher für udT angibt. Optional können Sie das serialisierbare Attribut angeben, obwohl SQL Server dies nicht erfordert.

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

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

IsByteOrdered
Ein boolescher Wert, der bestimmt, wie SQL Server binäre Vergleiche im 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. Für ein UDT mit der angegebenen benutzerdefinierten Serialisierung bezieht sich MaxByteSize auf die Gesamtgröße des UDT in seiner serialisierten Form, wie vom Benutzer definiert. Der Wert von MaxByteSize muss sich im Bereich von 1 bis 8000 befinden oder auf -1 festlegen, um anzugeben, dass das UDT größer als 8000 Bytes ist (die Gesamtgröße darf die maximale Lob-Größe nicht überschreiten). Betrachten Sie ein UDT mit einer Eigenschaft 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 Ermittlung des Werts von MaxByteSize die Gesamtgröße des serialisierten UDT berücksichtigt werden: die Größe der in binärer Form serialisierten Daten sowie den Aufwand, der durch die Serialisierung entsteht.

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, garantieren Sie, dass die serialisierten Binärdaten für die semantische Anordnung 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 in den serialisierten Bytes ausgeführt wird, sollten die Ergebnisse identisch sein, als ob derselbe Vergleichsvorgang im verwalteten Code durchgeführt wurde. 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 ORDER BY-, GROUP BY- und PARTITION BY-Klauseln 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. UDTs, die in SQL Server geladen wurden, sind nullfähig. Damit udT jedoch einen Nullwert erkennt, muss die Klasse die INullable-Schnittstelle implementieren. Weitere Informationen und ein Beispiel für die Implementierung der Nullierbarkeit in einem UDT finden Sie unter Codieren von benutzerdefinierten Typen.

Zeichenfolgenkonvertierungen

Um die Zeichenfolgenkonvertierung in und aus dem 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 ein UDT konvertiert werden. Sie muss als statisch (oder in Visual Basic freigegeben ) deklariert werden und einen Parameter vom Typ System.Data.SqlTypes.SqlString verwenden. Weitere Informationen und ein Beispiel für die Implementierung der Parse - und ToString-Methoden finden Sie unter Codieren von benutzerdefinierten Typen.

XML-Serialisierung

UDTs müssen die Konvertierung in den xml-Datentyp unterstützen, indem sie dem Vertrag für die XML-Serialisierung entsprechen. Der System.Xml.Serialization-Namespace enthält Klassen, die zum Serialisieren von Objekten in XML-Formatdokumente oder Datenströme verwendet werden. Sie können die XML-Serialisierung mithilfe der IXmlSerializable-Schnittstelle implementieren, die benutzerdefinierte Formatierung für die XML-Serialisierung und Deserialisierung bereitstellt.

Zusätzlich zum Ausführen expliziter Konvertierungen von UDT in XML ermöglicht ihnen die XML-Serialisierung Folgendes:

  • Verwenden Sie Xquery über 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 benutzerdefinierten Typs