James asks,
Ray, do you prefer to use cfupdate, or SQL cfquerys for your database updates? What do you see as the advantages, disadvantages, etc. or each?
I have never used cfupdate. Ever. (Ok, maybe once to test it out, but I didn't inhale.) Why? Multiple reasons.
The first reason is more relevant to my recent move to Model-Glue. The cfupdate tag works with form data, and typically I do not directly access the form scope when using Model-Glue. While cfupdate would certainly work, it would be against the standards of MG development to do so. Ignoring Model-Glue for a moment, most of my SQL work is now done in CFCs where you don't want to be using the form scope either.
Secondly - while I don't know the guts underneath, I'd be surprised if bind variables were being used in the query. Therefore you would lose both the security as well as the performance you get with the cfqueryparam tag.
Third - I always feel a bit insecure about "helper" functions like this, especially when I can't dig in and see what is going on (see reason #2). Unlike Reactor and Model-Glue which also offer levels of abstraction, I can't see exactly what cfupdate is up to.
Fourth - while my update query may be simple now, I figure if there is a 5% chance later on that the query may not be simple, I might as well write out the sql now.
Do any of my readers use cfupdate? I should run a poll to see which is the least used tag. (Anyone using cftable?)
Archived Comments
I think I tried it once back in CF4 or 5 just for kicks and found that it ran about 20x slower than a cfquery with update SQL. For all of the reasons that you mention, I never use this tag. Ditto for cfinsert.
There's a cftable tag ?
But no, never used cfupdate/cfinsert I could never see what it gave me over cfquery, and as you point out there are plenty of issues with it.
I can point out some more reasons not to use it, from experience I shared back in 98 (when I had a tip list on my old systemanage.com site, before the days of blogs)
http://www.systemanage.com/...
http://www.systemanage.com/...
Ray's right to recommend against their use, as most would nowadays. Sadly, because lots of code uses them, I'm guessing Adobe/MM/Allaire were reluctant to pull them. They could discourage or deprecate them, but they probably fear affecting so much code. These appeared to make some sense to CF's original goal of making web apps "easy". Times changed and skills increased, and really it's time to put them to bed. Ray's great point about security alone is reason to avoid them.
Hello my name is Mark, (everyone drones, "Welcome Mark")
I am a cfupdate user. I started using back in the CF 3.1 days, and have never been able to kick the habit. I have tried quitting cold turkey but, then I come across a code snipit or an old project and I'm right back off the wagon again.
I use cfupdate as part of a in house CRUD system, that we have used on almost every we do. It solved a few problems and fit the need at the time.
On the bright side, This CRUD system is long over due for a make over. I hope to very soon replace this CRUD system with a new one based on Reactor or customized version datamgr.cfc.
Cfupdate has its own problems. Like, Why to I have to list the primary key in the list of fields that I want to update in CF6+? With its issues aside it does a fair job. (but, I'm still going to replace it first chance I get.)
OK, I don't do any CFC development but I'm trying to learn. You say that you should avoid the form scope when dealing with CFCs. Why is that?
Thanks.
I have tried most tags at one time or another.
I didn't like cfinsert/cfupdate for the reasons that you and Charlie gave.
Actually, I disagree with your third point. I think helper functions can be nice. After all, ColdFusion provides a lot of abstraction and most of it is pretty nice.
I have to say that cftable is one of the most worthless tags though (tried it once in my first few months of CF - didn't like it then and haven't looked back).
Add me to the list of people who never used it.
Mark,
I don't want to hijack Ray's post but I am curious what mods you would like for DataMgr.cfc. Mind hoping over to my blog (steve.coldfusionjournal.com) and posting a comment?
James,
The problem with using Form scope from a CFC is that using any shared-scope variable(of which Form is one) from within a CFC breaks encapsulation. I don't think I can explain the benefits of encapsulation in a comment, but a little Googling on the subject should turn up plenty.
so how do you put DB logic in cfcs? atm i include my DB logic using cfinclude, but it's not that optimal :)
anyway, do you use session scope or pass every form variable with some function to the cfc? or are there some different ideas?
any hints appreciated
On a tangential note to the "helper" function issue, I today stripped out from an unrelated page (actually from the delivered page source on the browser!) the javascript generated by cfform validation on a simple page to utilize on an AJAXed page.
This was because there was a form delivered as part of innerHTML from an AJAX-called script to the main page, and I wanted to make it required - this won't work using cfform within the called script because the cfform-generated javascript won't have loaded in the header of the calling page.
Because these cfform helpers generate the actual javascript that DOES give us a look "under the hood", why not just take the parts of the engine want?
BTW, I was the one who posed the cfupdate question to Ray mostly because I have it in some older scripts but have since bailed it, and wanted his take on it. But evidently I am still lazy enough to use cfform!
robs,
You will get a lot of answers to that question.
The main thing (for me) is to make sure that you explicitly pass in to the CFC everything that it needs.
I would suggest passing each form variable in as a separate argument as it makes for better documentation, but you can pass in the whole structure if you want (though you are really adding depenencies and therefor breaking encapsulation if you do).
The main thing is that you won't want to pass in the datasource on each method. To avoid that, instantiate the component using an init (so named by convention) method and then use the instantiated component to do your work.
Searches on cfobject and on ColdFusion init should help.
I have used cfupdate and cfinsert on occassion. I'll probably continue to use it (on occasion). There's many situations when it's not appropriate (probably moreso then not). I think they're good tags to use as long as you know when and when not to use them. Afterall, CF is all about RAD.
As for binding, I believe it does bind the parameters. I can't point you to any proof or links, but I remember reading something (something that seemed official) quite some time ago that led me to believe that binding does occur. I don't remember what it was, but that was my belief ever since.
I remember a couple occasions in particular when dealing with a difficult client in they really needed to add some functionality and didn't believe they needed to pay for it. I went into what I call "ColdFusion Extreme" development mode, ignoring all best practices and implementing the fastest, most RAD development efforts possible. This included the use of cfinsert/cfupdate and hey... it got the job done with little to no money loss on my side :)
I'd also like to throw out there that these tags can be useful when you just need to do some quick prototyping.
Nope, I don't use cfupdate. I always prefer to have control on my SQL queries.
I spoke to Mr Nimer, formally of Adobe, and he says cfupdate does indeed use bound parameters, so SQL injection would not be an issue. I'm surprised, but pleased that Adobe would ensure best practices there. This includes cfinsert as well.
robs, this is now a bit off topic, but if you search on blog for CFCs, you will find a wealth of posts on the topic. There is also a link im my Guides pod to cfc resources including the cfcdev listserv.
Nope on either - when looking at the two choices, it seemed that it would take (about) as long to actually write the SQL than use a helper tag. And in the end, the helper tag just seems to obscure things - here's another way to query/insert, but it has special restrictions on how it works with data.
I can see how it was added to make ColdFusion even more accessible to people with no SQL experience (and accessibility is a good thing), but it feels like a false path to leed people down for some reason.
A set of clear, simple to read, examples may do wonders in supporting people to SQL in place of the "accessibility tags".
well, there's an additional benefit to using it, in which no one's brought up. Maintanence. Changing table column names, adding new columns, etc. Depending on the changes, there may be no need to modify insert/update statements.
I think I put CFUpdate up there with CFInsert and CFTable, as the tags I've never used, even when I was learning CF.
Devin, if you change those names, then you need to change your forms or the cfupdate/cfinsert will break.
Steve - thanks. So the distinction is that the form scope is not used inside the CFC, where as you could use the form scope to pass in arguments to the CFC. Correct?
And getting on topic - I used CFINSERT and CFUPDATE very early on in a large project because they were simple and quick. But later they caused problems so I ripped them out and replaced them with standard SQL queries.
James,
That's right. Basically, so long as you are not directly accessing any shared-scope variable (like Form) from within your CFC you are OK.
That a variable came originally from a Form variable in immaterial to the CFC because it could have come from elsewhere.
Make sense?
I think of CFUPDATE as sort of a 'CF Newbie' tag. It doesn't give you as much flexibility with your update statements. You can't include conditional (if) statements in CFUPDATE, and I don't think you can use CFQUERYPARAM which is a great tag to protect your data.
Hi
I used it once, in my early days of CF. But for reasons I can't remember, the requirements of the DB processing pretty much immediately meant the functionality of <cfupdate> / <cfinsert> wasn't up to spec.
I've found this of pretty much every CF tag that tries to "help" (<cfform>, <cftable>, <cfgrid>, <cfchart>, <cfmail>, <cfsearch> etc). They seem to kinda do something sort of almost useful, possibly as far as a proof-of-concept implementation goes, but once I have a real requirement, they have simply never cut it. This is why - referring to all the CF8 wishlists doing the rounds @ present - I'd rather see enhancements to the base language, bugfixes and performance improvements than more "bells and whistles".
--
Adam
Steve - Thanks. That makes perfect sense.
To me these tags are evil. Even if you're absolutely kick-ass at coldfusion, OO, and design patterns (which I'm not :D), you also need to master SQL when it comes to web development. Even much more so than HTML or CSS, if you ask me.
I think tags like those make it difficult to get good at it. On top of that you have less control over your sql, security, hints, and so on.
Again, one could argue that the whole purpose of CF is to make things more simple, but I think these tags take it a bit too far. It brings us back to that old post about the 2 types of CF developers doesn't it? ;-)
tof