TSQL用于标识长Float值

时间:2009-07-09 15:40:17

标签: sql-server sql-server-2005 tsql

我正在处理遗留系统,我需要根据数据类型为Float的列识别一些不良记录。

好记录的值为......

1
2
1.01
2.01

不良记录就是......

1.009999999999999
2.003423785643000
3.009999990463260

我已经尝试了一些select语句,其中我转换为Decimal并转换为varchar并使用LEN()函数,但这似乎不起作为1.01的良好记录变为1.0100000000000000

- 编辑 我现在离我更近了,因为我发现我可以做(重量* 100),所有好的记录都变成了整数值,如101,201,265,301,500等...... 而诸如2.00999999046326之类的坏事则变为200.999999046326

6 个答案:

答案 0 :(得分:1)

这适用于我的SQL Server 2005 DB:

select len(cast(cast(1.01 as float) as varchar))

结果:

4

事实上,如果我愿意,它甚至可以让我跳过显式varchar:

select len(cast(1.011 as float))

结果:

5


更新:首先,我仍然需要转换为varchar。认为不是错了。也就是说,我这一切都在使用字符串,并即将发布如何。那么你我对你的mulitpling 100的更新,并意识到这是要走的路。所以这是我用于测试两种方式的代码:

declare @test table ( c float)
insert into @test 
    select * from 
        ( select 14.0100002288818 as c union
          select 1.01 union
          select 2.00999999046326 union
          select 14.01
         ) t

select c,
  case when c = cast(cast(c as varchar) as float) AND LEN(cast(c as varchar))<=5 then 1 else 0 end,
  case when c * 100 = floor(c * 100) then 1 else 0 end
from @test

答案 1 :(得分:1)

也许是这样的事情? (当然,调整where子句中的精度/比例)

select val from mytable WHERE CONVERT(decimal(5,2), val) <> val

答案 2 :(得分:1)

您是否考虑过使用CLR集成并使用.net来处理验证 请参阅此链接Basics of Using a .NET Assembly in MS SQL - User Functions

基本上你使用.net方法作为用户定义的函数来进行验证; .NET更适合使用数字。

答案 3 :(得分:0)

你可以这样做:

SELECT * 
FROM YourTable
WHERE CAST(YourFloatField AS DECIMAL(15,2)) <> YourFloatField

我假设任何“坏”都有超过2个小数位。

答案 4 :(得分:0)

这真的会成为一个痛苦的因为浮点数是一种不精确的数据类型,你会在投射时获得隐式转换。

它还取决于您运行类似以下内容的位置

select convert(float,1.33)
查询分析器中的

输出为1.3300000000000001 在SSMS中,输出为1.33

转换为十进制时,需要指定比例和精度

所以,如果你这样做

select convert(decimal(10,6),convert(float,1.33))

你得到这个1.330000,因为你指定了6的缩放

你可以做这样的事情,在转换为十进制后,你会删除尾随的0s

select replace(rtrim(replace(convert(varchar(30),
    (convert(decimal(10,6),convert(float,1.33)))),'0',' ')),' ','0')

如果值为3.00999999046326,则需要至少为14的比例

select replace(rtrim(replace(convert(varchar(30),
    (convert(decimal(30,14),convert(float,3.00999999046326)))),'0',' ')),' ','0')

答案 5 :(得分:0)

运行:

DECLARE @d FLOAT;
SET @d = 1.23;
SELECT ABS(CAST(@d AS DECIMAL(10,2)) - CAST(@d AS DECIMAL(15,8)));
SET @d = 1.230000098;
SELECT ABS(CAST(@d AS DECIMAL(10,2)) - CAST(@d AS DECIMAL(15,8)));

使用某些阈值,例如:

ABS(CAST(@d AS DECIMAL(10,2)) - CAST(@d AS DECIMAL(15,8)))<0.00001