EDIT: I've changed the query to use your field names and added a "select-only" query for you to preview.
This is actually pretty easy to do... just use ROW_NUMBER() with a PARTITION clause:
UPDATE Persons SET UniqueName = temp.DeDupded FROM
(SELECT ID,
CASE WHEN ROW_NUMBER() OVER
(PARTITION BY UniqueName ORDER BY UniqueName) = 1 THEN UniqueName
ELSE UniqueName + CONVERT(VARCHAR, ROW_NUMBER()
OVER (PARTITION BY UniqueName ORDER BY UniqueName)-1) END AS DeDupded
FROM Persons) temp
WHERE Persons.ID = temp.ID
If you want a "select-only", then here you go:
SELECT ID,
CASE WHEN ROW_NUMBER() OVER
(PARTITION BY UniqueName ORDER BY UniqueName) = 1 THEN UniqueName
ELSE UniqueName + CONVERT(VARCHAR, ROW_NUMBER()
OVER (PARTITION BY UniqueName ORDER BY UniqueName)-1) END AS DeDupded
FROM Persons
EDIT Again: If you're looking for a SQL Server 2000 Solution...
CREATE TABLE #Persons ( ID INT IDENTITY(1, 1), UniqueName VARCHAR(100) )
INSERT INTO #Persons VALUES ('Bob')
INSERT INTO #Persons VALUES ('Bob')
INSERT INTO #Persons VALUES ('Bob')
INSERT INTO #Persons VALUES ('John')
INSERT INTO #Persons VALUES ('John')
SELECT
ID,
CASE WHEN Position = 0 THEN UniqueName
ELSE UniqueName + (CONVERT(VARCHAR, Position))
END AS UniqueName
FROM
(SELECT
ID,
UniqueName,
(SELECT COUNT(*) FROM #Persons p2 WHERE
p1.UniqueName = p2.UniqueName AND p1.ID > p2.ID) AS Position
FROM
#Persons p1) _temp
DROP TABLE #Persons