January 13, 2005 at 10:18 am
Hi Gents and Ladies,
I am trying to get GoTo written out of the coding standards at work. Everything I read argues that it is really bad practice, I agree with this and most of the reasoning behind this.
Are there any circumstances where it is 'unavoidable'?
Does anyone think GoTo is acceptable practice?
All thoughts appreciated........
Have Fun
Steve
We need men who can dream of things that never were.
January 13, 2005 at 10:30 am
I guess that the following may help
Sounds like this will be an interesting thread......
Good Hunting!
AJ Ahrens
webmaster@kritter.net
January 13, 2005 at 11:08 am
Hi,
I usually try to stay away of GOTO statement but i have to admit that i've used it a few time in the past for error handling...
Ex:
IF @@ERROR <> 0 GOTO ERRORHANDLER
ERRORHANDLER:
... error handling logic
Aiwa
January 13, 2005 at 3:25 pm
January 13, 2005 at 7:28 pm
First the funny thing is I didn't even know it existed in T-SQL until about a year ago when someone posted a piece of code containing it somewhere I was viewing.
As for it's usefullness I would have to say that 99.9% of the time people use it out of habit in there coding practices more than need.
Ex.
DECLARE @var1 datatype, @var2 datatype
SET @var1 = (SELECT column FROM table WHERE column = condition)
IF @var1 = x GOTO HERE
SET @var2 = 24
HERE:
--DO SOME STUFF
The overall complexity doesn't require a goto statement if they used exists in an if or if...begin...end so it really is applied without a solid purpose.
'
However with that said if you had a more complicated need of a lot of if statements in a row and had a common section of code you may find a reall good need for coding simplicity to use GOTO.
Ex.
DECLARE @var1 datatype
IF EXISTS(SELECT column FROM table1 WHERE column = condition)
BEGIN
SET @var1 = 'table1'
GOTO HERE
END
IF EXISTS(SELECT column FROM table2 WHERE column = condition)
BEGIN
SET @var1 = 'table2'
GOTO HERE
END
IF EXISTS(SELECT column FROM table3 WHERE column = condition)
BEGIN
SET @var1 = 'table3'
GOTO HERE
END
IF EXISTS(SELECT column FROM table4 WHERE column = condition)
BEGIN
SET @var1 = 'table4'
GOTO HERE
END
IF EXISTS(SELECT column FROM table5 WHERE column = condition)
BEGIN
SET @var1 = 'table5'
GOTO HERE
END
IF EXISTS(SELECT column FROM table6 WHERE column = condition)
BEGIN
SET @var1 = 'table6'
GOTO HERE
END
IF EXISTS(SELECT column FROM table7 WHERE column = condition)
BEGIN
SET @var1 = 'table7'
GOTO HERE
END
HERE:
--DO SOME STUFF
Which may be a lot easier to do what you need than say writing
Ex.
DECLARE @var1 datatype
IF EXISTS(SELECT column FROM table1 WHERE column = condition)
BEGIN
SET @var1 = 'table1'
END
ELSE
BEGIN
IF EXISTS(SELECT column FROM table2 WHERE column = condition)
BEGIN
SET @var1 = 'table2'
END
ELSE
BEGIN
IF EXISTS(SELECT column FROM table3 WHERE column = condition)
BEGIN
SET @var1 = 'table3'
END
ELSE
BEGIN
IF EXISTS(SELECT column FROM table4 WHERE column = condition)
BEGIN
SET @var1 = 'table4'
END
ELSE
BEGIN
IF EXISTS(SELECT column FROM table5 WHERE column = condition)
BEGIN
SET @var1 = 'table5'
END
ELSE
BEGIN
IF EXISTS(SELECT column FROM table6 WHERE column = condition)
BEGIN
SET @var1 = 'table6'
END
ELSE
BEGIN
IF EXISTS(SELECT column FROM table7 WHERE column = condition)
BEGIN
SET @var1 = 'table7'
END
END
END
END
END
END
END
--DO SOME STUFF
Either way you get the same net effect but from a readability standpoint using the GOTO method is simpler as well as less likely to trip you up in making sure on the pieces are where they need to be.
Now someone might point out you could write this way
Ex.
DECLARE @var1 datatype
IF EXISTS(SELECT column FROM table1 WHERE column = condition)
BEGIN
SET @var1 = 'table1'
END
IF EXISTS(SELECT column FROM table2 WHERE column = condition)
BEGIN
SET @var1 = 'table2'
END
IF EXISTS(SELECT column FROM table3 WHERE column = condition)
BEGIN
SET @var1 = 'table3'
END
IF EXISTS(SELECT column FROM table4 WHERE column = condition)
BEGIN
SET @var1 = 'table4'
END
IF EXISTS(SELECT column FROM table5 WHERE column = condition)
BEGIN
SET @var1 = 'table5'
END
IF EXISTS(SELECT column FROM table6 WHERE column = condition)
BEGIN
SET @var1 = 'table6'
END
IF EXISTS(SELECT column FROM table7 WHERE column = condition)
BEGIN
SET @var1 = 'table7'
END
--DO SOME STUFF
But if the value you are looking for in the condition is the same and could be found in multiple tables but you want to know the first occurrance then this code would fail.
Ok so wrap each exists to check to see if @var1 is null, ok will solve the problem but you are running unneeded CPU cycles because you will always check the @var1 variable 6 times whether you need to or not.
The point of coding is to optimize as best you can and try to keep as portable as possible, but I opt for optimization over portablility myself and just keep a portable version noted somewhere in many cases myself.
So simple put there can be conditions (imagine if you had the same thing expanded to looking thru 100 or 1000 or 10000 tables) where GOTO can help optimize and manage the code better but make sure you have reached that point before you just choose to use it.
Hope the psuedo code present well enough and that I didn't screw up my syntax.
January 14, 2005 at 4:17 am
Hello,
Everrything if fine while using goto untill you get the first bug and try to debug the same. the programmer even the one who wrote the same wont be able to understand the same. instead use functions .
Use GOTO judiciously, use only for the error handling or use it to send to the exit point.
Jeswanth
--------------------------------
January 14, 2005 at 5:42 am
I use it mainly in two ways:
1) errorhandling.
.. do some stuff
SET @err = @@error -- NEVER check errors directly on @@ERROR, always use a local var
( IF @err <> 0 ) GOTO errhandler
errhandler:
<do errhandlingstuff>
return 1
This is because I like to have as few exitpoints in a proc as possible, and preferrably only one place where all errors end up. Makes changes and debugging a LOT easier
2) overrides
Suppose you have a proc that copies, imports and processes files in a batch fashion. Normally it does all steps, but sometimes there may be something funky happening, and you need to debug it. In such a case you may already have all files copied, so it's unnecessary to do the copy step over and over again, you just want to skip that and go directly to the load step. Setting a mode parameter makes this easy.
create proc myBatch @mode = null
as
if ( @mode = 1 ) goto skipCopy
-- copy block
<copy files etc>
--load block
skipCopy:
<bcp files in >
-- process block
<clean/validate/update prod data>
return 0
errhandler:
-- handle errors and exit as gracefully as possible
<do rollbacks/errhandling/messaging etc>
return 1
just my .02 though
/Kenneth
January 14, 2005 at 7:00 am
I'm happy to see that I'm not the only one using GOTO for error handling . I think it makes sense when your error handling logic share the same set of instruction.
Aiwa
January 25, 2005 at 2:46 am
Sorry gents,
Posted - then had a week off and have just got back in the swing....
I'm in complete agreement of using GoTo in error handling code to get the required exit path - just not in the logic of normal code, even if it means writing more complex code.
Providing the nesting is correct, even the more complex code should be more readable and easier to debug.
Cheers for the follow ups.
Have fun
Steve
We need men who can dream of things that never were.
Viewing 9 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic. Login to reply