Przestarzałe typy danych, jak TEXT czy NTEXT, warto zastępować odpowiednikami VARCHAR(MAX) i NVARCHAR(MAX).
TEXT i NTEXT w SQL Server: co oznacza przestarzałość tych typów
W Microsoft SQL Server typy danych text i ntext są oznaczone jako przestarzałe, czyli pozostają obsługiwane głównie dla zgodności ze starszymi aplikacjami, ale nie powinny być wybierane przy projektowaniu nowych tabel. text przechowuje dane znakowe bez obsługi Unicode, natomiast ntext służy do przechowywania znaków Unicode. Ich zastosowanie może utrudniać rozwój schematu, ponieważ nowsze funkcje języka T-SQL oraz biblioteki klienckie są projektowane przede wszystkim z myślą o typach varchar(max) i nvarchar(max).
Przestarzałość nie oznacza, że każda kolumna tego rodzaju natychmiast powoduje awarię. Istniejące dane nadal mogą być odczytywane, a starsze programy mogą poprawnie korzystać z takich tabel. Problem pojawia się wtedy, gdy kod próbuje wykonywać typowe operacje tekstowe, takie jak łączenie wartości, porównywanie, sortowanie lub przekazywanie parametrów do funkcji. W przypadku text i ntext część operacji wymaga jawnej konwersji albo użycia starszych mechanizmów, co zwiększa złożoność zapytań i ryzyko niezgodności po aktualizacji aplikacji.
Dlaczego varchar(max) i nvarchar(max) są właściwymi zamiennikami
Współczesnym odpowiednikiem typu text jest zazwyczaj varchar(max), a odpowiednikiem ntext — nvarchar(max). Słowo max oznacza, że kolumna może przechowywać bardzo długi tekst, bez ograniczenia właściwego dla zwykłych deklaracji varchar(n) lub nvarchar(n). nvarchar(max) należy wybrać wtedy, gdy dane mogą zawierać znaki spoza podstawowego zestawu znaków używanego przez daną kolację, na przykład polskie litery, znaki cyrylicy, alfabet grecki lub symbole z innych systemów pisma.
Różnica między typami nie sprowadza się wyłącznie do nazwy. varchar(max) przechowuje znaki w kodowaniu zależnym od kolacji i ustawień SQL Server, natomiast nvarchar(max) korzysta z reprezentacji Unicode. Zmiana z ntext na varchar(max) może więc spowodować utratę znaków, których docelowe kodowanie nie reprezentuje. Przy migracji treści wielojęzycznych bezpieczniejszym wyborem jest zwykle nvarchar(max). Jeżeli zawartość jest ograniczona do określonego zestawu znaków i schemat świadomie używa typu nieunikodowego, można zastosować varchar(max).
Migracja kolumny bez uszkodzenia treści i logiki zapytań
Zmianę typu należy poprzedzić sprawdzeniem definicji tabeli, zależności, procedur składowanych, widoków, wyzwalaczy oraz kodu aplikacji. Istotne jest ustalenie, czy kolumna zawiera wartości NULL, czy aplikacja rozróżnia pusty tekst od wartości NULL oraz czy istnieją indeksy, ograniczenia lub mechanizmy wyszukiwania zależne od tej kolumny. Przykładowa operacja dla kolumny może mieć postać ALTER TABLE dbo.Dokumenty ALTER COLUMN Tresc nvarchar(max) NULL;, ale dokładna deklaracja NULL albo NOT NULL musi odpowiadać obecnym wymaganiom schematu.
Przed wykonaniem zmiany warto utworzyć kopię zapasową i przetestować migrację na kopii bazy zawierającej rzeczywiste rozmiary oraz różnorodność danych. Należy zweryfikować długość tekstów przed i po konwersji, w szczególności znaki narodowe, znaki końca wiersza, tabulatory i potencjalnie bardzo długie wartości. Samo polecenie CAST lub CONVERT nie naprawia błędów w kodzie aplikacji, który nadal deklaruje parametr jako stary typ. Po zmianie trzeba sprawdzić parametry zapytań, mapowanie typów w sterowniku oraz procedury używające operacji takich jak SUBSTRING, LIKE, CHARINDEX i konkatenacja.
Skutki pozostawienia starych typów w działającej bazie
Pozostawienie text lub ntext może prowadzić do błędów wynikających z niejawnych konwersji. SQL Server ma określoną hierarchię pierwszeństwa typów danych, dlatego połączenie wartości o różnych typach może wymusić konwersję całego wyrażenia do typu nieoczekiwanego przez autora zapytania. W praktyce może to zmienić sposób porównywania wartości, powodować odrzucenie instrukcji albo wymagać ręcznego rzutowania. Dodatkowym problemem jest konieczność utrzymywania starszych fragmentów kodu, mimo że pozostała część aplikacji korzysta już z typów varchar(max) i nvarchar(max).
Po migracji trzeba również sprawdzić wydajność zapytań. Kolumna typu max nadal jest przeznaczona do dużych wartości, więc nie każda operacja na niej będzie tania, a pełne wyszukiwanie treści może wymagać odpowiednio zaprojektowanego indeksu pełnotekstowego zamiast zwykłego indeksu B-tree. Sama zamiana typu nie gwarantuje poprawy szybkości; jej celem jest przede wszystkim zgodność ze wspieranym modelem danych SQL Server, prostsza obsługa w T-SQL i ograniczenie zależności od funkcji oznaczonych jako przestarzałe. Przy diagnozowaniu problemów należy porównać definicję kolumny, plan zapytania, konwersje typów oraz sposób przekazywania danych przez aplikację.