Len() против datalength() в SQL Server 2005
-
18-09-2019 - |
Вопрос
Недавно я столкнулся с проблемой при использовании len()
в запросе, чтобы узнать длину запроса, len()
не учитывал конечные пробелы в значении.Но datalength()
также подсчитывает конечные пробелы.
Означает ли это, что если я выполняю какую-то операцию, которая имеет дело с фактической длиной значения, то я должен использовать dalalength()
закончился len()
.
бывший:Если мне нужно, чтобы значение определенного значения было длиной в 10 символов.т. е.Если значение имеет длину в 3 символа, я должен добавить к нему 7 пробелов.
Решение
Да, это именно то, что вы должны сделать.Если вы хотите просто получить количество символов, исключая пробелы, вы бы использовали LEN()
функции, в то время как во всех других случаях DATALENGTH()
.
Даже LEN()
в документации есть информация о том, что для получения количества байтов для представления расширения вы должны использовать DATALENGTH()
Вот ссылки на документы MSDN:
Другие советы
Будь осторожен. ДЛИНА ДАННЫХ возвращает количество используемых байт, а не количество символов.
len подсчитывает количество используемых символов, а не требуемое хранилище, это будет еще более очевидно, когда вы используете nvarchar вместо varchar
len также не учитывает конечные пробелы
взгляните на это
declare @v nchar(5)
select @v ='ABC '
select len(@v),datalength(@v)
и выходные данные для len равны 3, в то время как выходные данные для datalength = 10
Просто используйте Replace():
SELECT LEN(REPLACE(N'4 Trailing Spaces: ', ' ', '_'))
Это заменит пробелы в конце символом, который LEN() действительно будет учитывать.
Проблема с DataLength() заключается в том, что вам нужно отслеживать, является ли ваша строка Unicode (nChar, nVarChar) или ASCII (Char, VarChar), чтобы знать, нужно ли вам также разделить длину данных строки Unicode на 2.
Я собирался использовать Len(Replace('бла-бла-бла',' ','_') предложение, когда мне пришло в голову, что это может быть более эффективным в использовании.Просто публикую на случай, если кто-то наткнется на эту тему, как это сделал я.
len('бла-бла -бла ' + '.')-1
К сожалению, идеального решения, о котором я знаю, не существует.
Одно из предложенных решений, LEN(string + '.')-1
возвращает неправильные результаты (-1), если строка является Unicode размером 4000 или не-Unicode и имеет размер 8000.Это происходит потому, что конкатенация игнорируется.Вы можете преодолеть это, если хотите, приведя строку к строке МАКСИМАЛЬНОГО размера: LEN(CAST(string as nvarchar(max)) + '.')-1
, но стоит ли оно того?
Как упоминалось другими, DATALENGTH(string)
возвращает количество байт, используемых для хранения.Для строк в Юникоде может быть недостаточно разделить результат на 2: Суррогатные символы Юникода может занимать более 16 бит.
В общем, помните об ограничениях каждого подхода и выбирайте то, что, по вашему мнению, вызовет у вас меньше проблем.