Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. Clever Code
  4. T-SQL LOOP

T-SQL LOOP

Scheduled Pinned Locked Moved Clever Code
databasehelpquestion
12 Posts 10 Posters 4 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Pascal Ganaye

    I find this code behave not the way it should. In this loop the vehicle registration persists from one contact to the next when no vehicle is found

    FETCH NEXT FROM ContactsCursor INTO
    @Contact_ContactID

    WHILE (@@FETCH_STATUS = 0))
    BEGIN
    DECLARE @Vehicle_Registration AS VARCHAR(25)

    SELECT  
        @Vehicle\_Registration     = V.Registration,
        FROM tblVehicle V (NOLOCK)
        WHERE V.ContactID = Contact\_ContactID
    
    ...
    
    FETCH NEXT FROM ContactsCursor INTO 
    	@Contact\_ContactID        
    

    END

    I would have expected 1 - the DECLARE keyword to clear the value 2 - the SELECT should set to nul if the SELECT returns no row. The obvious fix is to write a @Vehicle_Registration. Is there any thing more elegant?

    J Offline
    J Offline
    Jeremy Hutchinson
    wrote on last edited by
    #2

    Apparently SQL doesn't recognize the scope of the cursor, so it isn't re-declaring the @Vehicle_Registration. I agree that's kind of odd behavior, and if it's not going to re-declare it I would at least like it to throw an error to let me know I'm trying to declare the variable twice and it's not going to do that. There's no more elegant way around the second issue where it doesn't update the @Vehicle_Registration when the select statement returns 0 rows. It's just always been that way, if no rows are returned there is nothing to assign to the variable. That's different than returning one row where V.Registration = null. I'm not sure what you're doing here, but you might want to consider what happens if a contact has more than one vehicle. You're only going to get the Registration for one of the vehicles, and there's no guaranty that it will be the same registration each time you run the code...

    P 1 Reply Last reply
    0
    • P Pascal Ganaye

      I find this code behave not the way it should. In this loop the vehicle registration persists from one contact to the next when no vehicle is found

      FETCH NEXT FROM ContactsCursor INTO
      @Contact_ContactID

      WHILE (@@FETCH_STATUS = 0))
      BEGIN
      DECLARE @Vehicle_Registration AS VARCHAR(25)

      SELECT  
          @Vehicle\_Registration     = V.Registration,
          FROM tblVehicle V (NOLOCK)
          WHERE V.ContactID = Contact\_ContactID
      
      ...
      
      FETCH NEXT FROM ContactsCursor INTO 
      	@Contact\_ContactID        
      

      END

      I would have expected 1 - the DECLARE keyword to clear the value 2 - the SELECT should set to nul if the SELECT returns no row. The obvious fix is to write a @Vehicle_Registration. Is there any thing more elegant?

      R Offline
      R Offline
      robocodeboy
      wrote on last edited by
      #3

      A "Declare" statement doesn't initialize the declared value. And an assignment into a SELECT statement doesn't do anything if the result set is empty. So I would say it's working as expected. You should write something like this:

      DECLARE @Vehicle_Registration AS VARCHAR(25);

      FETCH NEXT FROM ContactsCursor INTO
      @Contact_ContactID

      WHILE (@@FETCH_STATUS = 0))
      BEGIN
      SET @Vehicle_Registration = NULL;

      SELECT  
          @Vehicle\_Registration     = V.Registration,
          FROM tblVehicle V (NOLOCK)
          WHERE V.ContactID = Contact\_ContactID
      
      IF (@Vehicle\_Registration IS NOT NULL)
      BEGIN
      	...
      END
      
      FETCH NEXT FROM ContactsCursor INTO 
      	@Contact\_ContactID        
      

      END

      See ya

      1 Reply Last reply
      0
      • P Pascal Ganaye

        I find this code behave not the way it should. In this loop the vehicle registration persists from one contact to the next when no vehicle is found

        FETCH NEXT FROM ContactsCursor INTO
        @Contact_ContactID

        WHILE (@@FETCH_STATUS = 0))
        BEGIN
        DECLARE @Vehicle_Registration AS VARCHAR(25)

        SELECT  
            @Vehicle\_Registration     = V.Registration,
            FROM tblVehicle V (NOLOCK)
            WHERE V.ContactID = Contact\_ContactID
        
        ...
        
        FETCH NEXT FROM ContactsCursor INTO 
        	@Contact\_ContactID        
        

        END

        I would have expected 1 - the DECLARE keyword to clear the value 2 - the SELECT should set to nul if the SELECT returns no row. The obvious fix is to write a @Vehicle_Registration. Is there any thing more elegant?

        P Offline
        P Offline
        PIEBALDconsult
        wrote on last edited by
        #4

        This isn't the proper forum for this.

        P 1 Reply Last reply
        0
        • P PIEBALDconsult

          This isn't the proper forum for this.

          P Offline
          P Offline
          Pascal Ganaye
          wrote on last edited by
          #5

          Really depend if I am after an answer or not. Here I know the answer. I am more complaining about the language, with the remote hope that perhaps someone will prove me wrong.

          1 Reply Last reply
          0
          • J Jeremy Hutchinson

            Apparently SQL doesn't recognize the scope of the cursor, so it isn't re-declaring the @Vehicle_Registration. I agree that's kind of odd behavior, and if it's not going to re-declare it I would at least like it to throw an error to let me know I'm trying to declare the variable twice and it's not going to do that. There's no more elegant way around the second issue where it doesn't update the @Vehicle_Registration when the select statement returns 0 rows. It's just always been that way, if no rows are returned there is nothing to assign to the variable. That's different than returning one row where V.Registration = null. I'm not sure what you're doing here, but you might want to consider what happens if a contact has more than one vehicle. You're only going to get the Registration for one of the vehicles, and there's no guaranty that it will be the same registration each time you run the code...

            P Offline
            P Offline
            Pascal Ganaye
            wrote on last edited by
            #6

            I won't tell for which insurance I work for then :-)

            1 Reply Last reply
            0
            • P Pascal Ganaye

              I find this code behave not the way it should. In this loop the vehicle registration persists from one contact to the next when no vehicle is found

              FETCH NEXT FROM ContactsCursor INTO
              @Contact_ContactID

              WHILE (@@FETCH_STATUS = 0))
              BEGIN
              DECLARE @Vehicle_Registration AS VARCHAR(25)

              SELECT  
                  @Vehicle\_Registration     = V.Registration,
                  FROM tblVehicle V (NOLOCK)
                  WHERE V.ContactID = Contact\_ContactID
              
              ...
              
              FETCH NEXT FROM ContactsCursor INTO 
              	@Contact\_ContactID        
              

              END

              I would have expected 1 - the DECLARE keyword to clear the value 2 - the SELECT should set to nul if the SELECT returns no row. The obvious fix is to write a @Vehicle_Registration. Is there any thing more elegant?

              R Offline
              R Offline
              RyanEK
              wrote on last edited by
              #7

              Pascal Ganaye wrote:

              Is there any thing more elegant?

              Yes... avoid cursors

              S 1 Reply Last reply
              0
              • P Pascal Ganaye

                I find this code behave not the way it should. In this loop the vehicle registration persists from one contact to the next when no vehicle is found

                FETCH NEXT FROM ContactsCursor INTO
                @Contact_ContactID

                WHILE (@@FETCH_STATUS = 0))
                BEGIN
                DECLARE @Vehicle_Registration AS VARCHAR(25)

                SELECT  
                    @Vehicle\_Registration     = V.Registration,
                    FROM tblVehicle V (NOLOCK)
                    WHERE V.ContactID = Contact\_ContactID
                
                ...
                
                FETCH NEXT FROM ContactsCursor INTO 
                	@Contact\_ContactID        
                

                END

                I would have expected 1 - the DECLARE keyword to clear the value 2 - the SELECT should set to nul if the SELECT returns no row. The obvious fix is to write a @Vehicle_Registration. Is there any thing more elegant?

                C Offline
                C Offline
                Chris Maunder
                wrote on last edited by
                #8

                This isn't that much different than if you declared the variable inside the loop in C++. If the inner select can't get any rows then there are no operations done, so of course the var is going to be left alone.

                cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                1 Reply Last reply
                0
                • R RyanEK

                  Pascal Ganaye wrote:

                  Is there any thing more elegant?

                  Yes... avoid cursors

                  S Offline
                  S Offline
                  Simon_Whale
                  wrote on last edited by
                  #9

                  RyanEK wrote:

                  Yes... avoid cursors

                  for me that is WHERE possible which is 99% of the time

                  As barmey as a sack of badgers

                  1 Reply Last reply
                  0
                  • P Pascal Ganaye

                    I find this code behave not the way it should. In this loop the vehicle registration persists from one contact to the next when no vehicle is found

                    FETCH NEXT FROM ContactsCursor INTO
                    @Contact_ContactID

                    WHILE (@@FETCH_STATUS = 0))
                    BEGIN
                    DECLARE @Vehicle_Registration AS VARCHAR(25)

                    SELECT  
                        @Vehicle\_Registration     = V.Registration,
                        FROM tblVehicle V (NOLOCK)
                        WHERE V.ContactID = Contact\_ContactID
                    
                    ...
                    
                    FETCH NEXT FROM ContactsCursor INTO 
                    	@Contact\_ContactID        
                    

                    END

                    I would have expected 1 - the DECLARE keyword to clear the value 2 - the SELECT should set to nul if the SELECT returns no row. The obvious fix is to write a @Vehicle_Registration. Is there any thing more elegant?

                    A Offline
                    A Offline
                    AspDotNetDev
                    wrote on last edited by
                    #10

                    This is another way to do it (disclaimer: I didn't compile this code, so some of the syntax might not be quite correct):

                    -- Variables.
                    DECLARE @Vehicle_Registration AS VARCHAR(25)
                    -- Assume ContactsCursor and @Contact_ContactID are already declared.

                    -- Loop.
                    WHILE 0 = 0
                    BEGIN

                    -- Next item in cursor.
                    FETCH NEXT FROM ContactsCursor INTO
                    	@Contact\_ContactID
                    IF @@FETCH\_STATUS != 0
                    BEGIN
                    	BREAK
                    END
                    
                    -- Get variable.
                    SELECT
                    	@Vehicle\_Registration =
                    		(
                    			SELECT TOP 1
                    				Registration
                    			FROM tblVehicle WITH (NOLOCK)
                    			WHERE
                    				ContactID = @Contact\_ContactID
                    		)
                    

                    END

                    If you have to assign a bunch of values, you can perform a LEFT JOIN that ensures one row will always be returned:

                    -- Variables.
                    DECLARE @Vehicle_Registration AS VARCHAR(25)
                    -- Assume ContactsCursor and @Contact_ContactID are already declared.

                    -- Loop.
                    WHILE 0 = 0
                    BEGIN

                    -- Next item in cursor.
                    FETCH NEXT FROM ContactsCursor INTO
                    	@Contact\_ContactID
                    IF @@FETCH\_STATUS = 0
                    BEGIN
                    	BREAK
                    END
                    
                    -- Get variable.
                    SELECT TOP 1
                    	@Vehicle\_Registration = Registration
                    	-- More variables assigned here.
                    FROM
                    	(
                    		SELECT 1 AS DummyValue
                    	) AS MinimumOneRow
                    LEFT JOIN tblVehicle WITH (NOLOCK)
                    	ON ContactID = @Contact\_ContactID
                    

                    END

                    And if you think that's a neat trick, check out my article, JOIN Instead of Repeating a Subquery. :)

                    [Forum Guidelines]

                    1 Reply Last reply
                    0
                    • P Pascal Ganaye

                      I find this code behave not the way it should. In this loop the vehicle registration persists from one contact to the next when no vehicle is found

                      FETCH NEXT FROM ContactsCursor INTO
                      @Contact_ContactID

                      WHILE (@@FETCH_STATUS = 0))
                      BEGIN
                      DECLARE @Vehicle_Registration AS VARCHAR(25)

                      SELECT  
                          @Vehicle\_Registration     = V.Registration,
                          FROM tblVehicle V (NOLOCK)
                          WHERE V.ContactID = Contact\_ContactID
                      
                      ...
                      
                      FETCH NEXT FROM ContactsCursor INTO 
                      	@Contact\_ContactID        
                      

                      END

                      I would have expected 1 - the DECLARE keyword to clear the value 2 - the SELECT should set to nul if the SELECT returns no row. The obvious fix is to write a @Vehicle_Registration. Is there any thing more elegant?

                      P Offline
                      P Offline
                      PoweredByOtgc
                      wrote on last edited by
                      #11

                      This will fix your select issue when nothing is returned FETCH NEXT FROM ContactsCursor INTO @Contact_ContactID WHILE (@@FETCH_STATUS = 0)) BEGIN DECLARE @Vehicle_Registration AS VARCHAR(25) SELECT @Vehicle_Registration = coalesce(V.Registration,null), FROM tblVehicle V (NOLOCK) WHERE V.ContactID = @Contact_ContactID ... FETCH NEXT FROM ContactsCursor INTO @Contact_ContactID END

                      1 Reply Last reply
                      0
                      • P Pascal Ganaye

                        I find this code behave not the way it should. In this loop the vehicle registration persists from one contact to the next when no vehicle is found

                        FETCH NEXT FROM ContactsCursor INTO
                        @Contact_ContactID

                        WHILE (@@FETCH_STATUS = 0))
                        BEGIN
                        DECLARE @Vehicle_Registration AS VARCHAR(25)

                        SELECT  
                            @Vehicle\_Registration     = V.Registration,
                            FROM tblVehicle V (NOLOCK)
                            WHERE V.ContactID = Contact\_ContactID
                        
                        ...
                        
                        FETCH NEXT FROM ContactsCursor INTO 
                        	@Contact\_ContactID        
                        

                        END

                        I would have expected 1 - the DECLARE keyword to clear the value 2 - the SELECT should set to nul if the SELECT returns no row. The obvious fix is to write a @Vehicle_Registration. Is there any thing more elegant?

                        S Offline
                        S Offline
                        ScottM1
                        wrote on last edited by
                        #12

                        I had the exact same problem about a week ago except mine was with an integer that was keeping the previous row's value if the current row was null. You would think that all variables in the scope of the while loop would be null for each iteration.

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups