'UPDATE'ing table with same value over and over again!

Please support our MS SQL advertiser: Intel Parallel Studio Home
Thread Solved

Join Date: Apr 2009
Posts: 16
Reputation: SQL_n00b is an unknown quantity at this point 
Solved Threads: 1
SQL_n00b's Avatar
SQL_n00b SQL_n00b is offline Offline
Newbie Poster

'UPDATE'ing table with same value over and over again!

 
0
  #1
21 Days Ago
One of the UPDATE queries I am trying to run is not quite working the way I want it to. I know this query is the culprit, but can't quite figure out how to fix it! Here's the story:
-------------------------------------------------------
I have 3 tables: let's call them tblUsers, tblDueVisits and tblWindows
tblUsers: UserID (PK, int), FirstName (char), LastName (char), BirthDate (smalldatetime), etc.
tblDueVisits: UserID (int), DueDate (smalldatetime), WindowName(char). UserID + DueDate together make up the key for this table.
tblWindows: WindowID (int), WindowName (varchar)
tblWindows stores a pre-defined maximum number of records (say 10). This table will, at least, theoretically never change.
Now this is what I have to do:
• Check how many records a particular User ID (say ID # 1) has in tblDueVisits. For the sake of this example assume there are 5 records.
• Next, SELECT the TOP 5 WindowName from tblWindows.
• UPDATE tblDueVisits to store the WindowName in tblDueVisits WHERE UserID = 1.
(The front-end user selects an ID# from a web page’s drop down box)
-----------------------------------------------------
I have written the T-SQL loop statements to do this, but somehow the UPDATE doesn’t work. Specifically, what happens is that the same WindowName gets written 5 times rather than writing the 5 different WindowNames once each!!

Let me know if I wasn't totally clear about something, or if you need me to post the code for this.

Thanks!
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 4,188
Reputation: peter_budo has much to be proud of peter_budo has much to be proud of peter_budo has much to be proud of peter_budo has much to be proud of peter_budo has much to be proud of peter_budo has much to be proud of peter_budo has much to be proud of peter_budo has much to be proud of peter_budo has much to be proud of peter_budo has much to be proud of 
Solved Threads: 482
Moderator
Featured Poster
peter_budo's Avatar
peter_budo peter_budo is offline Offline
Code tags enforcer
 
0
  #2
21 Days Ago
So if you have written that code why didn't you posted so somebody can have look at it and tell you what can be wrong?
So far it does look like you posted your assignment and expect somebody else do it for you...
Learn to see in another's calamity the ills which you should avoid.
Publilius Syrus
(~100 BC)

LJC - London Java Community, Graduate & Undergraduate Software Development Community, JAVAWUG (Java Web User Group), The London Android Group
Reply With Quote Quick reply to this message  
Join Date: Sep 2009
Posts: 42
Reputation: kplcjl is an unknown quantity at this point 
Solved Threads: 5
kplcjl kplcjl is offline Offline
Light Poster
 
-1
  #3
21 Days Ago
1. It is poor design to have a character field value added to a table that is contained in another table instead of referencing the table (IE WindowID)
2. It is poor design to use (char) for fields that don't have a fixed number of characters
3. It is poor design to not use an order by statement when you aren't using selection criteria and only taking a piece of the information.
That said:
  1. --initial test tables
  2. SET NOCOUNT ON
  3. DECLARE @tblUsers TABLE (UserID int PRIMARY KEY, FirstName varchar(20), LastName varchar(20), BirthDate smalldatetime)
  4. DECLARE @tblDueVisits TABLE (UserID int, DueDate smalldatetime, WindowName varchar(20) NULL)
  5. DECLARE @tblWindows TABLE (WindowID int identity, WindowName varchar(20) NULL)
  6. --initialize tables
  7. declare @dtnow smalldatetime, @id int,@txt varchar(3),@rw int
  8. SELECT @dtnow='20091105',@id=1
  9. WHILE @id < 100
  10. BEGIN
  11. SET @txt=@id
  12. INSERT INTO @tblUsers VALUES (@id, 'First' + @txt, 'LastName' + @txt, dateadd(year,-@id,@dtnow))
  13. INSERT INTO @tblWindows VALUES ('WindowName'+@txt)
  14. SELECT @id=@id*2,@rw=@@identity
  15. WHILE @rw > 0
  16. BEGIN
  17. INSERT INTO @tblDueVisits VALUES (@id, dateadd(day,@id*@rw,@dtnow),NULL)
  18. SET @rw=@rw-1
  19. END
  20. END
  21. SET nocount off
  22. --SELECT * FROM @tblUsers
  23. --SELECT * FROM @tblWindows
  24. --SELECT * FROM @tblDueVisits
  25. SET NOCOUNT ON
  26. -- Process requirement
  27. SET @id=16
  28. DECLARE @tbl1 TABLE (ID1 int IDENTITY, DueDate smalldatetime)
  29. DECLARE @tbl2 TABLE (ID2 int IDENTITY, WindowName varchar(20) NULL)
  30. INSERT INTO @tbl1 SELECT DueDate FROM @tblDueVisits WHERE UserID=@id
  31. SELECT @rw=@@ROWCOUNT
  32. INSERT INTO @tbl2 SELECT TOP (@rw) WindowName FROM @tblWindows
  33. UPDATE @tblDueVisits SET WindowName=c.WindowName
  34. FROM @tblDueVisits a
  35. JOIN @tbl1 b ON a.DueDate=b.DueDate AND UserID=@id
  36. JOIN @tbl2 c ON ID1=ID2
  37. SELECT * FROM @tblDueVisits WHERE UserID=@id
Is this what you are looking for?
Last edited by kplcjl; 21 Days Ago at 7:59 pm. Reason: Remove pasted data
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 28
Reputation: cheapterp is an unknown quantity at this point 
Solved Threads: 2
cheapterp's Avatar
cheapterp cheapterp is offline Offline
Light Poster
 
0
  #4
20 Days Ago
Originally Posted by peter_budo View Post
So if you have written that code why didn't you posted so somebody can have look at it and tell you what can be wrong?
So far it does look like you posted your assignment and expect somebody else do it for you...
You're right, peter_budo. I should have posted the code first time around. Anyway, here it is now
  1. DECLARE @VisitType varchar(7) --The Visit Name with which tblWindows is to be updated
  2.  
  3. --DECLARE @counter int --Counter to check if #Visits is reached
  4. --SET @counter = 1
  5.  
  6. DECLARE @NumberOfVisits int -- VAR to store the #Visits the ID has
  7. SET @NumberOfVisits = (SELECT COUNT(Window) FROM tblDueVisits WHERE UserID = 1) --typically the UserID will be picked up from the webpage form.
  8.  
  9. --Get the different Visit Types
  10. DECLARE cursorVisitNames CURSOR FOR SELECT TOP (@NumberOfVisits) VisitName FROM tblDueVisits ORDER BY VisitName
  11.  
  12. OPEN cursorVisitNames
  13. FETCH NEXT FROM cursorVisitNames INTO @VisitType
  14. SET NOCOUNT ON
  15. WHILE @@Fetch_Status = 0
  16. BEGIN
  17. PRINT @VisitType --Verify correct number of visits is selected
  18.  
  19. UPDATE tblWindows SET Visit = @VisitType WHERE UserID = 1
  20. --SET @counter = @counter+1
  21.  
  22. FETCH NEXT FROM cursorVisitNames INTO @VisitType
  23. END
  24. SET NOCOUNT OFF
  25.  
  26. CLOSE cursorVisitNames
  27. DEALLOCATE cursorVisitNames

Obviously, the UPDATE statement I have is a disaster. But anything else that I have tried won't work!
Reply With Quote Quick reply to this message  
Join Date: Sep 2009
Posts: 42
Reputation: kplcjl is an unknown quantity at this point 
Solved Threads: 5
kplcjl kplcjl is offline Offline
Light Poster
 
0
  #5
20 Days Ago
Originally Posted by cheapterp View Post
  1. ...
  2. --Get the different Visit Types
  3. DECLARE cursorVisitNames CURSOR FOR SELECT TOP (@NumberOfVisits) VisitName FROM
  4. ORDER BY VisitName
  5.  
  6. ...
  7. FETCH NEXT FROM cursorVisitNames INTO @VisitType
  8. ...
  9. UPDATE tblWindows SET Visit = @VisitType WHERE UserID = 1
... tblWindows stores a pre-defined maximum number of records (say 10). This table will, at least, theoretically never change. ...

...
So, you have a table that will never change that you are updating... Huh. WHERE UserID = 1 when the table doesn't contain UserID and you are puzzled because it doesn't work? OK lets switch the tables in the cursor and the update so it matches your original text.

UPDATE tblDueVisits SET Visit = @VisitType WHERE UserID = 1

This table according to your statement is a two column key, so there are multiple records where UserID = 1, so of course every record gets set to the same visit type. You need to use BOTH key values in your where statement to identify 1 record you want to update.

You can set up a second cursor on tblDueVisits to retrieve the date where UserID = 1. Fetch next on it inside your existing loop (ONE time only --- DO NOT loop inside the loop.) and use both key fields to update only one record per loop.

I recommend you review the code I supplied. Toggle it to text, copy and paste into EM, fix my typo and run it. (Or don't fix it. You still get an example of multiple rows getting updated in one statement with different values for every row.) You can't hurt anything because it only touches temp tables.

It doesn't use CURSORS because everything you read about will tell you this is a poor choice. (CURSOR does have its place.) I don't use count because I still need to retrieve every key field to use them in the combination of key fields. So I put them in a temp table and use @@rowcount instead.

OK, the data is bogus, it still displays the process.
Reply With Quote Quick reply to this message  
Join Date: Sep 2009
Posts: 42
Reputation: kplcjl is an unknown quantity at this point 
Solved Threads: 5
kplcjl kplcjl is offline Offline
Light Poster
 
0
  #6
20 Days Ago
Back to my code example:
  1. ...
  2. UPDATE @tblDueVisits SET WindowName=c.WindowName
  3. FROM @tblDueVisits a
  4. JOIN @tbl1 b ON a.DueDate=b.DueDate AND UserID=@id
  5. JOIN @tbl2 c ON ID1=ID2
  6. ...

OK, what is going on.
@tbl1 has an identity field and a list of every DueDate in @tblDueVisits where UserID=@id.
Since I didn't bother making a key for @tblDueVisits I instead made sure every DueDate was unique per UserID when I created the data so every date in both tables are an exact match.
@tbl2 has an identity field and a list of WindowNames that has the same number of rows in @tbl1 but from the static table data.
I am taking advantage of how an identity field works. Without modifiers, it will always start at 1 and always increase in value by 1. Therefore there will be a 1 to 1 match where ID1=ID2. Therefore there will also be a 1 to 1 where a.DueDate=b.DueDate and UserID=@id
So each WindowName is unique on each row after the update where UserID=@id.
I used 16 instead of 1 because it has multiple rows for the id in @tblDueVisits.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC