2011-12-12 43 views
1

我需要验证的位数小数点(比例)TSQL如何验证数量的规模

0的权利,在任何地方(十分之一,百分之一,千分之一的有效号码,等等。)。

任何提示或技巧?...没有广泛的正则表达式库,没有内置的函数,我更喜欢一个函数,接受数量,数量的地方,规模应该等于,然后返回一点。

与Maess的建议的后续行动,我想出了这一点:

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 
+0

你尝试过什么?如果你想按代码做代码,那么你应该聘请一名顾问。堆栈溢出是针对特定问题的帮助。 – JNK

+2

将其转换为字符串,在十进制数上解析它,并获取表示小数点右边的数字的字符串的长度。 – Maess

+0

我曾考虑将其转换为字符串,但我希望能找到一些不像黑客那样的东西......这可能是我最终要做的事情,尽管无论如何 – Patrick

回答

-1
CREATE FUNCTION dbo.DecimalPlaces(@n decimal(38,19)) 
RETURNS int 
AS 
BEGIN 
    RETURN FLOOR(LOG10(REVERSE(ABS(@n % 1) + 1))) + 1 
END 

编辑(2月5日'15):

谢谢sqlconsumer。我已在小数点之前包含了您的修补程序。

0

我想安东尼的一些成功的解决方案,但有一些不良的副作用,当第一个全数字是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 

正确的结果