交叉引用另一个数据库的SQL还原

时间:2018-11-29 17:11:30

标签: sql sql-server tsql

当我将MyDatabase_PROD的备份恢复到MyDatabase_TEST时,我的TEST中现在有一个来自产品的交叉引用。

例如,视图中的选择

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

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

所以现在我必须为每个存储的proc,视图等编写一个单独的脚本来解决该问题。

是否有一种方法可以还原并运行一个脚本来更改所有这些引用?我一直在研究db_name()db_id(如果存在)对此做些什么,但我认为有更好的方法。

有什么想法吗?

1 个答案:

答案 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