5

我必须在 MS Sql Server 托管的数据库中计算小数点后的数字(2005 或 2008 无关紧要),以纠正用户犯的一些错误。我在 Oracle 数据库上遇到了同样的问题,但事情没有那么复杂。底线在 Oracle 上,选择是:

select length( substr(to_char(MY_FIELD), instr(to_char(MY_FILED),'.',1,1)+1, length(to_char(MY_FILED)))) as digits_length
from MY_TABLE

其中提交的 My_filed 是 float(38)。

在 Ms Sql 服务器上,我尝试使用:

select LEN(SUBSTRING(CAST(MY_FIELD AS VARCHAR), CHARINDEX('.',CAST(MY_FILED AS VARCHAR),1)+1, LEN(CAST(MY_FIELD AS VARCHAR)))) as digits_length
from MY_TABLE

问题是在 MS Sql Server 上,当我将 MY_FIELD 转换为 varchar 时,浮点数仅被 2 位小数截断,并且数字的计数是错误的。有人可以给我任何提示吗?

最好的祝福。

4

4 回答 4

8
SELECT 
LEN(CAST(REVERSE(SUBSTRING(STR(MY_FIELD, 13, 11), CHARINDEX('.', STR(MY_FIELD, 13, 11)) + 1, 20)) AS decimal)) 
from TABLE
于 2013-07-04T09:17:47.603 回答
5

我从朋友那里收到了一个非常简单的解决方案,非常棒。因此,我将发布解决方法,以帮助与我处于相同位置的其他人。

首先,制作函数:

create FUNCTION dbo.countDigits(@A float) RETURNS tinyint AS
BEGIN
declare @R tinyint
IF @A IS NULL 
   RETURN NULL
set @R = 0
while @A - str(@A, 18 + @R, @r) <> 0
begin
   SET @R = @R + 1
end
RETURN @R
END
GO

第二:

select MY_FIELD,
dbo.countDigits(MY_FIELD) 
from MY_TABLE

使用该函数将为您提供小数点后的确切位数。

于 2012-12-20T09:31:33.590 回答
0

首先是切换到 usingCONVERT而不是CAST. 不同之处在于,CONVERT您可以使用 指定格式代码。CAST使用任何默认格式代码:

当表达式为浮点数或实数时,样式可以是下表中显示的值之一。其他值被处理为 0。

没有一种格式特别吸引人,但我认为最适合您使用的是2. 所以它会是:

CONVERT(varchar(25),MY_FIELD,2)

不幸的是,这将为您提供科学计数法的值,并且始终使用 16 位数字,例如1.234567890123456e+000. 要获得“真实”位数,您需要将这个数字分开,计算出小数部分的位数,然后用指数中提供的数字偏移它。


当然,在处理具有已定义二进制表示的数字时,插入关于尝试谈论数字的常见警告/警告。特定“数字”的数量可能会因计算方式而异。float

于 2012-12-19T13:22:58.123 回答
0

我不确定速度。等等或这段代码的优雅。这是为了一些临时测试来找到第一个十进制值。但是可以更改此代码以遍历所有小数并轻松找到最后一次值大于零的时间。

DECLARE @NoOfDecimals       int             = 0 
Declare @ROUNDINGPRECISION  numeric(32,16)  = -.00001000

select @ROUNDINGPRECISION = ABS(@ROUNDINGPRECISION)
select @ROUNDINGPRECISION = @ROUNDINGPRECISION - floor(@ROUNDINGPRECISION)


while @ROUNDINGPRECISION < 1
Begin
    select @NoOfDecimals = @NoOfDecimals +1
    select @ROUNDINGPRECISION =  @ROUNDINGPRECISION * 10

end;

select @NoOfDecimals
于 2016-10-07T16:05:18.007 回答