Typ SQL_Variant w SQL Server

Ciekawym typem wbudowanym w SQL Server jest SQL_VARIANT. Pozwala on na przechowywanie wartości o różnym typie danych w ramach pojedynczej kolumny czy też zmiennej. W ramach niniejszego artykułu postaram się przybliżyć ten typ danych i wskazać zarówno jego wad jak i zalet.

Gdy zdefiniujemy zmienną typu SQL_Variant to może ona przechowywać np. wartości CHAR, DECIMAL i DATE jednocześnie przy zachowaniu właściwości specyficznych dla danego typu. Zobrazujmy to na przykładzie. Na samym początku stwórzmy sobie testową bazę danych na której będziemy wykonywać przykłady – w niniejszym artykule możemy użyć domyślnych wartości przy tworzeniu bazy danych, nie będą one aż tak istotne:

Następnie stwórzmy tabelę, która będzie zawierała kolumnę typu SQL_VARIANT:

Teraz możemy wstawić do nowo powstałej tabeli wartości różnych typów – kolejno: datetime, smallint, decimal, varchar, nvarchar:

Zapytanie zakończyło się sukcesem, mamy również pewność, że w tym momencie nie zaszła żadna niejawna konwersja ponieważ powyższe typy nie są pomiędzy sobą kompatybilne. Sprawdźmy używając funkcji DATALENGTH ile bajtów zajmują wartości które wstawiliśmy:

Jak widać każda z wartości odpowiada rozmiarem swojej bazowej jednostce, można ten fakt sprawdzić używając dokumentacji jednak Microsoft stworzył ku temu specjalną funkcję, która poda nam te informacje wprost – chodzi mianowicie o funkcję SQL_VARIANT_PROPERTY.  Funkcja ta pozwala nam odczytać kilka interesujących własności pola z typem SQL_VARIANT. Na pierwszy rzut sprawdźmy bazowe typy danych dla kolejnych wartości- służy ku temu parametr BASE_TYPE:

Jak widać na poniższym zrzucie ekranowym typy danych zgadzają się z tym co chcieliśmy osiągnąć wstawiając kolejne wiersze:

Oprócz typu bazowego możemy użyć innych parametrów tejże funkcji tj.:

  • Precision – czyli liczba znaków dla typów numerycznych
  • Scale – czyli liczba znaków po przecinku dla typów numerycznych
  • TotalBytes – liczba bajtów potrzebna do zapisania konkretnej wartości oraz jej metadanych
  • Collation – kolacja konkretnej wartości
  • MaxLength – maksymalna długość typu danych

Jak można zauważyć opisywany typ danych daje nam bardzo wiele możliwości i jest niesamowicie elastyczny.  Jednakże z typem tym wiąże się bardzo wiele wad np. to, że dane w tym typie nie mogą być większe niż 8016 bajtów (dane +metadane) tak więc nie ma możliwości przechowywania tam długich typów jak np. varchar(max)., varbinary(max) itd

Największą wadą tego typu jest jednak to, że sterowniki ODBC i OLEDB nie w pełni wspierają ten typ. Oznacza to, że używając tego typu dane będą zwracane przez sterownik jako dane binarne.

Oczywiście możliwe jest wykonywanie funkcji języka TSQL natomiast warto zawsze wybierać tylko te wiersze, które są odpowiednie dla danej funkcji. Ponadto wiersze, które chcemy użyć jako parametr muszą zostać przekonwertowane na odpowiedni dla danej funkcji typ danych. Dla przykładu użyjemy funkcji SUM tylko dla typów

Jak widać używanie SQL_VARIANT jest stosunkowo proste, co prawda umożliwia zaprojektowanie bardzo ciekawego rozwiązania, lecz należy pamiętać aby go używać tylko w określonych przypadkach. Użycie tego typu wiąże się z dużym narzutem przez co wydajność całego rozwiązania może ucierpieć.

Adrian Chodkowski
Follow me

Adrian Chodkowski

SQL geek, Data enthusiast, Consultant & Developer
Adrian Chodkowski
Follow me

Latest posts by Adrian Chodkowski (see all)

2 Comments

  1. Piotr Ziuziański

    Warto wspomnieć, że typ ten nie jest obsługiwany przez tablediff przy porównywaniu dwóch tabel. PS. Niestety, ale nie widać zrzutów 🙁

    Reply
    1. Adrian ChodkowskiAdrian Chodkowski (Post author)

      Ten typ jest niestety ogólnie rzecz biorąc niewspierany przez większość mechanizmów. Zrzuty już są widoczne:)

      Reply

Leave a Comment

Your email address will not be published. Required fields are marked *