如何 select Microsoft SQL 2008 中每个 VIEW 的单个元素
How to select a single element from each VIEW in Microsoft SQL 2008
我正在尝试 select 来自数据库中每个视图的单个元素,以检查它们是否仍在 "correct form" 中。难的是这种观点的数量太多了。当我研究这个时,我发现了这段代码,它找到了所有 table 名称及其列名称。
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;
对于第一步,我认为在我的数据库中找到所有视图的名称将是一个好的开始。这是数据库结构。
数据库:
DB1、DB2、DB3……
对于每个数据库:DatabaseDiagrams、Tables、Views...
为了在我的数据库中找到所有视图,我写了这篇文章。
SELECT t.name AS view_name
FROM sys.views AS t
ORDER BY view_name;
其中一些数据库的文件夹中有 0 个视图,而有些数据库有很多视图。我的目标是 select 来自每个视图的单个元素。我怎样才能做到这一点?
编辑:这是我找到的答案
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;
代码对我来说 crystal 很清楚,但我可以向在某处遇到问题的任何人解释。
好的,下一个查询有点长,但我认为它可以满足您的要求:
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 *
语句输出到一个table变量中。然后我们打开一个游标并逐行执行语句。如果需要,您甚至可以通过取消注释 --WHERE selectStmt NOT LIKE '%DB1%';
部分来过滤游标中的数据库。
对于执行成功的视图,不会出现任何消息。对于失败的执行,将出现 'Execution failed:' + 查看消息。
有两点你必须要小心:
1) 如果您有很多浏览量,即使您过滤光标也需要很长时间。
2) 您或许应该考虑将结果输出到文件中。
我正在尝试 select 来自数据库中每个视图的单个元素,以检查它们是否仍在 "correct form" 中。难的是这种观点的数量太多了。当我研究这个时,我发现了这段代码,它找到了所有 table 名称及其列名称。
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;
对于第一步,我认为在我的数据库中找到所有视图的名称将是一个好的开始。这是数据库结构。
数据库: DB1、DB2、DB3…… 对于每个数据库:DatabaseDiagrams、Tables、Views...
为了在我的数据库中找到所有视图,我写了这篇文章。
SELECT t.name AS view_name
FROM sys.views AS t
ORDER BY view_name;
其中一些数据库的文件夹中有 0 个视图,而有些数据库有很多视图。我的目标是 select 来自每个视图的单个元素。我怎样才能做到这一点?
编辑:这是我找到的答案
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;
代码对我来说 crystal 很清楚,但我可以向在某处遇到问题的任何人解释。
好的,下一个查询有点长,但我认为它可以满足您的要求:
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 *
语句输出到一个table变量中。然后我们打开一个游标并逐行执行语句。如果需要,您甚至可以通过取消注释 --WHERE selectStmt NOT LIKE '%DB1%';
部分来过滤游标中的数据库。
对于执行成功的视图,不会出现任何消息。对于失败的执行,将出现 'Execution failed:' + 查看消息。
有两点你必须要小心:
1) 如果您有很多浏览量,即使您过滤光标也需要很长时间。
2) 您或许应该考虑将结果输出到文件中。