33Writing CFX Tags with Visual C++
NOTE
Queries cannot be passed using any attribute name other than query; therefore, only one query can be passed to any given CFX
tag. In contrast, CFX tags are free to return as many queries as they wish, simply by calling
pRequest->AddQuery() multiple
times (using a different query name each time).
Once the tag’s attributes have been reasonably validated, execution continues to the next portion of
the code (beginning with the series of
double declarations). After defining a few local variables, this
portion of the code uses two
for loops to perform the necessary mathematical calculations. Each of
the loops iterates from 1 to the number of rows in the query; within the loops, the value of the
Row
variable indicates the row currently being processed. The first thing each of these loops does is to
populate a string variable called
thisVal with the current value of the column specified in the tag’s
COLUMN attribute. It’s worth noting that values retrieved from queries are always retrieved as strings;
if you want to work with values as numbers, you need to use
atof() or some similar function to
convert the string to the desired numeric data type.
Speaking of which, the first loop uses an
if test to make sure that the length of the current row’s
value is not zero (that is, to make sure that the value is not an empty string). If it is, that probably
means that a
NULL is occupying that row of the query. ColdFusion represents null values as empty
strings whenever such a value is accessed as string; since
GetData() always accesses all data as strings,
you will always get an empty string for any null value in a query.
If the value is not an empty string, the tag adds the current numeric value to the
dTotal variable and
increments the
iValueCount variable by one. When the first for loop is complete, dTotal will hold
the total (sum) of all numbers in the data set, and
iValueCount will hold the number of data points
included in the total (that is, the number of rows that were not skipped because of suspected null
values).
If, on the other hand, a particular value is determined to be an empty string, the code checks to
see if the tag has been called with a
DEBUG attribute. If so, it uses pRequest->WriteDebug() to display
a debugging message whenever an empty string is found in the data set. See the “Generating Debug
Output” section, later in this chapter, to see what the debugging messages look like.
In any case, as long as at least one valid data point was found in the query, the next line of code
computes the mathematical average (mean) of the data points by dividing the
dTotal by iValueCount.
The average is stored in the variable called
dMean (which is not meant to imply that it’s demeaning
to be average). Next, another
for loop is used to iterate over the set of numbers again, this time
subtracting each value from the mean and squaring the result. After this loop finishes, the average
of these results is computed by dividing by the number of data points; this is called the variance.
The square root of the variance is then computed with the standard
sqrt() function; this is the
standard deviation.
The tag has now completed its work, so the only thing left to do is to return the standard deviation
to the calling ColdFusion page using
pRequest->SetVariable(). Since SetVariable() only accepts
string values, the standard deviation must first be converted to a string using the standard
gcvt()
function.
Commenti su questo manuale