ColdFusion Tips and Tutorials

ColdFusion Tips and Tutorials. Tips on ColdFusion, AJAX, CSS, JavaScript, HTML, Design, and more.

CFUnited Developer Conference 2010
Use this code TIPSCUST to get $100 off your registration @ CFUnited! We'll see you There!


ColdFusion Tips
Page 1 2 3
148 ColdFusion, Ajax, FuseBox, Tips, and Tut
147 Included Point of View
146 Javascript - OnFocus
145 Nathan's Rules of Professional Web Desig
144 Universal Server-Side Check | Bandwidth
143 Meeting Schedule | Identification Sessio
142 Breaking Frames Without Javascript
141 Unreal Forms
140 Screen Resolution
139 Human Help
138 Better Server-Side Validation
137 Automatic Server-Side Validation
136 Regular Expression Laboratory,ColdFusion
135 Rank-Ordered Site Search
134 Building Cryptograms
133 Well-Formed Includes
132 Grouping Families for Visits
131 Display Families on a Map Grid
130 Slide Shows
129 Determine Your Database Engine
128 ColdFusion in Context: Maxlength Lies
127 Something Extra
126 Parsing Database Structure from Data Def
125 Valid Values Maintenance
124 Print 1
123 Hide Session Id
122 Downsizing Data to Access
121 Time to Load a Page, FuseBox 4
120 Order and Rank by Subset
119 Warn through E-mail & Update on Paste Sp
118 Paste Spreadsheets, ColdFusion Component
117 Review Files Having Fixed-Length Fields
116 Organized Help
115 Sequence Slider
114 Bad Bits
113 Logical Deduction
112 Whiteout
111 Forced Navigation
110 Managing Permissions
109 Time Travel
108 Test First
107 Get Distance Between Map Coordinates
106 Validating Checkboxes
105 Matrix Manipulation
104 Field Help
103 Fake Object Not Found
102 Rank Order Correlation Coefficient
101 From Calling Pairs to Calling Tree
100 Posting Notice
99 Logout Persuasion
98 Release Session Memory
97 Use Identically Named Fields
96 Web Bug
95 Password Generation
94 Core Queries
93 Use CFFTP
92 Insert, Update, and Delete
91 Stack
90 T-Value
89 Bulk Data Entry and E-mail Validation
88 Quick Reset
87 Design 1
86 Use CFFTP
85 Support Login with AutoPost
84 Login and Site Protection
83 XY Graphs in a Graphing Calculator
82 Read Encrypted Files
81 Showing Progress
80 Frugal Cross-Browser Javascript
79 Tabbed Folders
Page 1 2 3



Custom Search
ColdFusion TIPS PLUS


Issue 00094 http://www.cftipsplus.com

I. My Comments

II. ColdFusion In Context: Core Queries
By R. Martin Ladner
martin.ladner@knology.net


I. Comments:

Thanks for reading cftips ezine. If you want to help cftipsplus.com grow please send in your support... time or money. I am wanting to gain some help to make this site grow much bigger.


Keep Coding,
Nathan Stanford
http://www.cftipsplus.com

If you have suggestions for articles send them to us.
If you would like to write for cftipsplus.com
send us an email to:

admin@cftipsplus.com

IF YOU WANT TO BE AN AUTHOR SEND IN YOUR COLDFUSION TIPS.

Remember this is a great way to get your name known in the
ColdFusion Community.



Advanced, Intensive ColdFusion Training!

Visit this site. If you have plans to get training here is a company that provides Advanced, Intensive ColdFusion Training. Check them out.

http://www.coldfusiontraining.com/index.cfm?ref=cftipsplus



CFM - The ColdFusion Monthly!
http://www.ColdFusionMonthly.com

By becoming a .CFM subscriber, you'll receive. ColdFusion information you will not find anywhere else:
Tips, tricks, techniques, strategies, and a wealth of knowledge you will be able to apply immediately to your work, all from established developers.

Monthly access to new articles written by industry-leading ColdFusion experts. A fully-functional application that accompanies each issue.

Full access to all issues, past and present (with a one year paid subscription). The chance to be seen in our "Community Spotlight" corner, which showcases new writers and emerging talent


If you have any suggestions please email me at cftips@nsnd.com.


II. ColdFusion in Context: Core Queries
By R. Martin Ladner
martin.ladner@knology.net



Suppose you have standard code you use to support every insert, update, and delete. Perhaps you use a try-catch combination for every database change. You've noticed that your support code is larger than the actual query. What can you do to avoid having to manually add this code to every query you write? This tip shows one way.
Set the Stage

To demonstrate changing a database, you'll need infrastructure. Because this technique lends itself well to re-use, you'll want an appropriate directory structure. You'll also need a table to modify. A pick list is appropriate to select records for update and deletion. An entry form supporting insert and update is also necessary.
Create Directories and a Table for the Demo
Directories organized by function (not by application) would be nice, and you'll need a table for the demo. Make the following directories under a common parent: work and querybin. Create a table named Item. The Item table needs a numeric ItemID, a text ItemName and a text ItemNo (to be used as you would use the part number in a catalog).

Make a Pick List
You'll need a page that displays existing rows and lets you pick one of them to modify or lets you prepare to insert a new row; call this code pick.cfm. It's fed by a straightforward select query. This particular form has an edit button for each row and a delete button for each row.

<cfquery name="getList" datasource="context">
select * from Item
</cfquery>
<form name="pick" action="form.cfm" method="post">
<table>
<tr><td>EDIT</td><td>NAME</td><td>NUMBER</td><td>DELETE</td></tr>
<cfoutput query="getList">
<tr>
<td><input type="submit" name="editme" value="#ItemID#">
</td><td>#ItemName#</td><td>#ItemNo#</td>
<td><input type="submit" name="delme" value="#ItemID#"></tr>
</cfoutput>
</table>
</form>

Make a Dual-Action Form
This form supports the pick list when update or delete is requested; call it form.cfm and put it in the work directory. If delete, the form deletes the record. If update, the entry fields are pre-filled from the selected record.
This form also implements an insert function. If the mode is not update, the entry fields are pre-filled from an empty query to which an empty row has been appended using the QueryAddRow function.

Finally, the page returns to the URL in the "Return" variable, form.cfm in this case. If there was a problem with an insert, update, or delete attempt, the page performing that function will return the problem in a query string attached to the URL of this page. The "Problem", if any, will be displayed on this page. The exit button takes the user to a page you have defined. (It will fail if you don't define it.)


<!--- Respond to pick.cfm --->
<cfparam name="form.editme" default="">
<cfparam name="form.delme" default="">
<cfparam name="form.addme" default="do this">
<cfset Return="../work/form.cfm">
<cfparam name="url.Problem" default="">
<cfoutput>#Problem#</cfoutput><br>
<cfif len(form.editme)>
<cfset myaction="../querybin/chgitem.cfm">
<cfquery name="getItem" datasource="context">
select * from Item
where ItemID = <cfoutput>#form.editme#</cfoutput>
</cfquery>
EDIT <cfoutput>#form.editme#</cfoutput><br>
<cfelse>
<cfquery name="getItem" datasource="context">
select * from Item
where 1 = 0
</cfquery>
<cfset dummy=QueryAddRow(getItem)>
ADD<br>
<cfif len(form.delme)>
<cfinclude template="../querybin/delitem.cfm">
<cfset form.delme="">
<cfelseif len(form.addme)>
<cfset myaction="../querybin/additem.cfm">
</cfif>
</cfif>
<!--- Accept data for insert or update --->
<form name="myForm"
action=<cfoutput>
"#myaction#"</cfoutput> method="post">
ItemName: <input type="text" name="ItemName"
value=<cfoutput>
"#getItem.ItemName#"</cfoutput>
size="22" maxlength="20"><br>
ItemNo: <input type="text" name="ItemNo"
value=<cfoutput>
"#getItem.ItemNo#"</cfoutput>
size="6" maxlength="5"><br>
<input type="button" name="dothis" value="Exit"
onClick="document.location='../yoursite.cfm'; return false;">

<input type="reset" name="dummy" value="Reset">
<input type="submit" name="dothis" value="Submit">
<input type="hidden" name="ItemID"
value=<cfoutput>
"#getItem.ItemID#"</cfoutput>>
<input type="hidden" name="Return" value=<cfoutput>"#Return#"</cfoutput>>
</form>

<!--- Pick for update or delete --->
<hr>
<cfinclude template="pick.cfm">

Consider Core Queries
If you can wedge a core query into your support code without changing that code, you can use a single copy of that support code for all your inserts, another for all your updates, and another for all of your deletes. That's what having a core query does for you.
Craft a Core Insert Query

Call this core query document additem.cfm, and put it in the querybin directory. Because this is an insert, your support code might do a query on its own to get the next ID number and will therefore need the table name and the name of the table's ID element (key). Any query will need the core query itself. The name of the page to return to can be set by the page that calls this one and can be ignored here.

The Table and Key names are readily passed in variables. The query can be stored in a string (named Core). Notice that this is straight SQL except for the ColdFusion variables and the question marks around ID1.

ID1 surrounded by question marks represents the value that WILL be used for the desired key but which is not yet defined and therefore should be treated as text now but as a variable later. Your support code will turn this into a ColdFusion variable and then fill in the key value it has obtained before it actually performs the insert.

Finally, this query document includes the page that contains the support code for the kind of action being performed: insert, update, or delete. In this case, it's insert, to be performed by add.cfm.


<cfset TableName="Item">
<cfset KeyName="ItemID">
<cfset Core="insert into #TableName#
(#KeyName#, ItemName, ItemNo)
values (?ID1?, '#form.ItemName#', '#form.ItemNo#')"
>

<cfinclude template="../querybin/add.cfm">

Make a Core Update Query
The update is simpler; call it chgitem.cfm and put it in the querybin directory. You don't have to specify the name of the key field. Because only one query is involved, you don't have to specify the table name separately if you don't need to repeat it in a problem alert. You only need the core query itself, the name you want it to have, and the name of the page that will execute it: chg.cfm.

<cfset Core="update Item set
ItemName = '#trim(form.ItemName)#',
ItemNo = '#trim(form.ItemNo)#'
where ItemID = #form.ItemID#"
>

<cfset QueryName="chgItem">
<cfinclude template="../querybin/chg.cfm">

Make a Core Delete Query
The delete query is similar to the update query; call it delitem.cfm and put it in the querybin directory. It will be executed by chg.cfm.

<cfset Core="delete from Item
where ItemID = #form.delme#"
>

<cfinclude template="../querybin/del.cfm">

Modify Your Insert Support Code
You may do inserts by wrapping a cftransaction tag around a check for the last-used ID number and the insert query that uses the next ID number. You may in turn wrap that inside a try-catch combination. You may wrap that inside a loop to try a few times before reporting failure. Code like this can nevertheless interface easily with a core query.

The general idea in this demo is that a query in the support code goes after the highest key value currently used and stores the next available value in the variable ID1, which is then used as the key in the insert query.

There are two important differences between hard-coding the query within this structure and using a query stored in a string. For insertion, after you determine the key value to be used, you need to convert the text representing that value (?ID1? in this case) to a ColdFusion variable that will carry the key value into the query. The string "?ID1?" must be changed to "#ID1#" where it appears in the insert query. The conversion must take place after ID1 is defined; that's why ID1 can't be specified as a variable when the core query is first written. The second difference holds true for all queries stored in a string: the preserveSingleQuotes function must be used to avoid dropping the single quotes from the query.

Here's what the result looks like. Notice that it contains no table-specific code and can be used to support any single-key insert query. Call it add.cfm and put it in the querybin directory.


<!--- Begin the loop --->
<cfset try=0>
<cfloop condition="try lt 4">
<cfset try=try+1>
<cfset Qstring="">

<cftry>
<cftransaction>
<cfset Qerr=0>
<!--- (no error yet) --->

<!--- Get next ID for single-element key --->
<cfquery name="getMax1" datasource="context">
select max(#KeyName#) as Max1
from #TableName#
</cfquery>
<cfif len(getMax1.Max1)>
<cfset ID1=getMax1.Max1+1>
<cfelse>
<cfset ID1=1>
</cfif>

<!--- Try to add the row --->
<cfset Core1=replaceNoCase(Core,"?ID1?","#ID1#")>
<cfquery name="add" datasource="context">
<cfoutput>#preserveSingleQuotes(Core1)#</cfoutput>
</cfquery>

</cftransaction>

<!--- Exit here when OK --->
<cfbreak>

<!--- Retry up to max times --->
<cfcatch type="database">
<cfif try gt 3>
<cfset Qstring="?Problem=Repeatedly failed to add to database; try again later or notify maintenance.">
<cfbreak>
</cfif>
</cfcatch>
</cftry>
</cfloop>

<cfset myURL="#Return##Qstring#">
<cflocation url="#myURL#">

Handle Updates
Update code is similar except that there is only one query, and it has to be given the name passed in a variable from the calling page. Call this code chg.cfm, and put in the querybin directory.

<!--- Begin the loop --->
<cfset try=0>
<cfloop condition="try lt 4">
<cfset try=try+1>
<cfset Qstring="">

<cftry>
<cftransaction>
<cfset Qerr=0>
<!--- (no error yet) --->

<!--- Try to change the row --->
<cfquery name="#QueryName#" datasource="context">
<cfoutput>#preserveSingleQuotes(Core)#</cfoutput>
</cfquery>

</cftransaction>
<!--- Exit here when OK --->
<cfbreak>

<!--- Retry up to max times --->
<cfcatch type="database">
<cfif try gt 3>
<cfset Qstring="?Problem=Repeatedly failed to change database; try again later or notify maintenance.">
<cfbreak>
</cfif>
</cfcatch>
</cftry>
</cfloop>

<cfset myURL="#Return##Qstring#">
<cflocation url="#myURL#">

Handle Deletes
Delete code is even simpler. Call this code in del.cfm, and put it in the querybin directory.

<!--- Begin the loop --->
<cfset try=0>
<cfloop condition="try lt 4">
<cfset try=try+1>
<cfset Qstring="">

<cftry>

<!--- Try to delete the row --->
<cfquery name="del" datasource="context">
<cfoutput>#preserveSingleQuotes(Core)#</cfoutput>
</cfquery>

<!--- Exit here when OK --->
<cfbreak>

<!--- Retry up to max times --->
<cfcatch type="database">
<cfif try gt 3>
<cfset Qstring="?Problem=Repeatedly failed to delete from database; try again later or notify maintenance.">
<cfbreak>
</cfif>
</cfcatch>
</cftry>
</cfloop>

<cfset myURL="#Return##Qstring#">
<cflocation url="#myURL#">

Summary
To try this out, browse form.cfm in the work directory. Coding for additional tables doesn't have to take a long time. You can create core queries simply that share this common infrastructure. You can build forms using the lessons contained in this demo. Extend these techniques and share the wealth.
=Marty=



Publisher and Creator:
Nathan Stanford,
admin@cftipsplus.com
C.F. Concepts, Inc.
http://www.cftipsplus.com

Macromedia and ColdFusion are U.S. registered trademarks.


Copyright (c) 2000 - 2001 CFTIPSPLUS.COM and NSND.COM
Permission is granted to circulate this publication via
MANUAL forwarding by email to friends provided that the text is
forwarded in its entirety and no fee is charged.

Photo of Nathan Stanford
Nathan Stanford
LinkedIn

R. Marty Ladner's
Site