Reputation: 1290
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?
Upvotes: 0
Views: 97
Reputation: 1181
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
Upvotes: 1