Есть проблемы с двумя наиболее популярными ответами. Ответ с рекомендацией DATALENGTH
подвержен ошибкам программиста. Результат DATALENGTH
должен быть разделен на 2 для NVARCHAR
типов, но не для VARCHAR
типов. Это требует знания типа, длина которого вы получаете, и если этот тип меняется, вы должны старательно менять места, которые вы использовали DATALENGTH
.
Существует также проблема с ответом, получившим наибольшее количество голосов (который, я признаю, был моим предпочтительным способом сделать это, пока эта проблема не укусила меня). Если значение, которое вы получаете, имеет тип NVARCHAR(4000)
и фактически содержит строку из 4000 символов, SQL будет игнорировать добавленный символ, а не неявно приводить результат к NVARCHAR(MAX)
. Конечный результат - неправильная длина. То же самое произойдет с VARCHAR (8000).
То, что я нашел, работает почти так же быстро, как обычный LEN
, быстрее, чем LEN(@s + 'x') - 1
для больших строк, и не предполагает, что нижележащая ширина символа следующая:
DATALENGTH(@s) / DATALENGTH(LEFT(LEFT(@s, 1) + 'x', 1))
Получается длина данных, а затем делится на длину данных одного символа из строки. Добавление 'x' охватывает случай, когда строка пуста (что в этом случае даст деление на ноль). Это работает независимо от того, является ли @s
VARCHAR
или NVARCHAR
. Выполнение LEFT
из 1 символа перед добавлением бреет некоторое время, когда строка большая. Однако проблема в том, что он некорректно работает со строками, содержащими суррогатные пары.
В комментарии к принятому ответу упоминается другой способ, использующий REPLACE(@s,' ','x')
. Этот метод дает правильный ответ, но на пару порядков медленнее, чем другие методы при большой длине строки.
Учитывая проблемы, создаваемые суррогатными парами для любой техники, использующей DATALENGTH
, я думаю, что самый безопасный метод, который дает правильные ответы, о которых я знаю, заключается в следующем:
LEN(CONVERT(NVARCHAR(MAX), @s) + 'x') - 1
Это быстрее, чем REPLACE
техника, и намного быстрее с более длинными строками. По сути, это техника LEN(@s + 'x') - 1
, но с защитой для краевого случая, когда строка имеет длину 4000 (для nvarchar) или 8000 (для varchar), так что правильный ответ дается даже для этого. Он также должен правильно обрабатывать строки с суррогатными парами.