代码之家  ›  专栏  ›  技术社区  ›  NoviceDeveloper

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

  •  0
  • NoviceDeveloper  · 技术社区  · 6 年前

    当我还原的备份时 MyDatabase_PROD MyDatabase_TEST 我在测试中有一个来自prod的对另一个数据库的交叉引用。

    例如,在视图中选择

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

    欧洲工商管理学院

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

    所以现在我必须为每个存储过程、视图等编写一个单独的脚本来修复它。

    有没有一种方法可以恢复并运行一个脚本来更改所有这些引用?我在调查 db_name() db_id 如果存在的话,就用它做点什么,但我认为有更好的方法。

    有什么想法吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   john McTighe    6 年前

    我将把选择作为本地同义词重新实现到其他DBS。

    这样,您就可以在不同的区域使用相同的代码。

    失败了-你可以用扫描代码来查找正则表达式吗???这将向外部数据库发出信号。

    或者另一种方法是建立一个prod-db名称列表(希望是短的),然后扫描syscomments以查找这些值,并用dev-db上的dev值进行硬替换

    可以通过while循环vs syscomments提取文本-执行replace()和exec()替换的SQL-注意syscomments中有多行的大型存储过程

    您可能需要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
    

    注意-这不适用于大型程序-您可以检查是否有以下任何一种程序:

    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