3

问题
我如何循环查看我的 SQL DB 中的视图列表?

背景和尝试的事情
我已经用谷歌搜索了大约 2 个小时,我发现了很多方法来遍历我的数据库的不同属性。我可以遍历一个表列表、一个列列表和一个计数列表,但我还没有找到任何可以让我遍历视图列表的东西。

循环遍历表的代码我试图修改

我用来获取以下示例代码的链接

--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

One way to do this is using cursors. And you are definitely gonna need dynamic SQL, so first go to this link. Then, you can try the following:

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 - 更具弹性的方法
在我的小测试数据库中尝试此方法时,我意识到我的第一个解决方案(以及所有其他解决方案)存在潜在问题。 视图可能会过时——这意味着底层对象会像列重命名一样发生变化。所有其他解决方案都将引发错误并停止处理。如果您正在执行大/长查询,这可能是不可取的。所以我添加了一点错误处理来记录错误并继续处理。

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 回答