これを行うには、カーソル、手動ループなど、さまざまな方法があります。セットベースの方法で、必要なもの(ミステリークエリへの回答を意味する)を見つける方法が考えられます。いずれにせよ、言い換えると、動的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-より回復力のある方法
私の小さなテストDBでこれを試していると、最初のソリューション(および他のすべてのソリューション)に潜在的な問題があることに気付きました。 ビューが古くなる可能性があります。つまり、基になるオブジェクトが列の名前変更のように変更されます。他のすべてのソリューションはエラーをスローし、処理を停止します。大規模/長いクエリを実行している場合、これは望ましくない場合があります。そこで、エラーを記録して処理を続行するために、エラー処理を少し追加しました。
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;