Label affecting Control of Flow

  •  It has always been my understanding that labels were strickly addressable points in the program control of flow (i.e, GOTO label), but did not, by themselves, affect flow of control. This line of thinking is supported by MS's definition and description of a label . However, when the following simple code executes, if @abc = 'A', then @flag is set to 'B', as coded. At this point control should fall out of this nested IF. However, instead, control falls down to TESTIT: and begins execution at that label.

    Any explanations on why this happens?

    If @abc = 'A'

       set @flag = 'B'

    else

       if @abc = 'C'

          set @flag = 'A'

       else

          if @abc = 'B'

             GOTO TestIt

          else

             If @xyz = 1

                set @flag = 'A'

             ELSE

                if @xyz = 2

                   set @flag = 'A'

                ELSE

    TESTIT:        if @def = 'A'

                      set @flag = 'A'

                   ELSE

                      IF @def = 'C'

                         set @flag = 'E'

                      ELSE

                         set @flag = 'C'

     

  • Hi,

    I think you'll find BEGIN......END flags around each bit, with decent nesting to show what you need to achieve - will remove all the problems. e.g:-

    If @abc = 'A'

    BEGIN

        set @flag = 'B'

    END

    else

    BEGIN

        if @abc = 'C'

        BEGIN

            set @flag = 'A'

        END

        else if @abc = 'B' 

        BEGIN       

             GOTO TestIt

        END 

        else If @xyz = 1

        BEGIN

                 set @flag = 'A'

        END

        else if @xyz = 2

        BEGIN

                  set @flag = 'A'

        END

               

    END

    TESTIT:       

    BEGIN

         if @def = 'A'

         BEGIN

             set @flag = 'A'

         END

         else if @def = 'C'

         BEGIN

                  set @flag = 'E'

         END

         else

         BEGIN

                  set @flag = 'C'

         END

    END

    I would also have a closer look into the CASE statement in BOL..........

    Have fun

    Steve

    We need men who can dream of things that never were.

  • BSB,

    Before anything else, just let me say one thing...

    DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!

    It appears that SQL Server is interpreting the label as the one statement allowed in the "Else" clause without using a "Begin" and "End" block.  This ends the nested "If" you have set up.  The next "If", even though it is on the same line as the label begins a new nested if.  Using "Begin" and "End" as Steve describes does fix this situation.  However, you could avoid the problem altogether if you...

    DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!  DON'T USE GOTO!

     

  • I had gotten around the problem using Begin .. End, similar to what was suggested (see below). But I just dont' understand why the problem occurs in the first place. Thanks to all for your ideas.

    We are supposed to be able to use labels for commenting, whether or not they are ever the address of a branch. If a label consistently ended a IF nest, they could be used very effectively as another control of flow statement. However, that is not how a label is defined by Microsoft.

    If @abc = 'A'

       set @flag = 'B'

    else

    BEGIN

       if @abc = 'C'

          set @flag = 'A'

       else

          if @abc = 'B'

             GOTO TestIt

          else

             If @xyz = 1

                set @flag = 'A'

             ELSE

                if @xyz = 2

                   set @flag = 'A'

                ELSE

    TESTIT:        if @def = 'A'

                      set @flag = 'A'

                   ELSE

                      IF @def = 'C'

                         set @flag = 'E'

                      ELSE

                         set @flag = 'C'

    END

    I would like hearing more opinions on the use of GOTO. I think with limited use they can make code very clear, but recoginize the potential to make code a nightmare to maintain when GOTO is used extensively by a spaghetti coder.

  • BSB,

    Your solution won't work if @abc = 'C'.  If you are only going to use one "Begin" "End" block it should be around the ELSE clause which has more than one statement in it.  Specificially, the ELSE clause containing the label.

    If @abc = 'A'

       set @flag = 'B'

    else

       if @abc = 'C'

          set @flag = 'A'

       else

          if @abc = 'B'

             GOTO TestIt

          else

             If @xyz = 1

                set @flag = 'A'

             ELSE

                if @xyz = 2

                   set @flag = 'A'

                ELSE

                BEGIN

    TESTIT:        if @def = 'A'

                      set @flag = 'A'

                   ELSE

                      IF @def = 'C'

                         set @flag = 'E'

                      ELSE

                         set @flag = 'C'

                END

     

    Once again, DON'T USE GOTO.  It only causes problems and confusion.

     

  • BSB,

    As far as your contention that "with limited use they can make code very clear", let me ask one thing:

    Since you used a GoTo and a label in your original code in this thread and your use of only one GoTo and Label was definitely "limited use", was it "very clear" to you that the ELSE clause interpreted the label as a statement?

    I think you've already answered your own question just by starting this thread.

     

  • I agree with everyone's comment about GOTO. I never use GOTO unless I need to have an common exit because of err handling. You just don't need a goto in this code.

  • This is more a case of sloppy coding by Microsoft - there is no mention of this aberrant behaviour of GOTO's and labels in BOL or Technet/KBase etc. This is a perfect definition of a known bug that has never been fixed. And won't.

    In theory, you should be able to use GOTO with confidence that it will work as documented, and without jumping through hoops to get it to work properly. In a tiny piece of coding such as this GOTO's are not going to obscure one's comprehension of the code's purpose, and the anti-GOTO hysteria is not justified.

    But I admit, I avoid GOTO like the plague, coming from the days of sequential programming languages and seeing the extreme obfuscation GOTO's can provide.

    DB


    The systems fine with no users loggged in. Can we keep it that way ?br>

Viewing 8 posts - 1 through 7 (of 7 total)

You must be logged in to reply to this topic. Login to reply