cfparam, SQL Server and datatypes
June 02, 2008
This one always catches me out, so once and for all I'm going to post it for future reference! If you use the attribute values of "cf_sql_numeric" or "cf_sql_decimal" for decimals then they are rounded to the nearest integer. As Matt points out in the comments, this is because "cf_sql_numeric" and "cf_sql_decimal" use the scale attribute to specify the number of decimal places. If you don't add the scale attribute, then the default is 0 decimal places. This does lead me on to wonder what real benefit there is to using cf_sql_decimal with a scale attribute instead of cf_sql_float (aside from the obvious rounding of decimal places).
To test this I created a table in SQL Server with the following schema:
CREATE TABLE [dbo].[SqlType] ( [type_id] [int] IDENTITY (1, 1) NOT FOR REPLICATION NOT NULL , [type_decimal] [decimal](18, 2) NULL , [type_money] [money] NULL , [type_float] [float] NULL , [type_name] [nvarchar] (50) COLLATE Latin1_General_CI_AS NULL , [type_real] [real] NULL ) ON [PRIMARY] GO ALTER TABLE [dbo].[SqlType] WITH NOCHECK ADD CONSTRAINT [PK_SqlType] PRIMARY KEY CLUSTERED ( [type_id] ) ON [PRIMARY] GO
I then created the following ColdFusion script:
<cfquery name="qrytest" datasource="john"> insert into [SqlType] ( type_decimal, type_money, type_float, type_real, type_name ) values ( <cfqueryparam value="2.6" cfsqltype="cf_sql_decimal" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_decimal" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_decimal" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_decimal" />, 'cf_sql_decimal' ) </cfquery> <cfquery name="qrytest" datasource="john"> insert into [SqlType] ( type_decimal, type_money, type_float, type_real, type_name ) values ( <cfqueryparam value="2.6" cfsqltype="cf_sql_double" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_double" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_double" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_double" />, 'cf_sql_double' ) </cfquery> <cfquery name="qrytest" datasource="john"> insert into [SqlType] ( type_decimal, type_money, type_float, type_real, type_name ) values ( <cfqueryparam value="2.6" cfsqltype="cf_sql_float" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_float" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_float" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_float" />, 'cf_sql_float' ) </cfquery> <cfquery name="qrytest" datasource="john"> insert into [SqlType] ( type_decimal, type_money, type_float, type_real, type_name ) values ( <cfqueryparam value="2.6" cfsqltype="cf_sql_money" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_money" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_money" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_money" />, 'cf_sql_money' ) </cfquery> <cfquery name="qrytest" datasource="john"> insert into [SqlType] ( type_decimal, type_money, type_float, type_real, type_name ) values ( <cfqueryparam value="2.6" cfsqltype="cf_sql_money4" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_money4" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_money4" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_money4" />, 'cf_sql_money4' ) </cfquery> <cfquery name="qrytest" datasource="john"> insert into [SqlType] ( type_decimal, type_money, type_float, type_real, type_name ) values ( <cfqueryparam value="2.6" cfsqltype="cf_sql_numeric" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_numeric" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_numeric" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_numeric" />, 'cf_sql_numeric' ) </cfquery> <cfquery name="qrytest" datasource="john"> insert into [SqlType] ( type_decimal, type_money, type_float, type_real, type_name ) values ( <cfqueryparam value="2.6" cfsqltype="cf_sql_real" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_real" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_real" />, <cfqueryparam value="2.6" cfsqltype="cf_sql_real" />, 'cf_sql_real' ) </cfquery>
Here are my results
| type_id | type_decimal | type_money | type_float | type_name | type_real |
| 1 | 2 | 2 | 2 | cf_sql_decimal | 2 |
| 2 | 2.35 | 2.35 | 2.35 | cf_sql_double | 2.35 |
| 3 | 2.35 | 2.35 | 2.35 | cf_sql_float | 2.35 |
| 4 | 2.35 | 2.35 | 2.35 | cf_sql_money | 2.35 |
| 5 | 2.35 | 2.35 | 2.35 | cf_sql_money4 | 2.35 |
| 6 | 2 | 2 | 2 | cf_sql_numeric | 2 |
| 7 | 2.35 | 2.35 | 2.349999905 | cf_sql_real | 2.35 |
| 8 | 3 | 3 | 3 | cf_sql_decimal | 3 |
| 9 | 2.6 | 2.6 | 2.6 | cf_sql_double | 2.6 |
| 10 | 2.6 | 2.6 | 2.6 | cf_sql_float | 2.6 |
| 11 | 2.6 | 2.6 | 2.6 | cf_sql_money | 2.6 |
| 12 | 2.6 | 2.6 | 2.6 | cf_sql_money4 | 2.6 |
| 13 | 3 | 3 | 3 | cf_sql_numeric | 3 |
| 14 | 2.6 | 2.6 | 2.599999905 | cf_sql_real | 2.6 |
So, the moral of the story is don't use "cf_sql_numeric" or "cf_sql_decimal" for decimals!
- Posted in:
- SQL
- ColdFusion
11 comments
Leave a comment
If you found this post useful, interesting or just plain wrong, let me know - I like feedback :)

Comment by Matt – June 02, 2008
Comment by Kris Brixon – June 02, 2008
Comment by John Whish – June 02, 2008
Comment by Ben Nadel – June 02, 2008
I've always used float and never thought about it. On the project I'm doing at the moment for some reason I used decimal instead (you'd think it would be for a decimal field!).
Comment by John Whish – June 02, 2008
Then, just make sure to use the scale attribute appropriately. Or am I missing something, or are you just saying that it's too much of a pain to remember that you only need to use scale when dealing with decimal types?
Comment by Aaron Longnion – June 02, 2008
I agree that sticking to the live docs is normally the way to go. However what Ben and I are saying is that as there appears to be no gain from using CF_SQL_DECIMAL instead of CF_SQL_FLOAT, why not always use float and not have the problem. Nice blog BTW :)
Comment by John Whish – June 09, 2008
Comment by Aaron Longnion – June 09, 2008
That's a valid point, I don't know the answer to that one! I guess it has more to do with the Java drivers rather than ColdFusion itself.
Comment by John Whish – June 09, 2008
our database experts always get the big shivers the couple of times I suggest using a float somewhere...
They claim it's the big evil in SQL-country and should only be used for scientific purposes and never 4 day 2 day SQL...
So my advice is using the correct datatype for the purpose needed - if the SQL is something scientific you could use a float, otherwise use decimal or numeric with the right scale ;-)
Comment by Sebastiaan – June 16, 2008
Interesting. I never use float in the actual database. Ask him what (s)he things about having a field type of decimal in the database, but using the CF_SQL_FLOAT type in ColdFusion. Does that send shivers down their spine? (If so - it sounds like fun!)
Comment by John Whish – June 16, 2008