Excerpted from CF Advisor, May 1999.

Modifying Headers (Title, JavaScript) After a CFINCLUDE

Counting Large Recordsets, The Right Way

Modifying Headers (Title, JavaScript) After a CFINCLUDE

Most have discovered that CFINCLUDE is one way to store and reference common header information that should be used on several pages. Place your top-of-page information in a file (<HEAD> and <BODY> tags with appropriate colors, perhaps a navigation bar, for instance), and simply reference this on each page with a CFINCLUDE. A nice re-use of code, and it makes it easy to modify the nav bar when needed.

But some may be reluctant to use this approach because it restricts their ability to place template-specific information in the header, such as a <TITLE>, or more importantly, any JavaScript intended to appear within the page's HEAD tags.

Fortunately, there is a ready--and perhaps often missed--solution to this dilemma. The CFHTMLHEAD tag is designed specifically to insert any text into the <HEAD> section of a template, and it can be included anywhere on a page, including after a CFINCLUDE that has otherwise placed other header tags on the page.

A simple example would be:
<CFHTMLHEAD TEXT="<TITLE>Registration Form</TITLE>">

Note that you simply include in the tag's TEXT parameter any code that should appear in the template's HEAD section when rendered on the browser, tags and all. Of course, this may seem cumbersome for a long set of JavaScript, but there's no reason you can't add that as well, as in:
	
<CFHTMLHEAD TEXT=
	"<TITLE>Process Registration Form</TITLE>
	 <SCRIPT>
		LANGUAGE='javascript'>
		function test(){ alert('test')}
	</SCRIPT>" >
		

Note that in this case, you may want to convert any double quotes used to be single quotes, or use CF's CHR(34) function to cause the double quotes to be written without confusing the CFML interpreter.

You might gain even greater flexibility by converting the CFINCLUDE to a call of a custom tag. That way, you could pass in attributes to change other characteristics in the "common header." For instance, if your INCLUDEd code contains the BODY tag, you'll have a problem if you intend the JavaScript to be called via an ONLOAD event on the BODY tag--that is, to be called in some templates but not in others. But if you "include" the header via a call to a custom tag instead, you could optionally pass in such an ONLOAD (or similar) event.


Counting Large Recordsets, The Right Way

This is an extension to last month's tip about not using a "SELECT *" when it's not necessary. That tip discussed how obtaining more than just the columns you need can bog down your query. An even more dangerous mistake is using a "SELECT *", followed by a test of the query's "recordcount," just to determine the number of records in the query.

If the ONLY purpose of the query is to obtain a count, you'll see dramatic reductions in the query time if you change the "SELECT *" to a "SELECT COUNT(*)".

The problem is that SELECT * returns every column of every record (in the table, or matching any WHERE clause) and stores it in the CF server memory for later processing. That takes both database processing time to gather all the columns from all the records, data transmission time to send the data between the database and the CF server (even if on the same box), and CF processing time to manage and store that data in memory.

The huge mistake is that, if you're not going to refer to ANY of those columns on ANY of the records and mean only to refer to the query's recordcount to count the records, you've asked for a potentially enormous amount of work just for that result.

Using just SELECT COUNT(*) will do it much more efficiently. It asks the database server simply to count the number of records in the table (having whatever WHERE criteria you may optionally specify), and returns that count. It returns the count as a column in the resultset, though, so rather than testing the query's "recordcount", you'll want to test this column in the query result set. And, of course, in order to reference such an "aggregate" column in CF, you'll need to give that column a name in the query using an "AS" clause, such as "SELECT COUNT(*) AS RECCOUNT".

This is the kind of problem that may not present itself early in a development cycle, if the tables are small, so it's easy to make the mistake and not pay any penalty. But as the tables grow, the effect can be disastrous, though it may not be apparent since it will often grow slowly.

In one case, a count being presented on a front page was causing that page to eventually slow to a crawl. Investigation identified this mistake, and the simple change caused the query's execution time to be reduced from 10,000 milliseconds to just 248!

Tips Contents:

| Home | ColdFusion | Articles | Presentations
| User Groups | Other Resources | Press Releases | Company

© 1998-2024, Charles Arehart, SysteManage
Our Practice Makes You Perfect