Wystąpiły problemy z dwoma najczęściej głosowanymi odpowiedziami. Polecająca odpowiedź DATALENGTH
jest podatna na błędy programisty. Wynik DATALENGTH
należy podzielić przez 2 dla NVARCHAR
typów, ale nie dla VARCHAR
typów. Wymaga to znajomości typu, którego długość otrzymujesz, a jeśli ten typ się zmieni, musisz pilnie zmieniać miejsca, z których korzystałeś DATALENGTH
.
Jest też problem z najbardziej pozytywną odpowiedzią (przyznaję, że był to mój ulubiony sposób, dopóki ten problem mnie nie ugryzł). Jeśli rzecz, której otrzymujesz długość, jest typu NVARCHAR(4000)
i faktycznie zawiera ciąg 4000 znaków, SQL zignoruje dołączony znak, zamiast niejawnie rzutować wynik na NVARCHAR(MAX)
. Wynik końcowy to nieprawidłowa długość. To samo stanie się z VARCHAR (8000).
To, co znalazłem, działa, jest prawie tak szybkie, jak zwykłe stare LEN
, jest szybsze niż w LEN(@s + 'x') - 1
przypadku dużych ciągów i nie zakłada, że podstawowa szerokość znaku jest następująca:
DATALENGTH(@s) / DATALENGTH(LEFT(LEFT(@s, 1) + 'x', 1))
Pobiera długość danych, a następnie dzieli przez długość danych pojedynczego znaku z ciągu. Dodanie „x” obejmuje przypadek, w którym ciąg jest pusty (co w tym przypadku dałoby podzielenie przez zero). Działa @s
to niezależnie od tego, czy jest, VARCHAR
czy NVARCHAR
. Wykonanie LEFT
1 znaku przed dołączeniem pozwala zaoszczędzić trochę czasu, gdy ciąg jest duży. Problem z tym polega jednak na tym, że nie działa poprawnie z łańcuchami zawierającymi pary zastępcze.
W komentarzu do zaakceptowanej odpowiedzi wspomniano o innym sposobie użycia REPLACE(@s,' ','x')
. Ta technika daje poprawną odpowiedź, ale jest o kilka rzędów wielkości wolniejsza niż inne techniki, gdy struna jest duża.
Biorąc pod uwagę problemy wprowadzone przez pary zastępcze w dowolnej używanej technice DATALENGTH
, myślę, że najbezpieczniejsza metoda, która daje prawidłowe odpowiedzi, to:
LEN(CONVERT(NVARCHAR(MAX), @s) + 'x') - 1
Jest to szybsze niż REPLACE
technika i znacznie szybsze w przypadku dłuższych strun. Zasadniczo ta technika jest LEN(@s + 'x') - 1
techniką, ale z ochroną dla przypadku krawędzi, w którym łańcuch ma długość 4000 (dla nvarchar) lub 8000 (dla varchar), więc nawet w tym przypadku podano poprawną odpowiedź. Powinien również poprawnie obsługiwać łańcuchy z parami zastępczymi.