使用SQL Server 2012.
使用为每个数据库存储的系统视图,我希望保留实例中所有索引的索引行为摘要。下面的代码收集一些统计信息并将它们放在一个表中供以后使用。问题是,我不得不使用游标来遍历实例中的数据库。任何人都可以建议一种更好的方法,而不必使用光标吗?
USE Master
GO
-- If the procedure already exists then update it.
IF OBJECT_ID('sp_index_stats') IS NOT NULL
DROP PROCEDURE sp_index_stats
GO
CREATE PROCEDURE sp_index_stats AS
DECLARE @dbname NVARCHAR(128)
DECLARE @finalSQL NVARCHAR(1024)
-- Results of the query are put into a table in Demo_DB.
-- So empty it now for the new results.
TRUNCATE TABLE Demo_DB.dbo.index_stats
-- Use a cursor to get a list of all the tables in the instance.
DECLARE database_cursor CURSOR LOCAL FOR
SELECT name
FROM Master.dbo.sysdatabases
WHERE name NOT IN ('master', 'model', 'msdb', 'tempdb')
OPEN database_cursor
FETCH NEXT FROM database_cursor INTO @dbname
WHILE @@FETCH_STATUS = 0
BEGIN
-- Each database will contain the same structue, so I need
-- to create a standard query just changing the database name.
SET @finalSQL = 'INSERT INTO Demo_DB.dbo.index_stats '
-- Sort out the select statement.
SET @finalSQL = @finalSQL + 'SELECT sdb.name, st.name, si.name, si.type_desc, '
SET @finalSQL = @finalSQL + 'si.is_primary_key, si.fill_factor, '
SET @finalSQL = @finalSQL + 'sd.user_scans, sd.last_user_scan, '
SET @finalSQL = @finalSQL + 'sd.user_updates, sd.last_user_update '
-- The 'from' and 'joins' need to be adjusted slightly for each databse.
SET @finalSQL = @finalSQL + 'FROM ' + @dbname + '.sys.tables st '
SET @finalSQL = @finalSQL + 'JOIN ' + @dbname + '.sys.indexes si ON (si.object_id = st.object_id) '
SET @finalSQL = @finalSQL + 'JOIN ' + @dbname + '.sys.dm_db_index_usage_stats sd ON (si.object_id = sd.object_id) '
SET @finalSQL = @finalSQL + 'JOIN ' + @dbname + '.sys.databases sdb ON (sdb.database_id = sd.database_id) ;'
-- Ok, let's run that...
EXEC (@finalSQL)
-- Get the next database in the instance..,
FETCH NEXT FROM database_cursor INTO @dbname
END
CLOSE database_cursor
DEALLOCATE database_cursor
GO
问候,
JC。
答案 0 :(得分:0)
连接怎么样?
像这样的东西(没有复制整个存储过程,但希望你得到要点)
DECLARE @SQL VARCHAR(MAX)
SET @SQL = ''
SELECT @SQL = @SQL +
'INSERT INTO Demo_DB.dbo.index_stats ' +
'SELECT sdb.name, st.name, si.name, si.type_desc, ' +
'si.is_primary_key, si.fill_factor, ' +
'sd.user_scans, sd.last_user_scan, ' +
'sd.user_updates, sd.last_user_update ' +
'FROM ' + name + '.sys.tables st ' +
'JOIN ' + name + '.sys.indexes si ON (si.object_id = st.object_id) ' +
'JOIN ' + name + '.sys.dm_db_index_usage_stats sd ON (si.object_id = sd.object_id) ' +
'JOIN ' + name + '.sys.databases sdb ON (sdb.database_id = sd.database_id) ;'
FROM Master.dbo.sysdatabases
WHERE name NOT IN ('master', 'model', 'msdb', 'tempdb')
SELECT @SQL
(显然此时并未执行任何操作)。