SQL SERVER – Puzzle – Challenge – Error While Converting Money to Decimal

Earlier I wrote SQL SERVER – Challenge – Puzzle – Usage of FAST Hint and I did receive some good comments. Here is another question to tease your mind. Run following script and you will see that it will thrown an error.
DECLARE @mymoney MONEY;
SET @mymoney = 12345.67;
SELECT CAST(@mymoney AS DECIMAL(5,2)) MoneyInt;
GO

The datatype of money is also visually look similar to the decimal, why it would throw following error:

Msg 8115, Level 16, State 8, Line 3
Arithmetic overflow error converting money to data type numeric.

Please leave a comment with explanation and I will post a your answer on this blog with due credit.

Reference: Pinal Dave (http://blog.sqlauthority.com)

About these ads

33 thoughts on “SQL SERVER – Puzzle – Challenge – Error While Converting Money to Decimal

  1. The money data type goes out to 4 places after the decimal.

    Your data type @mymoney is set to round to the nearest penny (2 places). SQL cannot handle the conversion and will throw out the overflow error.

    Try SELECT CAST(@mymoney AS DECIMAL(5,4)) MoneyInt;

    Like

    • As with the original post, this is wrong, DECIMAL(5,4) would hold for example, 1.2345, the first number is the total length, the second number is the decimal points

      Like

  2. You need to increase the size of precision. You need to make it 7 or above.

    DECLARE @mymoney MONEY;
    SET @mymoney = 12345.67;
    SELECT CAST(@mymoney AS DECIMAL(7,2)) MoneyInt;
    GO

    O/P-> 12345.67

    Thanks & Regards,
    Piyush srivastava
    Mumbai

    Like

  3. DECLARE @mymoney MONEY;
    SET @mymoney = 12345.67;
    SELECT CAST(@mymoney AS DECIMAL(7,2)) MoneyInt;
    GO

    The target data type is unable to accommodate needful value. We will need to give enough room by expanding the Decimal value and precision.

    Like

  4. In Your question while you converting money to decimal you are using decimal(5,2) that means 2 is precision in total number 5 digit including precision that means only 3 digit and your money value is greater then hundred

    Like

  5. Another approach (NOT RECOMMENDED)

    SET ARITHABORT OFF

    DECLARE @mymoney MONEY;
    SET @mymoney = 12345.67;
    SELECT CAST(@mymoney AS DECIMAL(5,2)) MoneyInt;
    GO

    The above method is the way to silently fail the conversions, in which case the CAST function will return a NULL Value. Notice the SET statement that explicitly sql server to ignore arithmetic overflows.

    Having said that, this approach is not a recommended practice and should not be used any environment (DEV,QA,STAG,PROD).

    Like

  6. you must do :

    DECLARE @mymoney MONEY;
    SET @mymoney = 12345.67;
    SELECT CAST(@mymoney AS DECIMAL(,2)) MoneyInt;

    you have 7 digits in @mymoney (including decimals)

    Like

  7. you must do :

    DECLARE @mymoney MONEY;
    SET @mymoney = 12345.67;
    SELECT CAST(@mymoney AS DECIMAL(abc,2)) MoneyInt;

    you have 7 digits in @mymoney (including decimals) so you put abc=7 or greater than 7

    Like

  8. You need to specify

    DECLARE @mymoney MONEY;
    SET @mymoney = -12345.67;
    SELECT CAST(@mymoney AS DECIMAL(7,2)) MoneyInt;

    Because…

    Here first part specifies total number of decimals. i.e. number of characters before “Period” (.) + number of characters after “Period” (.)

    5+2 = 7

    Second part sepcifies how many characters should be after “Period” (.)

    Like

  9. DECIMAL(5,2) has 5 precision and 2 scale.

    Precision is the total number of digits in a number.

    Scale is the number of digits to the right of the decimal point in a number.

    For Example the number 8714.235 has a

    precision – 7

    scale – 3

    Like

  10. Hi pinal

    as per the bol.

    In Transact-SQL statements, a constant with a decimal point is automatically converted into a numeric data value, using the minimum precision and scale necessary. For example, the constant 12345.67 is converted into a numeric value with a precision of 7 and a scale of 2.

    bol link : http://msdn.microsoft.com/en-us/library/ms191530.aspx

    section : Converting decimal and numeric Data

    Like

  11. DECLARE @mymoney MONEY;
    SET @mymoney = 12345.67;
    SELECT CAST(@mymoney AS DECIMAL(7,2)) MoneyInt;
    GO?

    Now it will not through any error.
    Since @mymoney variable has 5 digits before decimal and 2 digits after decimal. So we have to put 7 insead of 5 in precision of DECIMAl Datatype, because 5 + 2 = 7 means total no of digits that DECIMAL datatype may contain before decimal and after decimal place.
    For understanding, you can also see it like this DECIMAL((7-2),2).

    Have a look the detail given below for more clarity-
    DECIMAL(p,s)
    p (precision)
    The maximum total number of decimal digits that can be stored, both to the left and to the right of the decimal point.
    s (scale)
    The maximum number of decimal digits that can be stored to the right of the decimal point.

    Like

  12. Query from “fbncs” is correct because decimal data type takes 2 bytes of overhead to store the offset to the value. Which money don’t. Thats why converting from money to decimal need 2 bytes extra otherwise enjoy arithmetic overflow error ;)

    Like

  13. Hi Pinal,

    The overflow problem is because the length of DECIMAL(5,2) is small to support this value.

    In this case, the value 12345.67 has length (precision) of 7 digits, when 2 digits are dedicated to “.67″ (scale), then you can convert this number to a DECIMAL(7,2) and not to a DECIMAL(5,2).

    DECLARE @mymoney MONEY;
    SET @mymoney = 12345.67;
    SELECT CAST(@mymoney AS DECIMAL(7,2)) MoneyInt;
    GO

    But you can lost the 2 digits dedicated to “.67″, if you use a small decimal with a compatible precision without scale:

    DECLARE @mymoney MONEY;
    SET @mymoney = 12345.67;
    SELECT CAST(@mymoney AS DECIMAL(5,0)) MoneyInt;
    GO

    Like

  14. Yes I agree with Fbncs.

    Just adding description for whay it’s filing when we rty to convert it to Decimal(5,2)

    In decimal decalaration, DECIMAL(P,S), P (precision) specifies the number of digits on both side of decimal point. 12345.67 has 7 digits ( of 2 digits are of scale), so we need decimal(5,2) for storing this number.

    Even if we tries to convert the number to DECIMAL(7,3), we get same error as we specify scale as 3 and so, we can have only 4 digits on left side of decimal point.

    -Chintak

    Like

  15. You are taking 5 in place of 7.Because here length of This Money type variable will be fit in 5 digit before decimal point so you should take at least 5 digit in decimal datatype. digit after decimal will be round off.

    DECLARE @mymoney MONEY;
    SET @mymoney = 12345.67;
    SELECT CAST(@mymoney AS DECIMAL(7,2)) MoneyInt;

    Like

  16. Decimal data type is defined as Decimal (Precision, Scale).

    Precision includes Scale.

    So Decimal (5,2) actually means, we can have 3 digits before decimal and 2 digits after decimal.

    From above example, (3+2) digits is called as precision and 2 digits after decimal is callled as scale.

    In your example, you have 5 digits before decimal and 2 digits after decimal, therefore the correct decimal should be Decimal (7,2).

    ~ IM.

    Like

  17. Pingback: SQL SERVER – Challenge – Puzzle – Why does RIGHT JOIN Exists Journey to SQL Authority with Pinal Dave

  18. DECLARE @mymoney MONEY;
    SET @mymoney = 12345.67;
    SELECT CAST(@mymoney AS DECIMAL(5,2)) MoneyInt;

    SIR HERE THE DECIMAL VALUE ACCEPT

    DECIMAL(TOTAL DIGIT,DECIMAL POINT AFTER DIGIT)

    SO USE

    SELECT CAST(@mymoney AS DECIMAL(7,2)) MoneyInt;

    IT WILL RUN

    Like

  19. Pingback: SQL SERVER – 3 Simple Puzzles – Need Your Suggestions Journey to SQL Authority with Pinal Dave

  20. Pingback: SQLAuthority News – Statistics Used by the Query Optimizer in Microsoft SQL Server 2008 – Microsoft Whitepaper Journey to SQL Authority with Pinal Dave

  21. Pingback: SQLAuthority News – Statistics Used by the Query Optimizer in Microsoft SQL Server 2008 – Microsoft Whitepaper Journey to SQL Authority with Pinal Dave

  22. Pingback: SQL SERVER – Weekly Series – Memory Lane – #005 « SQL Server Journey with SQL Authority

  23. Pingback: SQL SERVER – Weekly Series – Memory Lane – #006 « SQL Server Journey with SQL Authority

  24. Numeric data types that have fixed precision and scale.
    decimal[ (p[ , s] )] and numeric[ (p[ , s] )]

    p (precision) :
    The maximum total number of decimal digits that can be stored, both to the left and to the right of the decimal point.
    s (scale) :
    The maximum number of decimal digits that can be stored to the right of the decimal point.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s