View comments | RSS feed

cfqueryparam

Description

Verifies the data type of a query parameter and, for DBMSs that support bind variables, enables ColdFusion to use bind variables in the SQL statement. Bind variable usage enhances performance when executing a cfquery statement multiple times.

This tag is nested within a cfquery tag, embedded in a query SQL statement. If you specify optional parameters, this tag performs data validation.

Macromedia recommends that you use the cfqueryparam tag within every cfquery tag, to help secure your databases from unauthorized users. For more information, see Security Bulletin ASB99-04, "Multiple SQL Statements in Dynamic Queries," at
www.macromedia.com/devnet/security/security_zone/asb99-04.html, and Accessing and Retrieving Data in ColdFusion MX Developer's Guide.

Category

Database manipulation tags

Syntax

<cfquery 
name = "query_name"
dataSource = "ds_name"
...other attributes...
SQL STATEMENT column_name =
<cfqueryparam value = "parameter value"
CFSQLType = "parameter type"
maxLength = "maximum parameter length"
scale = "number of decimal places"
null = "yes" or "no"
list = "yes" or "no"
separator = "separator character">
AND/OR ...additional criteria of the WHERE clause...>
</cfquery>

See also

cfinsert, cfprocparam, cfprocresult, cfquery, cfstoredproc, cftransaction, cfupdate; Enhancing security with cfqueryparam in Accessing and Retrieving Data in ColdFusion MX Developer's Guide

Attributes

Attribute Req/Opt Default Description

value

Required

 

Value that ColdFusion passes to the right of the comparison operator in a where clause.

If CFSQLType is a date or time option, ensure that the date value uses your DBMS-specific date format. Use the CreateODBCDateTime or DateFormat and TimeFormat functions to format the date value.

CFSQLType

Optional

CF_SQL_CHAR

SQL type that parameter (any type) is bound to:

  • CF_SQL_BIGINT
  • CF_SQL_BIT
  • CF_SQL_CHAR
  • CF_SQL_BLOB
  • CF_SQL_CLOB
  • CF_SQL_DATE
  • CF_SQL_DECIMAL
  • CF_SQL_DOUBLE
  • CF_SQL_FLOAT
  • CF_SQL_IDSTAMP
  • CF_SQL_INTEGER
  • CF_SQL_LONGVARCHAR
  • CF_SQL_MONEY
  • CF_SQL_MONEY4
  • CF_SQL_NUMERIC
  • CF_SQL_REAL
  • CF_SQL_REFCURSOR
  • CF_SQL_SMALLINT
  • CF_SQL_TIME
  • CF_SQL_TIMESTAMP
  • CF_SQL_TINYINT
  • CF_SQL_VARCHAR

maxLength

Optional

Length of string in value attribute

Maximum length of parameter. Ensures that the length check is done by ColdFusion before the string is sent to the DBMS, thereby helping to prevent the submission of malicious strings.

scale

Optional

0

Number of decimal places in parameter. Applies to CF_SQL_NUMERIC and CF_SQL_DECIMAL.

null

Optional

No

Whether parameter is passed as a null value:

  • Yes: tag ignores the value attribute.
  • No

list

Optional

No

  • Yes: the value attribute value is a delimited list.
  • No

separator

Required, if you specify a list in value attribute

, (comma)

Character that separates values in list, in value attribute.

Usage

Use the cfqueryparam tag in any SQL statement (for example, SELECT, INSERT, UPDATE, and DELETE) that uses ColdFusion variables.

You cannot use the cfquery cachedAfter or cachedWithin attributes with cfqueryparam.

For maximum validation of string data, specify the maxlength attribute.

This tag does the following:

To benefit from the enhanced performance of bind variables, you must use cfqueryparam for all ColdFusion variables, and your DBMS must support bind variables. If a DBMS does not support bind parameters, ColdFusion validates and substitutes the validated parameter value back into the string. If validation fails, it returns an error message.

The validation rules are as follows:

ColdFusion debug output shows the bind variables as question marks and lists the values beneath the query, in order of usage.

Note: To insert an empty string into a Microsoft Access table using the SequelLink ODBC Socket or SequelLink Access driver, the CFSQLType attribute must specify CF_SQL_LONGVARCHAR.

The following table shows the mapping of ColdFusion SQL data types with JDBC SQL types and those of the listed database management systems:

ColdFusion JDBC DB2 Informix Oracle MSSQL

CF_SQL_ARRAY

ARRAY

 

 

 

 

CF_SQL_BIGINT

BIGINT

Bigint

int8, serial8

 

 

CF_SQL_BINARY

BINARY

Char for Bit Data

 

 

binary

timestamp

CF_SQL_BIT

BIT

 

boolean

 

bit

CF_SQL_BLOB

BLOB

Blob

blob

blob, bfile

 

CF_SQL_CHAR

CHAR

Char

char,

nchar

char,

nchar

char, nchar,

unique
identifier

CF_SQL_CLOB

CLOB

Clob

clob

clob,nclob

 

CF_SQL_DATE

DATE

Date

date, datetime, year to day

 

 

CF_SQL_DECIMAL

DECIMAL

Decimal

decimal, money

number

decimal, money, small
money

CF_SQL_DISTINCT

DISTINCT

 

 

 

 

CF_SQL_DOUBLE

DOUBLE

Double

 

 

 

CF_SQL_FLOAT

FLOAT

Float

float

number

float

CF_SQL_IDSTAMP

CHAR

Char

char, nchar

char, nchar

char, nchar, unique
identifier

CF_SQL_INTEGER

INTEGER

Integer

integer, serial

 

int

CF_SQL_LONGVARBINARY

LONGVARBINARY

Long Varchar for Bit Data

byte

long raw

image

CF_SQL_LONGVARCHAR

LONGVARCHAR

Long Varchar

text

long

text, ntext

CF_SQL_MONEY

DOUBLE

Double

 

 

 

CF_SQL_MONEY4

DOUBLE

Double

 

 

 

CF_SQL_NULL

NULL

 

 

 

 

CF_SQL_NUMERIC

NUMERIC

Numeric

 

 

numeric

CF_SQL_OTHER

OTHER

 

 

 

 

CF_SQL_REAL

REAL

Real

smallfloat

 

real

CF_SQL_REFCURSOR

REF

 

 

 

 

CF_SQL_SMALLINT

SMALLINT

Smallint

smallint

 

smallint

CF_SQL_STRUCT

STRUCT

 

 

 

 

CF_SQL_TIME

TIME

Time

datetime hour to second

 

 

CF_SQL_TIMESTAMP

TIMESTAMP

Timestamp

datetime year to fraction(5), datetime year to second

date

datetime, smalldate
time

CF_SQL_TINYINT

TINYINT

 

 

 

tinyint

CF_SQL_VARBINARY

VARBINARY

Rowid

 

raw

varbinary

CF_SQL_VARCHAR

VARCHAR

Varchar

varchar, nvarchar, lvarchar

varchar2, nvarchar2

varchar, nvarchar, sysname

Example

<!--- This example shows cfqueryparam with VALID input in Course_ID. --->
<h3>cfqueryparam Example</h3>
<cfset Course_ID = 12>
<cfquery name = "getFirst" dataSource = "cfdocexamples">
   SELECT * 
   FROM courses
   WHERE Course_ID = <cfqueryPARAM value = "#Course_ID#"
   CFSQLType = "CF_SQL_INTEGER"> 
</cfquery>
<cfoutput query = "getFirst">
   <p>Course Number: #Course_ID#<br> Description: #descript#</p>
</cfoutput>

<!--- This example shows the use of CFQUERYPARAM when INVALID string data is
   in Course_ID. ----> 
<p>This example throws an error because the value passed in the CFQUERYPARAM 
tag exceeds the MAXLENGTH attribute</p> 

<cfset LastName="Peterson; DELETE employees WHERE LastName='Peterson'">
<!------- Note that for string input you must specify the MAXLENGTH attribute 
   for validation. --------------------------------------------------> 
<cfquery 
   name="getFirst" datasource="cfdocexamples"> 
   SELECT * 
   FROM employees 
   WHERE LastName=<cfqueryparam 
                        value="#LastName#" 
                        cfsqltype="CF_SQL_VARCHAR" 
                        maxlength="17"> 
</cfquery> 
<cfoutput 
   query="getFirst">       <p>
      Course Number: #FirstName# #LastName# 
      Description: #Department# </p> 
</cfoutput> 

ColdFusion MX 7 | ColdFusion MX 6.1 | ColdFusion MX | Forums | Developer Center | KnowledgeBase | Bug Reporting

Version 7

Comments


bizarrojack said on Apr 21, 2005 at 8:36 AM :
So I am told, the speed bonus comes in when a RDBMS' query optimizer can be circumvented, i.e. when the optimization plan is cached already. When non-cfqueryparam-ed query's optimization step is trivial, you wont see an improvement, and if it is repeated exactly (including arguments) you would also not see an improvement by using cfqueryparam. Without cfqueryparam (bind variables), queries with different arguments won't appear to be a match in the query optimizer cache lookup, and what is effectively the same query will have to go through the optimization process, basically needlessly.

You can see in the cfdebug output that the SQL without cfqueryparam is like this:
select x,y,z from table where foo = 'bar' . . .
select x,y,z from table where foo = 'baz' . . .
which is two entries in the optimization plan cache, whereas with cfqueryparam it will be
select x,y,z from table where foo = ? . . .
both times, with the variables printed afterwards. These are somewhat bad examples, because the optimization is trivial, and you wont be able to tell from the elapsed time whether that step was repeated or not.
bizarrojack said on Jul 12, 2005 at 7:54 AM :
ColdFusion does not require the "null" attribute, but if you have a numeric field that can be null, it is required to avoid a situational crash - "" (blank) will not be translated to NULL if you use only the "value" attribute even if your DBMS would accept SQL syntax that way; you have to consider the variable twice per cfqueryparam, like

<cfqueryparam value="#variable#" null="#variable is ""#" cfsqltype="CF_SQL_FLOAT">

This may depend on your DBMS.
switchbox said on Jul 14, 2005 at 7:43 PM :
The MSSQL data type uniqueidentifier is a single token, not 2 words. The same applies to smalldatetime and smallmoney.
ASandstrom said on Aug 1, 2005 at 12:58 PM :
In response to switchbox: A documentation bug (#60837) has been entered so that this will be corrected in the next release of ColdFusion.
edgriffiths said on Sep 20, 2005 at 9:05 AM :
To perform an MS SQL 'LIKE' comparison using CFQUERYPARAM place the percent signs within the 'value' attribute:

SELECT moreStuff
FROM myTable
WHERE stuff LIKE <cfqueryparam value="%#substringToCompare#%" cfsqltype="CF_SQL_VARCHAR">
ASandstrom said on Sep 27, 2005 at 7:16 AM :
For information about using the null attribute, see the article by Justin Fidler at http://www.macromedia.com/devnet/server_archive/articles/cfqueryparam_oracle_databases.html

Quoting from the article:
"There are a few things to keep in mind when using null variables. The VALUE parameter must be an empty string. By empty string, I mean two sets of double quotes with nothing in between. If you have anything else in there, even just a blank space, it can throw an error.

Also, make sure to set NULL="YES" or it won't set it to NULL properly. Finally, make sure to use the proper CFSQLTYPE to match the field you're setting to NULL. This may seem a bit counter-intuitive because NULL has no data type, but you may run into problems if you don't"
Oblio said on Nov 18, 2005 at 9:57 AM :
My tests show that Justin Fidler's article no longer applies when issuing nulls. I'm able to use the 'null' attribute to override the 'value' as the documentation describes. Further, the documentation doesn't note that any boolean value can be substituted for the 'yes|no' assignment to 'null'; for example, to only insert form fields that have been filled in, I used this:

<cfqueryparam value="#Trim(FORM.name)#" cfsqltype="CF_SQL_VARCHAR" null="#Len(Trim(FORM.name))#">
boughtonp said on Nov 29, 2005 at 8:20 AM :
Something that I can't see mentioned above, but that is worth noting:
If you enter an invalid or mis-spelt cfsqltype it will not throw an error, it will simply switch to using CF_SQL_CHAR.
No screen name said on Nov 27, 2006 at 12:24 PM :
For MSSQL, the money data type should use CF_SQL_MONEY, not CF_SQL_DECIMAL.
anthony_id said on Dec 8, 2006 at 2:32 PM :
RE: MS SQL LIKE statement

This only works if the % signs fit the datatype. I tried using it with a date datatype and received a type-mismatch error. This makes running a LIKE query on non *CHAR types impossible, so I've reverted to plain old text. This isn't a security concern if type checking/validation occurs on the data before it hits the query (mine is in a CFC), but negates any performance gains from cfqueryparam.
anthony_id said on Dec 8, 2006 at 2:54 PM :
RE: LIKE and MS SQL with cfqueryparam

To get around datatype matching with non character types, it is possible to CAST the column to varchar in the WHERE clause. In this case, the type is CF_SQL_VARCHAR in the cfqueryparam statement.

Note also that MS SQL uses the following format when dates are CAST:
mmm d yyyy (NOTE THERE ARE 2 [TWO!] spaces after mmm)
The Fletch said on Jan 4, 2007 at 2:23 PM :
CF_SQL_TINYINT does not seem to work properly. I used CF_SQL_INT (which is not even listed in the options) and it works just fine for a tinyint datatype in an MSSQL database.
Jon Briccetti said on May 30, 2007 at 8:20 AM :
i've noticed that when using bind variables against views, if we re-build the views in the database and then try to access the cfm code with the bind variable queries, it throws an error. if we switch to using a straight SQL stmt, somethign like ... where column = '#var1#' it works... and then after "a little while" i can switch back to using the cfqueryparam and it all works fine. what **i'm guessing** is that the cached optimization info on the oracle side is no longer valid once we re-build the view, yet it must be trying to use that optimization plan anyway. later, when the optimization chache clears it works again.

 

RSS feed | Send me an e-mail when comments are added to this page | Comment Report

Current page: http://livedocs.adobe.com/coldfusion/7/htmldocs/00000317.htm