我在引用另一个数据库的数据库中有大约20个视图,我们称之为数据库A.我需要一种方法来用脚本更新这些视图以指向不同的数据库,数据库B.有没有办法替换使用单个tsql脚本在视图中使用数据库B的名称的数据库A的名称并保持视图完好无损?我可以替换并将视图输出到查询窗口,但我想执行生成的ALTER语句,而不必手动运行输出。
更新我想要做的是类似于:https://stackoverflow.com/a/2983927/6084613,但也有脚本执行的输出。这可能吗?
答案 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