我正在尝试从db中的每个视图中选择一个元素,以检查它们是否仍处于“正确的形式”。困难的是,这个视图的数量太多了。当我研究这一点时,我发现了这段代码,它查找所有的表名及其列名。
GO
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
ORDER BY schema_name, table_name;对于第一步,我认为在我的数据库中找到所有视图的名称将是一个好的开始。下面是db结构。
数据库: DB1,DB2,DB3.......对于每个数据库: DatabaseDiagrams、表、视图...
所以为了在我的数据库中找到所有的视图,我写了这段代码。
SELECT t.name AS view_name
FROM sys.views AS t
ORDER BY view_name; 其中一些数据库在其文件夹中有0个视图,而另一些则有很多视图。我的目标是从每个视图中选择一个元素。我如何才能做到这一点呢?
编辑:这是我找到的答案
SET NOCOUNT ON;
DECLARE @ViewCount int = 0;
DECLARE @Counter int = 0;
DECLARE @sql nvarchar(max) = '';
DECLARE @viewName nvarchar(120) = ''
DECLARE @Views as TABLE ( pk int identity(1,1),
viewName nvarchar(300),
Primary Key clustered (pk)
);
INSERT INTO @Views (viewName)
SELECT name
FROM sys.views;
SET @ViewCount = SCOPE_IDENTITY();
WHILE(@Counter < @ViewCount) BEGIN
SET @Counter = @Counter+1;
SELECT @sql = 'select TOP 1 * FROM ' + viewName +';', @viewName = viewName
FROM @Views
WHERE pk = @Counter;
BEGIN TRY
exec(@sql);
END TRY BEGIN CATCH
Print ('Cannot query the view ' + @viewname );
END CATCH
END; 代码对我来说非常清楚,但我可以向任何在某处有问题的人解释它。
发布于 2016-08-23 21:13:25
好的,下一个查询有点长,但我认为它做了您想要的:
SET NOCOUNT ON;
DECLARE @sql NVARCHAR(MAX) = '';
DECLARE @stmt NVARCHAR(MAX);
DECLARE @testViews TABLE (selectStmt NVARCHAR(MAX));
;WITH dbs
AS ( SELECT name
FROM sys.databases
WHERE name NOT IN ('master','msdb','tempdb','model')
)
SELECT @SQL = 'SELECT ''SELECT TOP 1* FROM ''' + '+' + '''' + QUOTENAME(dbs.name) + '''' + '+ ''.'' + QUOTENAME(SCHEMA_NAME(t.schema_id)) + ''.'' + QUOTENAME(t.name) FROM '
+ QUOTENAME(name) + '.sys.views AS t;' + @sql
FROM dbs;
INSERT INTO @testViews
EXEC(@sql);
DECLARE EXEC_CURSOR CURSOR
FOR SELECT * FROM @testViews
--WHERE selectStmt NOT LIKE '%DB1%';
OPEN EXEC_CURSOR
FETCH NEXT FROM EXEC_CURSOR INTO @stmt;
WHILE (@@FETCH_STATUS = 0)
BEGIN TRY
PRINT 'Executing: ' + @stmt;
EXEC(@stmt);
FETCH NEXT FROM EXEC_CURSOR INTO @stmt;
END TRY
BEGIN CATCH
PRINT 'Execution failed: ' + @stmt;
FETCH NEXT FROM EXEC_CURSOR INTO @stmt;
END CATCH
CLOSE EXEC_CURSOR;
DEALLOCATE EXEC_CURSOR;这实际上是做什么的。首先,在CTE中,我为每个数据库(除了系统数据库,如果您愿意,可以将其打开)构造一条SELECT语句,该语句具有以下模板:
SELECT 'SELECT TOP 1* FROM '+'[database_name]'+ '.' +
QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name) FROM
[database_name].sys.views AS t;因此,现在每个数据库都有一条SELECT语句,它为该数据库中的所有视图构造TOP 1 * SELECT语句。
然后,我们执行生成的字符串并将所有SELECT TOP 1 *语句输出到一个表变量中。然后,我们打开一个游标并逐行执行语句。如果需要,您甚至可以通过取消注释--WHERE selectStmt NOT LIKE '%DB1%';部件来过滤游标中的数据库。
对于视图the execution succeeded,不会显示消息。对于失败的执行,将出现“Execution failed:”+视图消息。
有两件事你必须小心:
1)如果你有很多视图,即使你过滤了光标,这也需要很长时间。
2)您可能应该考虑将结果输出到一个文件中。
https://stackoverflow.com/questions/39094768
复制相似问题