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 5 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?

    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