tsql, как проверить шкалу числа - PullRequest
1 голос
/ 12 декабря 2011

Мне нужно проверить количество цифр справа от десятичной дроби (шкала)

0, это допустимое число в любом месте (десятые, сотые, тысячные и т. Д.).

Какие-нибудь советы или хитрости? ... без обширной библиотеки регулярных выражений и без встроенной функции, я бы предпочел функцию, которая принимает число, количество мест, которое должен равняться шкале, а затем возвращаетбит.

Следуя предложению Мейсс, я придумал следующее:

CREATE FUNCTION [dbo].[GetScale] 
(
    @tsValue varchar(250)
    , @tiScale int
)
RETURNS int
AS
BEGIN
    DECLARE
        @tiResult int
        , @tiValueScale int
        SET @tiResult = 0
        SELECT @tiValueScale =  LEN( SUBSTRING ( @tsValue, PATINDEX('%.%', @tsValue) + 1, LEN(@tsValue) ) )
        IF (@tiValueScale = @tiScale)
            SET @tiResult = 1
    RETURN @tiResult
END
GO

Кажется, работает как нужно.Спасибо за помощь.

Так же, как продолжение ... я столкнулся с проблемой, когда число не имеет десятичной дроби (которая возвращает patindex в 0), и число было того же размера, что и масштаб, оновернул бы ложное срабатывание ... поэтому я добавляю дополнительный выбор из patindex, чтобы определить, существует он или нет ... теперь это выглядит так:

- =============================================
ALTER FUNCTION [dbo].[GetScale] 
(
    @tsValue varchar(250)
    , @tiScale int
)
RETURNS int
AS
BEGIN
    DECLARE
        @tiResult int
        , @tiValueScale int
        , @tiDecimalExists int

        SET @tiResult = 0
        SET @tiDecimalExists = 0

        SELECT @tiDecimalExists = PATINDEX('%.%', @tsValue)

        IF (@tiDecimalExists != 0)
        BEGIN
            SELECT @tiValueScale =  LEN( SUBSTRING ( @tsValue, @tiDecimalExists + 1, LEN(@tsValue) ) )
            IF (@tiValueScale = @tiScale)
                SET @tiResult = 1

        END
    RETURN @tiResult
END

Ответы [ 2 ]

0 голосов
/ 31 мая 2013

Я попробовал решение Энтони с некоторым успехом, но есть некоторые нежелательные побочные эффекты, когда первое целое число равно 9.

Например ...

   select 0.11 as fraction, Math.NumberOfDecimalPlaces(0.11) dp union
   select 9.1, Math.NumberOfDecimalPlaces(9.1) union
   select 9.01, Math.NumberOfDecimalPlaces(9.01) union
   select 9.0, Math.NumberOfDecimalPlaces(9.0) union
   select 99.0, Math.NumberOfDecimalPlaces(99.0) union
   select 10999.0, Math.NumberOfDecimalPlaces(10999.0) union
   select 8.0, Math.NumberOfDecimalPlaces(8.0) union
   select 0, Math.NumberOfDecimalPlaces(0)

Производит ...

0.00    0
0.11    2
8.00    0
9.00    -1
9.01    2
9.10    1
99.00   -2
10999.00    -3

Что показывает некоторые неправильные вычисления, когда 9 - это первое целое число.

Я немного улучшил первоначальную функцию Энтони.

CREATE FUNCTION [Math].[NumberOfDecimalPlaces]
(
    @fraction decimal(38,19)
)
RETURNS INT
AS
BEGIN
    RETURN FLOOR(LOG10(REVERSE(ABS(@fraction % 1) +1))) +1
END

Этопросто полоски целой части дроби.Который при реализации выдает ...

0.00    0
0.11    2
8.00    0
9.00    0
9.01    2
9.10    1
99.00   0
10999.00    0

Правильный результат

0 голосов
/ 19 марта 2012
CREATE FUNCTION dbo.DecimalPlaces(@n decimal(38,19))
RETURNS int
AS
BEGIN
    RETURN FLOOR(LOG10(REVERSE(ABS(@n % 1) + 1))) + 1
END

Редактировать (5 февраля '15):

Спасибо sqlconsumer .Я включил ваше исправление для девятки до десятичной точки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...