0

When I restore a backup of MyDatabase_PROD to MyDatabase_TEST I have a cross Reference of another database in my TEST now that comes from prod.

For example a select in a view of

Select * from [My_DB_PROD].[dbo].[ID]

Insead of

Select * from [My_DB_TEST].[dbo].[ID]

So now I have to write a separate script for each stored proc, view etc to fix that.

Is there a way to restore and run a single script to change all of those references? I was looking into db_name() or db_id if exists do something with it but I think there is a better way.

Any ideas?

3
  • Is this view in a different database? If it's in the database My_DB_PROD then why are you reference the database it's in? The easier option would be to change to 2 part naming; then no matter what you call the database, the View will always refer to itself. Commented Nov 29, 2018 at 17:15
  • 2
    Otherwise, if they're in a separate database, the common method is to use synonyms, and script those out. Commented Nov 29, 2018 at 17:16
  • @Larnu it is a reference of a different database. You can add your answer if you wish. Commented Nov 29, 2018 at 17:18

1 Answer 1

1

I would re-implement the Selects to other DBs as Local Synonyms.

That way you can have the same code in different regions.

Failing that - You could probably scan code for regular expressions with ?.?.? which would signal an external DB.

Or Another way is to Build up a list of prod DB Names (hopefully short)- then scan syscomments for these values& do a hard replace with the Dev values on the Dev DB

You can extract the text via a while loop vs syscomments- do a Replace() and Exec() the replaced SQL - Watch out for Giant sprocs that have multiple rows in syscomments

You'll probably need dbo or sa rights.

Edit to add SQL

DECLARE @SQL varchar(max)

WHILE EXISTS (select * from sys.syscomments where text like '%My_DB_PROD%')

BEGIN


select top 1 @SQL = Text from sys.syscomments where text like '%My_DB_PROD%'

SET @SQL = REPLACE(@SQL, 'My_DB_PROD','My_DB_TEST')

EXEC (@SQL)

END

NB - This doesn't handle giant procs - you can check if you have any of these with:

select object_name(id) , count(*) from syscomments 

group by object_name(id)

having count(*) > 1

If you do then its a bit trickier as you have to concat all the separate text values into a single sql statement (colid 1,2,3 etc)

Check if this is the case - it might not be!

SQL for BIG Procs Here:

DECLARE @SQL varchar(max)='', @colid int=1, @ID Int, @MaxColID int, @TempSQL varchar(MAX)

WHILE EXISTS (select * from sys.syscomments where text like '%My_DB_PROD%')

BEGIN

    select top 1 @ID= ID from sys.syscomments where text like '%My_DB_PROD%'

    SELECT @MaxColID = MAX(COLID) from sys.syscomments where ID = @ID

    WHILE @ColID <= @MaxColID

    BEGIN

        SELECT @TempSQL = Text FROM syscomments where ID = @ID and colid = @Colid

        Set @SQL += @TempSQL

        SET @ColID +=1

    END



    SET @SQL = REPLACE(@SQL, 'My_DB_PROD','My_DB_TEST')

    EXEC (@SQL)

    SET @SQL = ''

END
Sign up to request clarification or add additional context in comments.

1 Comment

Can you add a short examples of these if possible?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.