Funkcja CHARINDEX zwraca pozycję pierwszego wystąpienia poszukiwanego ciągu znaków wewnątrz podanego tekstu.
CHARINDEX w języku Transact-SQL
CHARINDEX jest funkcją języka Transact-SQL używanego w Microsoft SQL Server. Służy do wyszukania pierwszego wystąpienia określonego ciągu znaków w innym ciągu. Jej podstawowa składnia ma postać CHARINDEX(expressionToFind, expressionToSearch [, start_location]). Pierwszy argument określa szukany tekst, drugi zawiera tekst, w którym ma zostać wykonane wyszukiwanie, a opcjonalny trzeci wskazuje pozycję, od której SQL Server powinien rozpocząć sprawdzanie znaków.
Pozycje znaków zwracane przez tę funkcję są numerowane od 1, a nie od 0. Dla przykładu wyrażenie CHARINDEX('SQL', 'Microsoft SQL Server') zwróci pozycję, na której zaczyna się pierwszy znak ciągu SQL. Jeżeli szukany fragment nie zostanie znaleziony, funkcja zwraca wartość 0. Nie należy mylić tej wartości z wartością NULL: zero oznacza prawidłowo wykonane wyszukiwanie bez dopasowania, natomiast NULL może oznaczać brak danych wejściowych.
Argumenty, pozycja startowa i typ wyniku
Argument start_location pozwala pominąć początkową część tekstu. Wartość 1 oznacza rozpoczęcie od pierwszego znaku, wartość 5 — od znaku numer 5. W praktyce można użyć wyniku pierwszego wyszukania do znalezienia kolejnego wystąpienia, przekazując jako pozycję startową wynik powiększony o długość znalezionego fragmentu. Jeżeli wartość początkowa jest równa 0 albo jest ujemna, SQL Server rozpoczyna wyszukiwanie od początku przeszukiwanego wyrażenia.
Wynik ma zwykle typ int. Jeżeli przeszukiwane wyrażenie ma typ varchar(max), nvarchar(max) albo varbinary(max), wynik ma typ bigint. Ma to znaczenie przy przypisywaniu rezultatu do zmiennej lub kolumny, szczególnie gdy kod obsługuje bardzo długie wartości. Szukany argument nie może przekraczać 8000 znaków. Funkcja nie przyjmuje również jako argumentów typów text, ntext ani image w miejscach, w których SQL Server ich nie obsługuje dla tego mechanizmu.
Wpływ sortowania i różnica między CHARINDEX a PATINDEX
CHARINDEX korzysta z reguł sortowania, czyli kolacji, obowiązujących dla porównywanych wyrażeń. W kolacji niewrażliwej na wielkość liter wyszukanie 'abc' może znaleźć także 'ABC'. W kolacji wrażliwej na wielkość liter te wartości są rozróżniane. Zachowanie można ustalić jawnie, stosując klauzulę COLLATE, na przykład CHARINDEX('abc', tekst COLLATE Latin1_General_100_BIN2). Dobór kolacji powinien odpowiadać wymaganiom danych, ponieważ zmienia on wynik porównania.
Funkcja wyszukuje zwykły ciąg znaków i nie interpretuje go jako wzorca z symbolami wieloznacznymi. Jeżeli potrzebne jest wyszukiwanie według wzorca, w Transact-SQL służy do tego między innymi PATINDEX. Z kolei do prostego sprawdzenia obecności fragmentu można użyć warunku CHARINDEX('fragment', kolumna) > 0. Gdy którykolwiek z argumentów tekstowych ma wartość NULL, wynik także jest równy NULL. Wartość CHAR(0), czyli znak o kodzie zero, nie może być używana w tym wyszukiwaniu w kolacjach systemu Windows.
Praktyczne użycie przy analizie danych w SQL Server
CHARINDEX jest przydatny podczas filtrowania rekordów zawierających określony fragment, rozdzielania prostych formatów tekstowych oraz ustalania miejsca wystąpienia separatora. Przykładowo warunek WHERE CHARINDEX('@', adres_email) > 0 wybierze wiersze, w których znajduje się znak @, ale sam w sobie nie potwierdzi poprawności całego adresu. Do pobrania części tekstu można połączyć CHARINDEX z funkcjami LEFT, SUBSTRING lub RIGHT. Należy wcześniej obsłużyć przypadek wyniku 0, aby nie obliczać zakresu na podstawie nieistniejącego separatora.
Wydajność zależy od sposobu użycia funkcji. Warunek z CHARINDEX zastosowany bezpośrednio do kolumny często wymaga sprawdzenia wartości w wielu wierszach i nie daje takiej samej możliwości wykorzystania indeksu jak proste porównanie kolumny. Przy dużych tabelach warto rozważyć kolumnę obliczaną, odpowiedni indeks, pełnotekstowe wyszukiwanie albo zmianę sposobu przechowywania danych, zależnie od celu zapytania. Podczas diagnostyki zapytań SQL Server należy sprawdzić typy argumentów, kolację, obecność wartości NULL oraz to, czy kod prawidłowo rozróżnia wynik 0 od braku danych.