有没有办法使用tsql脚本替换代码和更新视图

时间:2017-09-12 12:44:00

标签: sql-server tsql

我在引用另一个数据库的数据库中有大约20个视图,我们称之为数据库A.我需要一种方法来用脚本更新这些视图以指向不同的数据库,数据库B.有没有办法替换使用单个tsql脚本在视图中使用数据库B的名称的数据库A的名称并保持视图完好无损?我可以替换并将视图输出到查询窗口,但我想执行生成的ALTER语句,而不必手动运行输出。

更新我想要做的是类似于:https://stackoverflow.com/a/2983927/6084613,但也有脚本执行的输出。这可能吗?

3 个答案:

答案 0 :(得分:3)

我在下面创建了SQL来做同样的事情。这个脚本将需要2个输入 1.旧数据库名称 2.新的DB名称 3.您要修改的视图列表

declare @OldDb  varchar(250),  @newDB  varchar(250)
select @OldDb = '' , ---------->>> provide old db name
@newDB = '' ---------->>> provide new  db name

    create table #ViewList (Id int identity , ViewName varchar(250))
insert into #ViewList 
select TABLE_NAME from INFORMATION_SCHEMA.VIEWS  where TABLE_NAME IN ( ) ---------->>> provide you view list 

create table #ViewDef(  ViewDef nvarchar(max) , ViewName varchar(250) ,Id int   )

declare @minId int , @maxid int , @sql nvarchar(max) ='' , @ViewName varchar(250)

select @minId = min(Id) , @maxid = max(id) from #ViewList

while @minId <= @maxid

begin 

select @ViewName = ViewName from #ViewList where id = @minId

set @sql = '    insert into #ViewDef (ViewDef)
exec sp_helptext '+ @ViewName +' 
update #ViewDef
set ViewName  = '''+ @ViewName +''', 
id = ' + cast(@minId as varchar(10)) +'
where id is null
update #ViewDef 
set ViewDef = replace(ViewDef , '''+ @OldDb+''','''+ @newDB +''')  
where id = ' + cast(@minId as varchar(10)) +'
update #ViewDef 
set ViewDef = replace(ViewDef , ''create'',''alter'')  
where id = ' + cast(@minId as varchar(10)) +'
'
exec sp_executesql  @sql 

SET @sql = ''

select @sql = @sql + ViewDef from #ViewDef  where id =   @minId   

exec sp_executesql  @sql
--print @sql

set @minId = @minId +1 

end 

**请测试脚本并保存旧的定义以避免在上述脚本中出现任何错误时丢失

答案 1 :(得分:2)

您只需将查询定义放入变量中,然后使用sp_executeSQL执行。

但是:我会谨慎使用引用的脚本而不需要更多的工作。 例如,并非所有视图都具有确切的文本“CREATE VIEW”。 如果用手写,有些可能是“创建视图”或“创建视图”。 另外,'DB1'可能是我写的'[DB1]'。

因此要么添加更复杂的逻辑,要么在执行之前通过眼睛验证所有内容。

   Declare @queryDef nvarchar(max)

   SELECT @queryDef = REPLACE (REPLACE (sm.definition, 'CREATE VIEW', 'ALTER VIEW'), 'DB1.', 'DB2.') 
   FROM sys.sql_modules sm JOIN sys.objects o 
        ON sm.object_id = o.object_id
    WHERE
        sm.definition LIKE '%DB1.%' AND o.type = 'V'

    print @queryDef
    exec sp_executeSql @querydef

答案 2 :(得分:0)

使用 SimonB 的想法,我创建了一个循环来自动执行:

DECLARE @queryDef NVARCHAR(max)

WHILE EXISTS (
                    SELECT 1
                    FROM sys.sql_modules    sm 
                    JOIN    sys.objects  o ON sm.object_id = o.object_id 
                    WHERE   sm.definition LIKE '%TEXT_TO_REPLACE%' 
                    AND o.type = 'V'
            )
BEGIN
    
                                                                    -- TO ALTER THE VIEW AUTOMATICALLY                                          
    SET @queryDef = (   SELECT TOP 1 Replace (Replace (sm.definition, 'CREATE VIEW', 'ALTER VIEW'), 
                                            'TEXT_TO_REPLACE', 
                                            'NEW_TEXT') 

                        FROM sys.sql_modules    sm 
                        JOIN    sys.objects  o ON sm.object_id = o.object_id

                        WHERE   sm.definition LIKE '%TEXT_TO_REPLACE%'
                        AND     o.type = 'V')
    
    EXEC sp_executeSql @queryDef

END