Быстрая версия: Что лучше всего из следующего и почему? (или есть способ лучше):
SELECT FLOOR(LOG10(Number))+1 AS NumLength FROM Table
SELECT LEN(CONVERT(VARCHAR, Number)) AS NumLength FROM Table
SELECT LEN(CAST(Number AS VARCHAR(10))) AS NumLength FROM Table
Немного подробнее:
Я хочу определить наиболее эффективный механизм для вычисления длины строкового представления целого числа (точнее натурального числа - всегда> 0) .
Я использую MS SQL Server (2005).
Я придумал 3 решения выше, все из которых работают нормально.
Я знаю, что у третьей версии могут быть проблемы с очень большие целые числа, но пока мы можем предположить, что "Число" никогда не превышает 9 десятичных цифр.
Еще более подробная информация: (вам не нужно читать этот бит, чтобы ответить на мой вопрос)
Этот запрос широко используется в среде обработки транзакций.
До сих пор я придерживался предположения, что «Число» всегда состоит из 6 цифр.
Однако теперь я должен обновить код для поддержки от 4 до 9 цифр.
Этот SQL является частью условия для идентификации схемы карты карты.
Полный запрос пытается найти записи, соответствующие началу номера карты относительно диапазона начала и конца.
Таким образом, полное условие SQL будет примерно таким:
WHERE
-- Start and End match
((Start=End OR End=0) AND (Start=CAST(LEFT('<card number>', FLOOR(LOG10(Start))+1) AS BIGINT))) OR
-- Start != End
-- >= Start
(Start<=CAST(LEFT('<card number>', FLOOR(LOG10(Start))+1) AS BIGINT) AND
-- <= End
End>=CAST(LEFT('<card number>', FLOOR(LOG10(Start))+1) AS BIGINT))
ПРИМЕЧАНИЕ:
Я могу переделать таблицу, чтобы использовать VARCHAR вместо INT. Это позволило бы мне использовать «LEN (Start)» вместо «FLOOR (LOG10 (Start)) + 1)», однако тогда условие будет иметь гораздо больше CAST.
Я бы предпочел продолжить работу с INT, поскольку схема БД останется прежней, и в любом случае работа с INT должна быть быстрее, чем с VARCHAR.
ЕСЛИ я изменю поля на VARCHAR, мое условие может быть таким:
WHERE
-- Start and End match
((Start=End OR LEN(End)=0) AND (Start=LEFT('<card number>', LEN(Start)))) OR
-- Start != End
-- >= Start
(CAST(Start AS BIGINT)<=CAST(LEFT('<card number>', LEN(Start)) AS BIGINT) AND
-- <= End
CAST(End AS BIGINT)>=CAST(LEFT('<card number>', LEN(Start)) AS BIGINT))
Большое спасибо за любую помощь,
Дэйв