Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
craigh999
Starting Member
10 Posts |
Posted - 2004-07-22 : 05:21:49
|
| HiWhat i am trying to achieve is to update a table with a card no from another table containigna just a list of card numbers and a status. There is no particular order just want to take the top N records from the card numbers table and update the other table (N amount of records). And after we done with a particular record just set the status in both, and keep moving round until they all done. The query below does that but is really slow (we got to do around 10 million!!!!)So my question is there a better way to do it?DECLARE @sNumber VARCHAR(18)DECLARE @nID INTEGERWHILE (SELECT COUNT(*) FROM Import WHERE NewCardNum IS NULL) > 0BEGIN SELECT @sNumber = MIN(CardNumber) FROM NewCardNums WHERE Status = 0 SELECT @nID = MIN([ID]) FROM Import WHERE NewCardNum IS NULL UPDATE Import SET NewCardNum = @sNumber WHERE [ID] = @nID UPDATE NewCardNums SET STATUS = 1 WHERE CardNumber = @sNumberENDMany Thanks for your help people |
|
|
JasonGoff
Posting Yak Master
158 Posts |
Posted - 2004-07-22 : 06:24:31
|
This might make it a bit faster..DECLARE @sNumber VARCHAR(18)DECLARE @nID INTEGERWHILE EXISTS(SELECT 1 FROM Import WHERE NewCardNum IS NULL) BEGIN SET @sNumber = (SELECT TOP 1 CardNumber FROM NewCardNums WHERE Status = 0) SET @nID = (SELECT TOP 1 ID FROM Import WHERE NewCardNum IS NULL) UPDATE Import SET NewCardNum = @sNumber WHERE [ID] = @nID UPDATE NewCardNums SET STATUS = 1 WHERE CardNumber = @sNumberEND |
 |
|
|
JasonGoff
Posting Yak Master
158 Posts |
Posted - 2004-07-22 : 07:05:59
|
And here is a set-based solution that cuts down the loop iterations...-- Create two tables to hold the data we are manipulating. Adding an Identity column let's us join the two tables-- row 1 to row 1, row 2 to row 2 etc.DECLARE @tmpNewCardNums TABLE (Ident INT IDENTITY, CardNumber VARCHAR(18),Status INT)DECLARE @tmpImport TABLE (Ident INT IDENTITY, NewCardNum VARCHAR(18) NULL, ID INT)-- now, go round the existing loop while empty newcardnums existWHILE EXISTS(SELECT 1 FROM Import WHERE NewCardNum IS NULL) BEGIN SET ROWCOUNT 1000 -- set this number to be the batch size to process each iteration -- load the next lot of Import records into our temporary holding area INSERT INTO @tmpImport (newcardnum,id) SELECT newcardnum,id FROM Import WHERE NewCardNum IS NULL -- and do the same with the new card numbers INSERT INTO @tmpNewCardNums (cardnumber,status) SELECT cardnumber,status FROM newcardnums WHERE Status=0 -- turn the rowcount limiter off SET ROWCOUNT 0 -- now update the master import table by linking through the temporary batch table on the IDENTITY columns UPDATE Import SET newcardNum=cardnumber FROM @tmpnewcardnums TC INNER JOIN @tmpImport TI on TI.Ident=TC.Ident WHERE Import.ID=TI.ID -- now update the status of all the card numbers we've used UPDATE newcardnums SET Status=1 WHERE cardnumber IN (SELECT cardnumber from @tmpnewcardnums)END |
 |
|
|
craigh999
Starting Member
10 Posts |
Posted - 2004-07-22 : 07:09:24
|
| Thanks for that it has made things a bit quicker much appreciated |
 |
|
|
craigh999
Starting Member
10 Posts |
Posted - 2004-07-22 : 07:24:03
|
| HiTried the query for the set solution but got the follwing errors:I ask because i have never used the table statement in this way?Many ThanksServer: Msg 156, Level 15, State 1, Line 3Incorrect syntax near the keyword 'TABLE'.Server: Msg 170, Level 15, State 1, Line 19Line 19: Incorrect syntax near '@tmpImport'.Server: Msg 170, Level 15, State 1, Line 23Line 23: Incorrect syntax near '@tmpNewCardNums'.Server: Msg 170, Level 15, State 1, Line 32Line 32: Incorrect syntax near '@tmpnewcardnums'.Server: Msg 170, Level 15, State 1, Line 38Line 38: Incorrect syntax near '@tmpnewcardnums'. |
 |
|
|
craigh999
Starting Member
10 Posts |
Posted - 2004-07-22 : 08:48:17
|
| Got it 2 work and that is lightning fast! Many Thanks |
 |
|
|
|
|
|
|
|