Длина целого числа в SQL (т.е. длина десятичной строки)

Быстрая версия: Что лучше всего из следующего и почему? (или есть способ лучше):

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))

Большое спасибо за любую помощь,
Дэйв

9
задан marc_s 21 March 2011 в 13:10
поделиться