Ich habe mehrmals gelesen und gehört, dass sql_variant
vermieden werden sollte. Ich denke, ich habe einen großartigen Anwendungsfall dafür. Ich habe varchar(max)
in der Vergangenheit verwendet, um verschiedene Typen in derselben Spalte zu speichern, aber es scheint sinnvoll, den De- / Serialisierungs-Overhead zu vermeiden, wenn ein eingebauter Typ genau das tut, was ich will.
Also, was genau sind die Fallstricke bei der Verwendung von sql_variant
? Sind sie leistungsbezogen oder leicht zu machen Programmierfehler oder etwas anderes? Übrigens werde ich mit dieser Spalte aus Client-Code und CLR-Funktionen interagieren, wenn das etwas zu beachten ist.
Ich habe sowohl Leistungsprobleme als auch Probleme mit der Codequalität gesehen:
In den meisten Fällen, in denen Sie auf dieses Feld zugreifen, müssen Sie den Typ überprüfen (mit sql_variant_property). Dies macht Ihre Abfragen komplexer, was zu den beiden aufgelisteten Problemen führen kann.
Sie müssen dieses Feld auch jedes Mal neu eingeben, wenn Sie es verwenden, was zu weiteren Leistungseinbußen führt.
Außerdem können sql_variant-Spalten kein Teil eines Primärschlüssels sein, sie funktionieren nicht als Teil einer berechneten Spalte und sie funktionieren nicht mit LIKE in einer WHERE-Klausel.
Es erleichtert auch das Auftreten von Programmierfehlern. Ein DBA / Programmer betrachtet eine Spalte und sieht wie eine Ganzzahl aus, also fügt er eine Ganzzahl ein, aber ein Prozess möchte, dass es weiter unten in der Zeile eine Zeichenkette ist. Ich habe das mit schlecht geschriebenen Importen in sql_variant Spalten gesehen.
Das Speichern von verschiedenen Typen in der gleichen Spalte über SQL_VARIANT
ist fast das Gleiche wie das Umwandeln von alles in Object
in .NET. Und manchmal gibt es berechtigte Gründe für die Verwendung dieses Typs, da es sicherlich eine generische programmatische Struktur ermöglichen kann.
Wie Sie jedoch vorausgesagt haben, gibt es einige Tücken bei der Verwendung von SQL_VARIANT
, die Sie beachten sollten, insbesondere da einer davon ein Deal-Breaker sein könnte:
Genauso wie in% auf Object
(und möglicherweise abhängig vom Basistyp Boxing / Unboxing erforderlich), gibt es einen deutlichen Leistungseinbruch, wenn SQL_VARIANT
verwendet wird. Abhängig vom Anwendungsfall kann es akzeptabel sein, eine reduzierte Leistung zu haben, wenn die Funktionalität dies wirklich benötigt und / oder die Verwendung nicht sehr häufig ist (d. H. Viele Male pro Sekunde).
Im Gegensatz zu dem Konvertieren von Object
in .NET hat der SQL_VARIANT
-Datentyp Einschränkungen hinsichtlich der Basis-Datentypen, die er enthalten kann. Die folgenden Datentypen können nicht als SQL_VARIANT
:
VARCHAR(MAX)
NVARCHAR(MAX)
VARBINARY(MAX)
XML
TIMESTAMP
/ ROWVERSION
TEXT
(Sie sollten diesen Typ sowieso nicht wie in SQL Server 2005 verwenden) NTEXT
(Sie sollten diesen Typ sowieso nicht wie in SQL Server 2005 verwenden) IMAGE
(Sie sollten diesen Typ sowieso nicht wie in SQL Server 2005 verwenden) Diese Einschränkung kann die Verwendung von SQL_VARIANT
leicht verhindern, wenn diese Datentypen gespeichert werden müssen. Bitte beachten Sie, dass das Problem hier der Basis-Datentyp ist und nicht die Größe der Daten, wie der folgende Test zeigt:
Rückkehr:
%Vor% Um fair zu sein, ein Vorteil der Verwendung von SQL_VARIANT
gegenüber dem Umwandeln von alles in NVARCHAR
ist, dass SQL_VARIANT
die zugrunde liegenden Typinformationen beibehält und deren Verwendung erzwingt, so dass Sie Werte in völlig unpassenden Kontexten nicht einfach missbrauchen können.
Rückkehr:
%Vor% Wenn Sie SQL_VARIANT
nicht als PK verwenden können: Dies ist wirklich kein Problem, da die Natur eines generischen Datentyps es für eine solche Verwendung in erster Linie nicht wünschenswert erscheinen lässt.
Wenn Sie SQL_VARIANT
nicht mit einem LIKE
-Operator verwenden können: Dies ist meist kein Problem, da es in einen passenden Typ konvertiert werden kann, der mit LIKE
funktioniert, wie in:
Das Obige ist sicherlich nicht das effizienteste, aber es ist funktional, und wie oben erwähnt, war die Effizienz bereits ausgeschlossen, da es als Gegenleistung für die Funktionalität geopfert wurde, als der SQL_VARIANT
-Datentyp gewählt wurde.
Der einzige offensichtliche Fehler, der Ihnen in den Sinn kommt, ist in Situationen, in denen Sie Werte haben, die Sie in Ihr sql_variant-Feld einfügen möchten, die die maximale Länge überschreiten (8016 Byte pro Webseite: Ссылка ). Wenn sich Ihre Werte nie dieser Grenze nähern, kann sql_variant ein sehr guter Ansatz sein. Andernfalls könnten Sie sql_variant verwenden, aber ein separates "isBlob" -Bitfeld bereitstellen, das auf eine separate Tabelle mit Ihren varbinary (max) -Werten verweist (z. B.).
Tags und Links sql-server sql-server-2005 tsql variant sqlclr