| By Ian Rutherford | Article Rating: |
|
| December 3, 2001 12:00 AM EST | Reads: |
13,012 |
Why should ColdFusion analyze the query results when the database could do it and you could save the bandwidth for something that really needs it?
In Part 1 of this article (CFDJ, Vol. 3, issue 10) I introduced stored procedures and performed some basic tasks with them. In this article I show how to do more complex tasks that involve IF/ELSE statements, looping, and string manipulation.
First, see Listing 1; how often have you had to do something similar? Let's say you just received a note from your product supplier stating that Item 20 has a new, lower everyday price of $15. Now your store is running a special in which you give away certain items, but you can't remember if Item 20 is one of those items. You could either look up the item and its cost and then decide whether to send another request to the database to update the price, or simply tell the database which item you want to edit, its new cost, and let the database do everything else.
To process this request the database needs two pieces of information: the item number and the price. The ColdFusion end of the procedure looks like Listing 2.
In the database we need to say what the procedure will be called (I begin all my procedures with "pr_" to identify them as stored procedures. It may seem to make more sense to use "sp_", but "sp_" is used for system stored procedures that can be accessed from any database on the server.)
CREATE PROCEDURE [pr_ItemCost]
We add our variables:
@ItemNo [int],
AS
@Cost [money]
Then we write the SQL statement. First we need the current value for cost because if it's zero, we aren't going to change the amount. If we only want to know if the cost is zero but don't care what it is if it's not zero, we can use the @@ROWCOUNT function instead of actually setting local variables and doing comparisons. (@@ROWCOUNT is a function that tells how many rows were affected by the previous statement.)
SELECT CostLet's look at this code. In the first select statement we determined if Item 20 had a cost of zero. By querying for the item with a cost of zero we could get two results: one row or zero rows. @@ROWCOUNT tells us how many were returned. If @@ROWCOUNT=0, then Item 20 has a cost that's not zero.
FROM Items
WHERE ItemNo = @ItemNo
AND Cost = 0IF @@ROWCOUNT = 0
BEGIN
UPDATE Items
SET Cost = @Cost
WHERE ItemNo = @ItemNo
END
Our IF statement requires a BEGIN and an END command to let the database know where to stop the execution of the IF statement. In between we put our update statement that will change the price of the item only if its original price wasn't zero.
What if we do care what the cost currently is? Maybe we have a company policy that items under $10 will only increase in cost by $3 or the new cost, whichever is less, but everything else that isn't free increases to whatever the new cost is. Normally, you would change your CF code to reflect the business rules, but with stored procedures you can keep the two separate. This will keep your Web developers happy because they probably enjoy making new site features more than getting into the minutia of business rules.
The procedure starts the same but we'll need a local variable within the procedure to hold the current cost of the item:
CREATE PROCEDURE [pr_ItemCost]Then we need to add our variables:
@ItemNo [int],Finally, we need to use our business rules to decide if the cost should change:
@Cost [money]AS
DECLARE
@CurrentCost [money]
Next, we need to set this new variable equal
to the current value using a special select statement:SELECT
@CurrentCost = Cost
FROM Items
WHERE ItemNo = @ItemNo
IF @CurrentCost = 0Notice that each piece of the IF/ ELSE statement requires its own BEGIN and END. You can include as many IF/ELSE statements as you need, and you don't need to include a final ELSE clause, just as in ColdFusion.
BEGIN
. . .
END
ELSE IF @CurrentCost < 10
BEGIN
. . .
END
ELSE
BEGIN
. . .
END
IF/ELSE statements are useful but what's really helpful is the ability to replace some of your CFLOOPs over recordsets with a single stored procedure, saving you many trips to and from the database.
Let's assume that the items in our store can be assigned to various special occasions. One way to do this is to have a multiple select-box form submitted to a template that would loop over the list, adding a row to the database each time. If you have the following list of events: birthday, wedding, Mother's Day, anniversary, and graduation, you could have up to five separate calls to the database. Instead, let's pass the entire list to the database and let the database do the looping.
Looping in SQL consists of using WHILE instead of LOOP. This is similar to using conditional CFLOOPs.
We want to loop over the list, add each value to the database, then remove it from the list until the list is empty. This will require some string manipulation as well as looping. This complete procedure can be seen in Listing 3.
CREATE PROCEDURE [pr_AddItemEvents]@ListLength will hold the character count of our list. @ CommaCount holds the position of the first comma in our list.@ItemNo [int],
@EventList [varchar](40),
@EventValue [int]AS
DECLARE @ListLength [int],
@CommaCount [int]
SETLen() in SQL works the same as in CF
@ListLength =
Len(@EventList)
WHILE @ListLength >0CHARINDEX tells us at what character count the first match for the pattern occurs.
BEGIN
SET
@CommaCount = CHARINDEX(',', @EventList)
We need to know this so we can properly extract our values from the list. Use the function PATINDEX if you need to match strings with wild cards (*, %).
IF @CommaCount > 0@Event Value is the current value in the list. If there's a comma in the list we need to take all the characters starting at 1 and ending right before the comma, which is why we use @CommaCount -1.
BEGIN
SET
@EventValue =
SubString(@EventList, 1, @CommaCount-1)
END
ELSEIf there aren't any commas we can set @EventValue equal to whatever is left in the list.
BEGIN
SET @EventValue = @EventList
END
INSERT INTO Event_Items_XrefIf we were doing the looping on the CF server instead of in the database, we would repeatedly have to call this query through ColdFusion.
(Item_Fk,
Event_Fk)
VALUES
(@ItemNo,
@EventValue)
IF @CommaCount > 0If we have commas in the list we need to remove the current item and the trailing comma from the list. The Right function works the same way in ColdFusion as in SQL.
BEGIN
SET
@EventList =
Right(@EventList, @ListLength-@CommaCount)
END
ELSEIf there aren't any commas in the list, the list is at its last value so we can remove the last value from the list.
BEGIN
SET @EventList = ''
END
SET @ListLength = Len(@EventList)We need to reset the list length after each loop so that the WHILE statement can check the current length. When the length equals zero, the loop stops running.
END
This article presented several useful programming constructs that will save your applications from multiple trips to the database. However, stored procedures can do much more. For example, stored procedures have access to SQL objects called cursors. A cursor is a result set that you can loop over one row at a time - similar to using CFOUTPUT with a query. This is handy for shopping carts in which each line item needs processing as it's added to an order.
There are also several special stored procedures that allow you to use the command line, similar to CFEXECUTE, and registry editing commands, similar to CFREGISTRY. Finally, as with ColdFusion, you can create special C++ objects that can be accessed through stored procedures, making it possible to move complex programming off the Web server and into the database.
If you want to find out more about MS stored procedure programming, I recommend the book SQL Server 2000 Stored Procedure Programming by Dejan Sunderic and Tom Woodhead (Osborne Press). This book covers all the basics as well as more advanced topics including OLE and XML integration. I also recommend opening up the SQL Server Books Online (www.microsoft.com/sql/techinfo/productdoc/2000/books.asp) every time you have a question about syntax or possible functions. They're a very thorough reference and better than any SQL reference book you can buy.
Published December 3, 2001 Reads 13,012
Copyright © 2001 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Ian Rutherford
I have been working with CF for two years and am currently the designer of CatholicStore.com and Catholicliturgy.com. I have been working with SQL for two years and started working with stored procedures about two months ago as we began an update of CatholicStore.com. Both sites are built using the Fusebox methodology.
I graduated from the University of Dallas in 1996 with a Political Philosophy degree which explains why I do web programming.
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe Reader Sued
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Adobe LiveCycle Enterprise Suite 2 for Cloud Computing
- Adobe Cans Another 9% of its Workforce
- Adobe Betas Target RIAs and Cloud Computing
- Adobe MAX 2009 Online
- Thinking of Flex in London
- Moyea DVD4Web Converter V2.0 Converts DVD to FLV Fast and Synchronously with Watermarks
- Adobe & Salesforce Cut Cloud Deal
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Eval JavaScript in a Global Context
- Fig Leaf Software to Exhibit at Government IT Conference & Expo
- Is Microsoft as Free as Open Source?
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe Reader Sued
- The Planet Named “Bronze Sponsor” of Cloud Computing Expo
- Microsoft Expression Web Has Got Game
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Bruce Chizen Joins Voyager Capital as Venture Partner
- My Top Seven Wishes From Adobe MAX 2009
- Adobe Flex Developer Earns $100K in New York City
- The Next Programming Models, RIAs and Composite Applications
- Where Are RIA Technologies Headed in 2008?
- Constructing an Application with Flash Forms from the Ground Up
- AJAX World RIA Conference & Expo Kicks Off in New York City
- CFEclipse: The Developer's IDE, Eclipse For ColdFusion
- Personal Branding Checklist
- Adobe Flex 2: Advanced DataGrid
- Has the Technology Bounceback Begun?
- Building a Zip Code Proximity Search with ColdFusion
- i-Technology Viewpoint: We Need Not More Frameworks, But Better Programmers
- The Asynchronous CFML Gateway
- Web Services Using ColdFusion and Apache CXF





































