我试图从服务器上的大多数数据库中删除特定视图。粘贴在下面是我现在拥有的。它成功完成但实际上并没有删除视图。
我错过了什么,为什么不是错误而不是实际上放弃了视图?此外,当我在特定数据库中运行exec语句时,它会删除视图。
USE [Master]
DECLARE @DBname VARCHAR (128);
DECLARE @NumDBs INT;
DECLARE @Count INT = 0;
DECLARE getDBs CURSOR
FOR
SELECT name
FROM sys.databases
WHERE name NOT IN ('DBName1','DBName2')
ORDER BY name;
SET @NumDBs = (SELECT COUNT(9) FROM sys.databases WHERE
name NOT IN ('DBName1','DBName2') )
;
OPEN getDBs
FETCH NEXT FROM getDBs
INTO @DBname;
WHILE (@Count < @NumDBs)
BEGIN
Exec('IF EXISTS (SELECT *
FROM '+@DBname+'.sys.views
WHERE object_id= OBJECT_ID(N''[ViewName]''))
DROP VIEW [ViewName]'
);
SET @Count = @Count + 1;
FETCH NEXT FROM getDBs
INTO @DBname;
END;
CLOSE getDBs;
DEALLOCATE getDBs;
答案 0 :(得分:1)
EXECUTE master.sys.sp_MSforeachdb
'USE [?];if db_id()>4 and db_name() not in (''somedb'',''somedb1'') drop view viewname;'
答案 1 :(得分:1)
Powershell救援!
push-location;
import-module sqlps -disablenamechecking;
pop-location;
$s = new-object microsoft.sqlserver.management.smo.server 'yourServer';
foreach ($db in $s.Databases | where {$_.IsAccessible -eq $true}) {
$v = $db.Views['ViewName'];
if ($v -ne $null) {
$v.Drop();
}
}
答案 2 :(得分:0)
Exec('USE ' +@DBname+'; IF EXISTS (SELECT *
FROM sys.views
WHERE object_id= OBJECT_ID(N''[ViewName]''))
DROP VIEW [ViewName]'
);
答案 3 :(得分:0)
我将原来的EXEC语句替换为下面粘贴的,并且所有语句都按照我需要的方式工作。
Exec(
'Use ['+@DBName+'] ;
IF EXISTS (SELECT * FROM '+@DBname+'.sys.views WHERE object_id = OBJECT_ID(N''[ViewName]''))
DROP VIEW [ViewName]'
);
答案 4 :(得分:0)
几乎所有东西都适合您的数据库。除了我不会在那里使用光标,因为它绝对是多余的,尝试不惜任何代价避免它们并开始考虑基于行集的逻辑。
您可以像这样动态构建查询:
DECLARE @SQL NVARCHAR(MAX) = N'';
SELECT @SQL += N'
USE ' + QUOTENAME([name]) + ';
IF OBJECT_ID(''[ViewName]'', ''V'') IS NOT NULL
DROP VIEW [ViewName];'
FROM sys.databases
WHERE [name] NOT IN ('DBName1','DBName2')
ORDER BY [name];
EXEC sys.sp_executesql @SQL;
在我的本地实例上,它会生成这样的查询:
USE [AdventureWorks2014];
IF OBJECT_ID('[ViewName]', 'V') IS NOT NULL
DROP VIEW [ViewName];
USE [master];
IF OBJECT_ID('[ViewName]', 'V') IS NOT NULL
DROP VIEW [ViewName];
USE [model];
IF OBJECT_ID('[ViewName]', 'V') IS NOT NULL
DROP VIEW [ViewName];
USE [msdb];
IF OBJECT_ID('[ViewName]', 'V') IS NOT NULL
DROP VIEW [ViewName];
USE [ReportServer];
IF OBJECT_ID('[ViewName]', 'V') IS NOT NULL
DROP VIEW [ViewName];
USE [ReportServerTempDB];
IF OBJECT_ID('[ViewName]', 'V') IS NOT NULL
DROP VIEW [ViewName];
USE [tempdb];
IF OBJECT_ID('[ViewName]', 'V') IS NOT NULL
DROP VIEW [ViewName];
USE [test];
IF OBJECT_ID('[ViewName]', 'V') IS NOT NULL
DROP VIEW [ViewName];
总体而言,@TheGameiswar建议的解决方案是最好的解决方案,它使用sys.sp_MSforeachdb
,这是针对此类用例创建的。