Performance issues generating a unique name

I have a table 'Objects' present in SQL Server DB. It contains the names (string) of objects.
I have a list of names of new objects that need to be inserted in the 'Objects' table, in a separate table 'NewObjects'. This operation will be referred as 'import' henceforward.

I need to generate a unique name for each record to be imported to 'Objects' from 'NewObjects', if the record name is already present in 'Objects'. This new name will be stored in 'NewObjects' table against the old name.

I have implemented a stored procedures which generates unique name for each record to be imported from 'NewObjects'. However, I am not happy with the performance for 1000 records (in 'NewObjects'.)
I want help to optimize my code. Below is the implementation:

DISCLAIMER: I am in no position to test these recommendations therefore there may be syntax errors that you'll have to work out on your own as you implement them. They are here as a guide to both fix this procedure but also aid you in growing your skill set for future projects.

One optimization just skimming through, that would become more prevalent as you iterated over larger sets, is this code here:

The reason I say you can make that optimization is because unless you have to worry about other entities inserting records during this time that look like the ones you are (e.g. Fxxxxx), then you only have to find the MAX one time and can simply iterate@counter over the loop.

In fact, you could actually pull this entire piece out of the loop. You should be able to extrapolate that pretty easily. Just pull the DECLARE and SET of @counter out along with the code inside the IF (@beg = 1). But take it one step at a time.

Also, change this line:

select top 1 @z = @newName from Objects

to this:

SET @z = @newName

because you are literally running a query to SET two local variables. This is likely a huge cause for the performance issues. A good practice for you to get into is unless you're actually setting a variable from a SELECT statement, use the SET operation for local variables. There are some other places in your code where this applies, consider this line:

select @beg = @beg + 1

use this instead:

SET @beg = @beg + 1

Finally, as stated above regarding simply iterating@counter, at the end of the loop where you have this line:

select @beg = @beg + 1

just add a line:

SET @counter = @counter + 1

and you're golden!

So to recap, you can gather the maximum conflicting name just one time so you'll be getting rid of all those iterations. You're going to start using SET to get rid of performance ridden lines like select top 1 @z = @newName from Objects where you're actually querying a table to set two local variables. And you're going to leverage the EXISTS method instead of setting a variable that leveraged an AGGREGATE function COUNT to do that work.