有很多方法可以做到这一点,游标,手动循环。可能有多种方法可以以基于集合的方式找到您想要的内容(即神秘查询的答案)。无论哪种方式,如您所说,您都需要动态 sql。
选项 1 - so/so 方法
SET NOCOUNT ON;
DECLARE @Views as TABLE (Object_id int, name nvarchar(200));
INSERT INTO @Views (Object_ID, name)
SELECT Object_ID, name
FROM sys.views
DECLARE @viewName nvarchar(200) = (select top 1 name from @Views);
DECLARE @sql nvarchar(max) = '';
WHILE(Exists(select 1 from @Views)) BEGIN
SET @sql = 'select count(*) FROM ' + @ViewName +';'
--exec(@sql); --careful you're not accepting user input here!
Print (@sql);
DELETE FROM @Views where name = @viewName;
SET @ViewName = (select top 1 name from @Views);
END;
选项 2 - 更具弹性的方法
在我的小测试数据库中尝试此方法时,我意识到我的第一个解决方案(以及所有其他解决方案)存在潜在问题。 视图可能会过时——这意味着底层对象会像列重命名一样发生变化。所有其他解决方案都将引发错误并停止处理。如果您正在执行大/长查询,这可能是不可取的。所以我添加了一点错误处理来记录错误并继续处理。
SET NOCOUNT ON;
DECLARE @ViewCount int = 0;
DECLARE @Counter int = 0;
DECLARE @sql nvarchar(max) = '';
DECLARE @viewName nvarchar(200) = ''
DECLARE @Views as TABLE ( rownum int identity(1,1),
name nvarchar(200),
Primary Key clustered (rownum)
);
INSERT INTO @Views (name)
SELECT name
FROM sys.views;
SET @ViewCount = SCOPE_IDENTITY();
WHILE(@Counter < @ViewCount) BEGIN
SET @Counter = @Counter+1;
SELECT @sql = 'select count(*) FROM ' + name +';', @viewName = name
FROM @Views
WHERE rownum = @Counter;
BEGIN TRY
-- exec(@sql); --careful you're not accepting user input here!
Print (@sql);
END TRY BEGIN CATCH
Print ('ERROR querying view - ' + @viewname + ' // ' + ERROR_MESSAGE());
END CATCH
END;