3

質問
SQLDBのビューのリストをループするにはどうすればよいですか?

背景と試してみた
私は約2時間グーグルで検索しましたが、DBのさまざまな属性をループする方法をたくさん見つけました。テーブルのリスト、列のリスト、カウントのリストをループできますが、ビューのリストをループできるものはまだ見つかりません。

変更しようとしたテーブルをループするコード

以下のサンプルコードを取得するために使用したリンク

--List all the tables of current database and total no rows in it
EXEC sp_MSForEachTable 'SELECT ''?'' as TableName, COUNT(1) 
as TotalRows FROM ? WITH(NOLOCK)' 

--List all the tables of current database and space used by it EXECUTE sp_MSforeachtable 'EXECUTE sp_spaceused [?];'; 
GO

私がやりたいことのためのsudoコード

loop through each view in list
run query here for each view
output results

ヘルプのリクエスト

誰かがこれを行う方法やサンプルコードを提供する方法についての詳細情報に私をリンクできますか?すべての助けは大歓迎です!ありがとう!

4

3 に答える 3

3

これを行う1つの方法は、カーソルを使用することです。そして、あなたは間違いなく動的SQLを必要とするので、最初にこのリンクにアクセスしてください。次に、次のことを試すことができます。

DECLARE @View VARCHAR(200), @Query VARCHAR(MAX)


DECLARE YourView CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR
SELECT name
FROM sys.views

OPEN YourView
FETCH NEXT FROM YourView INTO @View
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @Query = 'SELECT '''+@View+''' ViewName, COUNT(1) Rows
                  FROM '+QUOTENAME(@View)  -- Your code here
    PRINT(@Query)
    FETCH NEXT FROM YourView INTO @View
END
CLOSE YourView
DEALLOCATE YourView
于 2012-09-27T15:27:37.140 に答える
3

これを行うには、カーソル、手動ループなど、さまざまな方法があります。セットベースの方法で、必要なもの(ミステリークエリへの回答を意味する)を見つける方法が考えられます。いずれにせよ、言い換えると、動的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;    
于 2012-09-27T15:27:51.383 に答える
2

ROW_NUMBER()とINFORMATION_SCHEMAを使用して、ビューを反復処理しています。

これは、ワークリストの概要です。

SELECT TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME AS ViewName
    ,ROW_NUMBER() OVER (
        ORDER BY TABLE_CATALOG
            ,TABLE_SCHEMA
            ,TABLE_NAME
        )
FROM INFORMATION_SCHEMA.VIEWS

ストアドプロシージャは次のとおりです。

CREATE PROCEDURE LoopThroughViews
AS
DECLARE @sql VARCHAR(max)
    ,@tableCount INT
    ,@i INT = 0

SELECT @tableCount = COUNT(*)
FROM INFORMATION_SCHEMA.VIEWS

WHILE (@tableCount >= @i)
BEGIN
    SELECT @sql = 'select * from ' + ViewName
    FROM (
        SELECT TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME AS ViewName
            ,ROW_NUMBER() OVER (
                ORDER BY TABLE_CATALOG
                    ,TABLE_SCHEMA
                    ,TABLE_NAME
                ) AS ViewNum
        FROM INFORMATION_SCHEMA.VIEWS
        ) x
    WHERE @i = ViewNum

    EXEC(@sql)

    SET @i = @i + 1
END

そして最後に呼び出し:

EXEC LoopThroughViews
于 2012-09-27T15:30:45.690 に答える