I’m using a cursor to update a single field in a table, and I’m attempting to declare the cursor using an ORDER BY in the text of the select.
I’ve got the following example data:
testTable:
RecordGuid RecordID DupeParentID
---------- -------- ------------
[guid] A Y
[guid] A N
[guid] A N
[guid] A N
[guid] B Y
[guid] B N
[guid] B N
[guid] C Y
[guid] C N
[guid] C N
And script:
DECLARE @allcounter INT
SET @allcounter = 1
SELECT RecordID, count(*) as [NumberDupes]
INTO #RecordGroupCounts
FROM testTable
GROUP BY RecordID
DECLARE @temp VARCHAR(500)
DECLARE @current VARCHAR(500)
DECLARE c1 CURSOR
FOR
SELECT RecordID FROM testTable WHERE RecordID IN (SELECT RecordID FROM testTable WHERE DupeParentID = 'Y')
ORDER BY RecordID
FOR UPDATE OF RecordID
OPEN c1
FETCH NEXT FROM c1 INTO @current
FETCH NEXT FROM c1 INTO @current
WHILE @@fetch_status = 0
BEGIN
UPDATE testTable
SET RecordID = RecordID + '-' + cast(@allcounter AS VARCHAR)
WHERE CURRENT OF c1
IF (@allcounter + 1) = (SELECT [NumberDupes] FROM #RecordGroupCounts WHERE RecordID = @current)
BEGIN
FETCH NEXT FROM c1 INTO @current
SET @allcounter = 0
END
SET @allcounter = @allcounter + 1
FETCH NEXT FROM c1 INTO @current
END
CLOSE c1
DEALLOCATE c1
The desired output of all of this is:
RecordGuid RecordID DupeParentID
---------- -------- ------------
[guid] A Y
[guid] A-1 N
[guid] A-2 N
[guid] A-3 N
[guid] B Y
[guid] B-1 N
[guid] B-2 N
[guid] C Y
[guid] C-1 N
[guid] C-2 N
I’m working with SQL Server 2000 so I don’t have ROW_NUMBER() available – I know the common way to do this is with loops, but I am by no means a DBA, and this currently works if I remove my ORDER BY RecordID in the cursor declaration.
With as small as my current test table is this seems to be working fine, but the reason I’m attempting to order this is that I’m fairly sure it’ll break if the RecordIDs aren’t in order (by RecordID ASC, DupeParentID DESC) and I intend to use this on a much larger set of records semi-regularly. Is there a way to define the order for a cursor that updates? Is the cursor ordered automatically somehow? If not, is there a simpler (or faster) way to write this for SQL Server 2000?
The above statement should return 1 row per recordID with the max(guID) for that recordID. heh, spell check keeps changing guid to guide. Now we can increment all of these with the 1.
Get the logic here? What we’re doing is taking the first duplicate ID using the max recordguid as an identifier for the ‘first’…lil arbitrary, we could use min as well as long as it returns just one guID for each recordID. If you had some other logic as to which record was to be called the -1 vs the -2, you can include it here.
This will create all the recordID-1 (A-1,B-1) and leave the rest alone. Now you should be able to loop this and increment the -1 as needed…or you could just repeat run it manually incrementing the -1 yourself if this is a one time fix…your call there.
Let me know how it goes…the logic should work and will be quite quicker than going through each recordID at a time.