当我将MyDatabase_PROD
的备份恢复到MyDatabase_TEST
时,我的TEST中现在有一个来自产品的交叉引用。
例如,视图中的选择
Select * from [My_DB_PROD].[dbo].[ID]
的
Select * from [My_DB_TEST].[dbo].[ID]
所以现在我必须为每个存储的proc,视图等编写一个单独的脚本来解决该问题。
是否有一种方法可以还原并运行一个脚本来更改所有这些引用?我一直在研究db_name()
或db_id
(如果存在)对此做些什么,但我认为有更好的方法。
有什么想法吗?
答案 0 :(得分:1)
我会将Selects重新实现为本地同义词。
这样,您可以在不同的区域使用相同的代码。
失败-您可能会使用?。?。?扫描代码以查找正则表达式。这将向外部数据库发出信号。
或者另一种方法是建立产品数据库名称列表(希望简短)-然后扫描系统注释以查找这些值并用Dev DB上的Dev值进行硬替换
您可以通过while循环vs syscomments提取文本-进行Replace()和Exec()替换后的SQL-注意在syscomments中有多行的Giant程序
您可能需要dbo或sa权限。
编辑以添加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
注意-这不能处理巨大的proc-您可以通过以下方法检查其中是否有任何
select object_name(id) , count(*) from syscomments
group by object_name(id)
having count(*) > 1
如果这样做,则有点棘手,因为您必须将所有单独的文本值合并为一个sql语句(colid 1,2,3等)
检查是否是这种情况-可能不是!
此处用于大程序的SQL:
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