SQL如何遍历我的视图列表

时间:2012-09-27 15:12:46

标签: sql sql-server loops views

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

背景和尝试的事情
我现在用Google搜索了大约2个小时,我找到了很多方法来循环我的数据库的不同属性。我可以遍历一个表列表,一个列列表和一个计数列表,但我还没有找到任何允许我遍历一个视图列表的内容。

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

link i used to obtain sample code below

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

请求帮助

有人可以链接到我有关如何执行此操作或提供示例代码的更多信息吗?非常感谢所有帮助!谢谢!

3 个答案:

答案 0 :(得分:3)

执行此操作的一种方法是使用游标。你肯定需要动态SQL,所以首先转到this link。然后,您可以尝试以下方法:

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

答案 1 :(得分: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

答案 2 :(得分:1)

有很多方法可以做到这一点,游标,手动循环。有可能以基于集合的方式找到您想要的内容(意味着您的神秘查询的答案)。无论哪种方式,如你所说,你需要动态的SQL。

选项1 - 一个方法

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;