我想在SQL Server 2008数据库服务器上运行诊断报告。
我循环遍历所有数据库,然后对于每个数据库,我想查看每个表。但是,当我查看每个表(使用tbl_cursor
)时,它总是选择数据库'master'
中的表。
我认为这是因为我的tbl_cursor
选择:
SELECT table_name FROM information_schema.tables WHERE table_type = 'base table'
如何解决此问题?
以下是整个代码:
SET NOCOUNT ON
DECLARE @table_count INT
DECLARE @db_cursor VARCHAR(100)
DECLARE database_cursor CURSOR FOR
SELECT name FROM sys.databases where name<>N'master'
OPEN database_cursor
FETCH NEXT FROM database_cursor INTO @db_cursor
WHILE @@Fetch_status = 0
BEGIN
PRINT @db_cursor
SET @table_count = 0
DECLARE @table_cursor VARCHAR(100)
DECLARE tbl_cursor CURSOR FOR
SELECT table_name FROM information_schema.tables WHERE table_type = 'base table'
OPEN tbl_cursor
FETCH NEXT FROM tbl_cursor INTO @table_cursor
WHILE @@Fetch_status = 0
BEGIN
DECLARE @table_cmd NVARCHAR(255)
SET @table_cmd = N'IF NOT EXISTS( SELECT TOP(1) * FROM ' + @table_cursor + ') PRINT N'' Table ''''' + @table_cursor + ''''' is empty'' '
--PRINT @table_cmd --debug
EXEC sp_executesql @table_cmd
SET @table_count = @table_count + 1
FETCH NEXT FROM tbl_cursor INTO @table_cursor
END
CLOSE tbl_cursor
DEALLOCATE tbl_cursor
PRINT @db_cursor + N' Total Tables : ' + CAST( @table_count as varchar(2) )
PRINT N'' -- print another blank line
SET @table_count = 0
FETCH NEXT FROM database_cursor INTO @db_cursor
END
CLOSE database_cursor
DEALLOCATE database_cursor
SET NOCOUNT OFF
答案 0 :(得分:2)
使用表变量更容易,因此可以使用另一个动态SQL语句将行添加到@tablist
SET NOCOUNT ON
DECLARE @table_count INT
DECLARE @dblist TABLE (DBName VARCHAR(100))
DECLARE @tablist TABLE (TableName VARCHAR(100))
DECLARE @dbname varchar(100), @tabname varchar(100)
INSERT @dblist
SELECT name FROM sys.databases where name<>N'master'
SELECT TOP 1 @dbname = DBName FROM @dblist
WHILE @@ROWCOUNT <> 0
BEGIN
INSERT @tablist (tableName)
EXEC ('SELECT table_name FROM ' + @dbname + '.information_schema.tables WHERE table_type = ''base table'' ')
SELECT TOP 1 @tabname = tableName FROM @tablist
WHILE @@ROWCOUNT <> 0
BEGIN
--do my stuff
DELETE @tablist WHERE tableName = @tabname
SELECT TOP 1 @tabname = tableName FROM @tablist
END
DELETE @dblist WHERE DBName = @dbname
SELECT TOP 1 @dbname = DBName FROM @dblist
END
答案 1 :(得分:2)
问题是因为您实际上总是在主db上下文下运行INFORMATION_SCHEMA.TABLES查询。
您需要将tbl_cursor块转换为动态SQL,以便使用数据库名称完全限定查询。
e.g。
SELECT table_name FROM YourDatabase.INFORMATION_SCHEMA.TABLES WHERE....
基本上就是你需要为该游标执行的内容。
答案 2 :(得分:0)
您可能必须创建动态SQL。因为information_schema将仅从您运行此查询的当前活动数据库中获取对象。
你可以试试sys.objects