When you query records from a database, the results (known as a record set) are returned in a special ColdFusion data type called a query object. A query object stores the records within it in rows and columns—just like a spreadsheet. Throughout this book, I’ll use the terms record and row interchangeably. Column name and field are also used interchangeably. Before we get into the specifics of querying databases and working with query objects, we need to create a database with some sample data to work with.
The majority of examples in this chapter (and throughout the book)
use a data source called ProgrammingCF
that
contains several database tables including one called
EmployeeDirectory
. The schema and sample data for
this database are listed in Appendix C. For
simplicity, I’ve chosen to use a Microsoft Access database for
all the examples; you can download the sample Access database from
O’Reilly’s catalog page for this book (http://www.oreilly.com/catalog/coldfusion/).
Of course, you can use any database you choose. To get started, you
need to create a new database and save it as
ProgrammingCF
. Next, create a new table and add
the fields shown in Table 4-2.
Table 4-2. Employee Directory Table Within the ProgrammingCF Database
Field Name |
Field Type |
Max Length |
---|---|---|
ID (primary key) |
AutoNumber |
N/A |
Name |
Text |
255 |
Title |
Text |
255 |
Department |
Text |
255 |
|
Text |
255 |
PhoneExt |
Number (long int) |
N/A |
Salary |
Number (double, two decimal places) |
N/A |
Picture |
Memo |
N/A |
In this example, ID
is an AutoNumber field
designated as the primary key for the table. A primary key is a
single field or concatenation of fields that uniquely identifies a
record. In Microsoft Access, AutoNumber is a special field type that
automatically assigns a sequentially incremental number when a record
is inserted into the table.[6] If you
aren’t using Access as your database, and your database
doesn’t have the equivalent of the AutoNumber field, consider
using ColdFusion’s Create-UUID( )
function
to generate a universally unique identifier (UUID) to use as the
primary key value for your record. UUIDs are 35-character
representations of 128-bit strings where each character is a
hexadecimal value in the range 0-9 and A-F. UUIDs are guaranteed to
be unique:
<!--- create a UUID and output it to the browser ---> <CFSET MyPrimaryKeyValue = CreateUUID( )> <CFOUTPUT> ID: #MyPrimaryKeyValue# </CFOUTPUT>
When you finish adding the fields, go ahead and save the table as
EmployeeDirectory
. Now it is time to populate the
EmployeeDirectory
table with data. Table 4-3 contains a short listing of records. For the
complete list, see Appendix C.
Table 4-3. Employee Directory Database Table Containing Employee Contact Information
ID |
Name |
Title |
Department |
|
Phone-Ext |
Salary |
---|---|---|---|---|---|---|
1 |
Pere Money |
President |
Executive Mgmt |
pere@example.com |
1234 |
400K |
2 |
Greg Corcoran |
Director |
Marketing |
greg@example.com |
1237 |
960K |
3 |
Mark Edward |
VP |
Sales |
mark@example.com |
1208 |
155K |
Once you finish entering all the records, save the database to a
directory on your ColdFusion server. If you have downloaded the
sample Access database, you need to make sure that it resides on the
same machine as your ColdFusion server or on a network share
available to the server. Before you can begin using the database, you
need to register it as a data source with the ColdFusion
Administrator. Be sure to register the data-source name as
ProgrammingCF
.
The
CFQUERY
tag can retrieve data from a data source
by passing an SQL SELECT
statement to the data
source. The SELECT
statement specifies what data
to retrieve from the data source. For example, if you want to
retrieve all records from the EmployeeDirectory
table in the ProgrammingCF
data source, you can
use a CFQUERY
tag with a SELECT
statement like this:
<CFQUERY NAME="GetEmployeeInfo" DATASOURCE="ProgrammingCF"> SELECT * FROM EmployeeDirectory </CFQUERY>
This SELECT
statement uses a wildcard (*) to
retrieve all records from the EmployeeDirectory
table in the ProgrammingCF
data source.
Alternately, if you want to retrieve data from only a few columns as
opposed to all columns (don’t confuse this with all rows), you
can modify the SELECT
statement like this:
<CFQUERY NAME="GetEmployeeInfo" DATASOURCE="ProgrammingCF"> SELECT Name, Title FROM EmployeeDirectory </CFQUERY>
This query retrieves only the Name
and
Title
columns from each row of the database. This
type of query is used when you need only a subset of the data stored
in a data source. Retrieving only the data you need as opposed to the
entire table contents improves the overall performance of your
queries. It is much more efficient for a database to send a small
subset of data back to ColdFusion as opposed to an entire table,
especially when you need only a small portion of the larger data set
to begin with.
In general, it is not advisable to
retrieve data using SELECT *
. From a database
standpoint, selecting all fields using a wildcard creates a
performance hit, especially on larger record sets, because the
database has to do extra work to determine what fields to return. If
you really do need all the fields from a particular table returned in
your result set, still consider specifying them individually by name,
because it saves the database from having to construct the list.
You can further refine the SELECT
statement to
return only a limited number of rows of data based on a condition.
This is done by including the condition using the
WHERE
keyword. The idea at work here is to return
the smallest record set you need. The more specific the data returned
by a query is to your needs, the less work you need to have the
ColdFusion server do to process it. Executing the following
CFQUERY
returns just the names and email addresses
of employees in the IT department:
<CFQUERY NAME="GetEmployeeInfo" DATASOURCE="ProgrammingCF"> SELECT Name, Title FROM EmployeeDirectory WHERE Department = 'IT' </CFQUERY>
Note the use of the single quotes around the value
'IT'
in the WHERE
clause.
String values must always be enclosed in single quotes. Numeric,
Boolean, and date values may be specified without quotes.
You can extend this one step further, providing a dynamic value for
the condition in the WHERE
clause:
<CFQUERY NAME="GetEmployeeInfo" DATASOURCE="ProgrammingCF"> SELECT Name, Title FROM EmployeeDirectory WHERE Department = '#Form.Department#' </CFQUERY>
This example retrieves the name and title of each employee in the
department specified by a form variable called
Department
. Using this type of technique allows
you to build dynamic SQL statements that return different results
depending on form or URL input. Dynamic SQL is discussed in Chapter 11.
Once you
have data stored in a query object, the next step is to display it
using the CFOUTPUT
tag. The
CFOUTPUT
tag allows you to display data contained
in a query object by referencing the query name in the
QUERY
attribute. Example 4-1
queries the EmployeeDirectory
of the
ProgrammingCF
data source and outputs the results
to the browser using CFOUTPUT
.
Example 4-1. Outputting the Results of a Query in an HTML Table
<!--- retrieve all records from the database ---> <CFQUERY NAME="GetEmployeeInfo" DATASOURCE="ProgrammingCF"> SELECT ID, Name, Title, Department, Email, PhoneExt, Salary FROM EmployeeDirectory </CFQUERY> <HTML> <HEAD> <TITLE>Outputting Query Results</TITLE> </HEAD> <BODY> <H2>Employee Records</H2> <!--- create an HTML table for outputting the query results. This section creates the first row of the table - used to hold the column headers ---> <TABLE CELLPADDING="3" CELLSPACING="0"> <TR BGCOLOR="#888888"> <TH>ID</TH> <TH>Name</TH> <TH>Title</TH> <TH>Department</TH> <TH>E-mail</TH> <TH>Phone Extension</TH> <TH>Salary</TH> </TR> <!--- the CFOUTPUT tag is used in conjunction with the QUERY attribute to loop over each row of data in the result set. During each iteration of the loop, a table row is dynamically created and populated with the query data from the current row. ---> <CFOUTPUT QUERY="GetEmployeeInfo"> <TR BGCOLOR="##C0C0C0"> <TD>#ID#</TD> <TD>#Name#</TD> <TD>#Title#</TD> <TD>#Department#</TD> <TD><A HREF="Mailto:#Email#">#Email#</A></TD> <TD>#PhoneExt#</TD> <TD>#Salary#</TD> </TR> </CFOUTPUT> </TABLE> </BODY> </HTML>
In this example, the CFQUERY
tag executes a
SELECT
statement against the
EmployeeDirectory
table of the
ProgrammingCF
data source. The query retrieves all
the columns for all the records stored in the table. The template
then creates an HTML table and generates column headings using a
series of HTML <TH>
tags.
Next, the CFOUTPUT
tag is used in conjunction with
the QUERY
attribute to loop over each row of data
in the result set. With each iteration of the loop, a table row is
dynamically created and populated with the query data from the
current row. Note the double pound signs (##
)
before the hex color code in the <TR>
tag.
Because the color code is used within a CFOUTPUT
block, the pound sign that comes before the hex code must be escaped.
If is isn’t escaped, ColdFusion tries to interpret the color as
a variable and throws an error because no ending pound sign is found
Whenever you
perform a query using ColdFusion, four variables are automatically
created that contain information about the CFQUERY
operation and the result set it returned, if any. Here are the four
variables:
These variables can be used in countless ways and are used heavily throughout this book for such things as knowing how many records were returned by a particular query and breaking the display of query result sets into manageable chunks.
[6] Because portability from one database platform to another may be an issue, it’s not desirable to use an AutoNumber field as a table’s primary key value. The examples in this book use AutoNumber fields for primary key values as a matter of convenience.
Get Programming ColdFusion now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.