Login or Sign Up to become a member!
LessThanDot Sit Logo

LessThanDot

Data Management

Less Than Dot is a community of passionate IT professionals and enthusiasts dedicated to sharing technical knowledge, experience, and assistance. Inside you will find reference materials, interesting technical discussions, and expert tips and commentary. Once you register for an account you will have immediate access to the forums and all past articles and commentaries.

LTD Social Sitings

Lessthandot twitter Lessthandot Linkedin Lessthandot friendfeed Lessthandot facebook Lessthandot rss

Note: Watch for social icons on posts by your favorite authors to follow their postings on these and other social sites.

Your profile

    Search

    XML Feeds

    Google Ads

    « Don't use text datatype for SQL 2005 and upUndetectable Distributed Deadlocks »
    comments

    That may seem a little harsh, and it's not always true. However, most of the time, the float data type should be avoided. Unfortunately, the float (and real) data types are approximate data types that can lead to significant rounding errors.

    How to detect this problem:

    1. Select Table_Name + '.' + Column_Name As Name, 'Table' As ObjectType
    2. From   Information_Schema.Columns
    3. Where  Data_Type in ('Float', 'Real')
    4.  
    5. UNION ALL
    6.  
    7. SELECT  Name, Types.Description
    8. FROM    (
    9.         SELECT S.Name, S.XType, C.TEXT
    10.         FROM   sysobjects S
    11.                INNER Join syscomments C
    12.                  ON  S.id = C.id
    13.                  And S.xtype in ('P', 'v', 'TF', 'FN')
    14.         WHERE   OBJECTPROPERTY(S.ID, N'IsMSShipped') = 0
    15.  
    16.         UNION All
    17.  
    18.         SELECT OBJECT_NAME(A.id), s.XType, LeftText + RightText
    19.         FROM   sysobjects s
    20.                INNER Join (
    21.                  SELECT Id, RIGHT(TEXT, 10) AS LeftText, ColId
    22.                  FROM   syscomments
    23.          ) AS A
    24.                    ON  S.id = A.id
    25.                    And OBJECTPROPERTY(S.ID, N'IsMSShipped') = 0
    26.                    And S.xtype in ('P', 'v', 'TF', 'FN')
    27.                INNER Join (
    28.                  SELECT Id, LEFT(TEXT, 10) AS RightText, ColId
    29.          FROM   syscomments
    30.              ) AS B
    31.                    ON  A.id = B.id
    32.                    and A.ColId = B.ColId - 1
    33.         ) AS A
    34.         Inner join (
    35.             Select 'FN' As XType, 'Function' As Description
    36.             Union All
    37.             Select 'P' As XType, 'Procedure' As Description
    38.             Union All
    39.             Select 'V' As XType, 'View' As Description
    40.             Union All
    41.             Select 'TF' As XType, 'Table Values Function' As Description
    42.             ) As Types
    43.             On A.XType = Types.XType
    44. WHERE   TEXT Like '%float[^(]%'
    45. ORDER BY Name

    How to correct it: Examine the data you are using and identify the precision and scale required. Change the data type (or code) to use a decimal with the precision and scale you require.

    Level of severity: Moderate

    Level of difficulty: Easy

    About the Author

    George has been developing software professionally for 19 years, first for the department of defense, and then for various other companies. In 1998, George started his software company, Orbit Software, specializing in School Bus Transportation software. His specialty is refining SQL Server queries to deliver optimal performance.
    Social SitingsTwitterLTD RSS Feed
    Instapaper

    4 comments

    Comment from: sqlsister [Member] Email
    sqlsister I've been saying this for years and having it mostly fall on deaf ears. Amazing how programmers don't understand about rounding errors!
    11/16/09 @ 10:56
    Comment from: George Mastros (gmmastros) [Member]
    George Mastros (gmmastros) Hopefully the code I provide above will help you determine where the float data type is used so that it is easier to fix this potential problem.

    Thanks for the feedback.
    11/16/09 @ 11:00
    Comment from: Adam Machanic [Visitor] · http://sqlblog.com
    Adam Machanic Unfortunately the numeric types can have pretty serious rounding issues as well, depending on how you have them configured. To get around this I sometimes use FLOAT as an intermediary when I need to deal with very small values and -some- value is better than rounding to zero.

    ---
    DECLARE @d1 DECIMAL(28, 12)
    DECLARE @d2 DECIMAL(28, 12)
    SET @d1 = 0.00001
    SET @d2 = 0.00001

    SELECT
    @d1 * @d2,
    CONVERT(DECIMAL(28, 12), CONVERT(FLOAT, @d1) * CONVERT(FLOAT, @d2))
    ---
    11/16/09 @ 13:48
    Comment from: Naomi Nosonovsky [Member]
    Naomi Nosonovsky Interestingly this is posted in Database Weekly

    Database Weekly article

    11/17/09 @ 09:42

    Leave a comment


    Your email address will not be revealed on this site.

    Your URL will be displayed.
    (Line breaks become <br />)
    (Name, email & website)
    (Allow users to contact you through a message form (your email will not be revealed.)