SQL 2000 and 2005 Taskpad View Replacement using SQL 2005 RS   1 comment

Originally published Saturday, December 29, 2007 at http://www.biblereadingschedule.com/nucleus?itemid=76&catid=6

As promised, here are a stored procedure and a SQL Server 2005 Reporting Services report that give you a view similar to the Taskpad view in the old SQL 2000 Enterprise Manager. This report is not meant to emulate every feature in the Taskpad view. Rather I created it as a handy tool to help manage file sizes and other aspects of SQL servers. The stored procedure and report will work accurately against both SQL 2000 and 2005 instances.

The output includes logical and physical file names and sizes, file locations, used vs. free space in each file, database compatibility level of the database, database recovery model (full, simple, or bulk logged), and Autogrowth settings. Additionally, the report includes sections for free disk space, SQL edition and version, and configuration settings.

First the stored procedure, which you will need to deploy in the master database of every SQL Instance you wish to report on.

Here is the script. To easily copy the code, hover your mouse over the below section and click the “copy to clipboard” button in the tool bar that appears at the top right. If the copy button is not available, then click the “view source” button, press Ctrl + A to select all, and Ctrl + C to copy. Then paste into your favorite editor.

USE [myDatabaseName]

USE [master]
GO

IF OBJECT_ID('dba_rpt_SQL_Files_Report') IS NOT NULL
	DROP PROCEDURE dba_rpt_SQL_Files_Report
GO

CREATE PROCEDURE [dbo].[dba_rpt_SQL_Files_Report]

AS

/*

	12/29/2007 by Norm Enger, https://thesqlguy.wordpress.com/2010/11/15/sql-2000-and-2005-taskpad-view-replacement-using-sql-2005-rs/

	Reports on the file info for all dbs on a SQL instance, SQL 2000 and above.

	EXEC dba_rpt_SQL_Files_Report
	
	8/29/2007 - NE - Added db compatibility level 
	(cmptlevel from sysdatabases) as part of results.
	
	12/21/2007 - NE - Added Autogrowth.
	
	1/5/2009 - NE - Added tempdb initial file sizes 
	(sizes they would be upon a server restart) and 
	growth.
	
	5/6/2010 - NE - Changed DEC(* casts to DEC(38,7).

	12/27/2011 - NE - Fixed bug that did not handle 
	multiple tlog files. If there is more than one tlog 
	file, each will now be displayed, and the used 
	space of each is calculated based on logused 
	(percentage) value returned from "DBCC sqlperf(logspace) 
	with no_infomsgs" applied against each tlog file.

*/

SET NOCOUNT ON

DECLARE @cmd1 VARCHAR(8000)
DECLARE @cmd2 VARCHAR(8000)
DECLARE @cmd3 VARCHAR(8000)

CREATE TABLE #data(
	dbname VARCHAR(300),
	dbcompat VARCHAR(10),
	Fileid       int NOT NULL,
	[FileGroup]  int NOT NULL,
	TotalExtents int NOT NULL,
	UsedExtents  int NOT NULL,
	[Name]       sysname NOT NULL,
	[FileName]   varchar(300) NOT NULL,
	FilePath     VARCHAR(500) NULL,
	Autogrowth	 VARCHAR(500) NULL,
	init_size_MB DECIMAL (38,7) NULL,
	tempdb_growth_MB DECIMAL (38,7) NULL
)

CREATE TABLE #log(
	id int identity(1,1) not null,
	groupid      INT DEFAULT 0 NULL,
	dbname       sysname NOT NULL,
	dbcompat VARCHAR(10),
--	LogSize      numeric(15,7) NOT NULL,
	LogSize      numeric(38,7) NOT NULL,
--	LogUsed      numeric(9,5) NOT NULL,
	LogUsed      numeric(38,7) NOT NULL,
	Status       int NOT NULL,
	[Name]   VARCHAR(300) NULL,
	FilePath     VARCHAR(500) NULL,
	Autogrowth	 VARCHAR(500) NULL,
	init_size_MB DECIMAL (38,7) NULL,
	tempdb_growth_MB DECIMAL (38,7) NULL
)

DECLARE @DBs table (name sysname, status varchar(100), dbcompat varchar(10))
DECLARE @CurrDB varchar(500)
DECLARE @CurrCmptlevel varchar(10)

INSERT INTO @DBs 
(name, dbcompat)
SELECT name, cmptlevel
FROM sysdatabases 
WHERE category IN ('0', '1','16') 
AND CAST(DATABASEPROPERTYEX (name, 'status') AS VARCHAR(500)) = 'ONLINE'
ORDER BY name

SELECT @CurrDB = MIN(name) FROM @DBs
SELECT @CurrCmptlevel = dbcompat FROM @DBs WHERE name = @CurrDB

--Data files
WHILE @CurrDB IS NOT NULL
BEGIN
	SET @cmd1 = 'USE [' + @CurrDB + ']; INSERT #data (Fileid, FileGroup, TotalExtents, UsedExtents, Name, FileName) EXEC(''DBCC showfilestats with no_infomsgs''); UPDATE #data SET dbname = ''' + @CurrDB + ''', dbcompat = ''' + CAST(@CurrCmptlevel AS VARCHAR(10)) + ''' WHERE dbname IS NULL; update #data set [FilePath] = s.filename, Autogrowth = ''Autogrowth: '' + CASE WHEN (s.status & 0x100000 = 0 AND CEILING((s.growth * 8192.0)/(1024.0*1024.0)) = 0.00) OR s.growth = 0 THEN ''None'' WHEN s.status & 0x100000 = 0 THEN ''By '' + CONVERT(VARCHAR,CEILING((s.growth * 8192.0)/(1024.0*1024.0))) + '' MB'' ELSE ''By '' + CONVERT(VARCHAR, s.growth) + '' percent'' END + CASE WHEN (s.status & 0x100000 = 0 AND CEILING((s.growth * 8192.0)/(1024.0*1024.0)) = 0.00) OR s.growth = 0 THEN '''' WHEN CAST([maxsize]*8.0/1024 AS DEC(38,7)) <= 0.00 THEN '', unrestricted growth'' ELSE '', restricted growth to '' + CAST(CAST([maxsize]*8.0/1024 AS DEC(38,7)) AS VARCHAR) + '' MB'' END from #data d inner join dbo.sysfiles s on d.FileGroup = s.groupid and d.Fileid = s.fileid where d.dbname = ''' + @CurrDB + ''''
	   
	EXEC (@cmd1)

	SELECT @CurrDB = MIN(name) FROM @DBs WHERE name > @CurrDB
	SELECT @CurrCmptlevel = dbcompat FROM @DBs WHERE name = @CurrDB

END

SELECT @CurrDB = MIN(name) FROM @DBs
SELECT @CurrCmptlevel = dbcompat FROM @DBs WHERE name = @CurrDB

--Log files
WHILE @CurrDB IS NOT NULL
BEGIN

	--Update log file logical names
	SET @cmd3 = 'USE [' + @CurrDB + ']; INSERT #log (dbname, LogSize, LogUsed, Status) EXEC(''DBCC sqlperf(logspace) with no_infomsgs''); INSERT #log (dbname, [groupid], LogSize, LogUsed, Status, [Name]) SELECT ''' + @CurrDB + ''' , [s].[groupid] , s.[size] * 0.0078125 as [size], 0, 0, [name] FROM dbo.sysfiles s WHERE [groupid] = 0; USE [' + @CurrDB + ']; UPDATE #log SET [#log].[LogUsed] = b.[LogUsed] FROM [#log] t INNER JOIN (	SELECT [l].[dbname] , [LogUsed] FROM #log l lEFT JOIN ( SELECT dbname, Name, MIN(id) AS id FROM #log GROUP BY dbname, Name ) k ON l.dbname = k.dbname AND l.Name = k.Name AND l.id = k.id  WHERE k.id IS NULL ) AS b ON [t].[dbname] = [b].[dbname]; DELETE #log where Name IS NULL; USE [master]; update #log set [Name] = s.name, [FilePath] = s.filename, Autogrowth = ''Autogrowth: '' + CASE WHEN (s.status & 0x100000 = 0 AND CEILING((s.growth * 8192.0)/(1024.0*1024.0)) = 0.00) OR s.growth = 0 THEN ''None'' WHEN s.status & 0x100000 = 0 THEN ''By '' + CONVERT(VARCHAR,CEILING((s.growth * 8192.0)/(1024.0*1024.0))) + '' MB'' ELSE ''By '' + CONVERT(VARCHAR, s.growth) + '' percent'' END + CASE WHEN (s.status & 0x100000 = 0 AND CEILING((s.growth * 8192.0)/(1024.0*1024.0)) = 0.00) OR s.growth = 0 THEN '''' WHEN CAST([maxsize]*8.0/1024 AS DEC(38,7)) <= 0.00 THEN '', unrestricted growth'' ELSE '', restricted growth to '' + CAST(CAST([maxsize]*8.0/1024 AS DEC(38,7)) AS VARCHAR) + '' MB'' END from #log l inner join [' + @CurrDB + '].dbo.sysfiles s on l.groupid = s.groupid AND l.[Name] COLLATE DATABASE_DEFAULT = s.[name] COLLATE DATABASE_DEFAULT where l.dbname = ''' + @CurrDB + '''; USE [' + @CurrDB + ']; update #log set dbcompat = ''' + @CurrCmptlevel + ''' where dbname = ''' + @CurrDB + ''''

	EXEC (@cmd3)

	SELECT @CurrDB = MIN(name) FROM @DBs WHERE name > @CurrDB
	SELECT @CurrCmptlevel = dbcompat FROM @DBs WHERE name = @CurrDB

END

--Get tempdb initial file sizes - update tempdb data files init sizes
UPDATE [#data]
SET [init_size_MB] = a.Initial_Size_MB
FROM #data d
INNER JOIN 
(
	SELECT 
		[DB_Name] = 'tempdb',
		f.[name] AS logical_file_Name,
		(CAST(f.[size] AS DECIMAL(38,7)) * 8192) / 1024 /1024 AS Initial_Size_MB
	FROM master..sysaltfiles f
		INNER JOIN master..sysdatabases d
		ON f.dbid = d.dbid
	WHERE d.name = 'tempdb') AS a
ON d.dbname = a.[DB_Name]
AND d.[Name] = a.logical_file_Name

--Get tempdb initial file sizes - update tempdb log file init sizes
UPDATE [#log]
SET [init_size_MB] = a.Initial_Size_MB
FROM #log l
INNER JOIN 
(
	SELECT 
		[DB_Name] = 'tempdb',
		f.[name] AS logical_file_Name,
		(CAST(f.[size] AS DECIMAL(38,7)) * 8192) / 1024 /1024 AS Initial_Size_MB
	FROM master..sysaltfiles f
		INNER JOIN master..sysdatabases d
		ON f.dbid = d.dbid
	WHERE d.name = 'tempdb') AS a
ON l.dbname = a.[DB_Name]
AND l.[Name] = a.logical_file_Name

--Calculate tempdb files growth
UPDATE [#data] 
SET [tempdb_growth_MB] =
CASE 
	WHEN ((TotalExtents*64)/1024.0) - init_size_MB < 0.00 THEN 0.00
	ELSE ((TotalExtents*64)/1024.0) - init_size_MB
END

UPDATE [#log]
SET [tempdb_growth_MB] =
CASE 
	WHEN LogSize - init_size_MB < 0.00 THEN 0.00
	ELSE LogSize - init_size_MB
END

--Return results for all dbs
SELECT
	dbname + ' (' + CAST(DATABASEPROPERTYEX (dbname, 'recovery') AS VARCHAR(500)) + ') (' + dbcompat + ')'  AS [DB_NAME],
	dbname AS DB_NAME_2,
	'Data File' AS [Type],
	[Name] AS [NAME],
	[FilePath],
	init_size_MB,
	(TotalExtents*64)/1024.0 AS [TotalMB],
	tempdb_growth_MB,
	(UsedExtents*64)/1024.0 AS [UsedMB],
	(TotalExtents*64)/1024.0 - (UsedExtents*64)/1024.0 AS [FreeMB],
	[Autogrowth]
FROM #data 
UNION
SELECT
	dbname + ' (' + CAST(DATABASEPROPERTYEX (dbname, 'recovery') AS VARCHAR(500)) + ') (' + dbcompat + ')' AS [DB_NAME],
	dbname AS DB_NAME_2,	
	'TLog File',
	[Name] AS [NAME],
	[FilePath],
	init_size_MB,
	LogSize,
	tempdb_growth_MB,
	((LogUsed/100)*LogSize),
	LogSize - ((LogUsed/100)*LogSize),
	[Autogrowth]
FROM #log 
ORDER BY 1, [Type], [Name]

DROP TABLE #data
DROP TABLE #log

Now for the report. HERE is what the final report will look like (exported to .pdf).

And HERE is a zip file with the report .rdl file, which you can use as a template to use with your own list of servers. You will need to manually type your own list of SQL instances in the Report Parameters section of Business Intelligence Design Studio (BIDS).

An idea for further modification that I have implemented but not shared here is populating the list of SQL Instances dynamically from a SQL table, instead of typing them in manually in the Report Parameters section of BIDS. Another idea I have implemented is to create a weekly export of the file for each SQL instance, using the data-driven subscription functionality in SQL Enterprise Ed. Reporting Services, and saved to an archive directory, for historical purposes.

Happy reporting!

Posted November 15, 2010 by Norm Enger in Microsoft SQL Server

Advertisements

Posted November 15, 2010 by Norm Enger in Microsoft SQL Server

One response to “SQL 2000 and 2005 Taskpad View Replacement using SQL 2005 RS

Subscribe to comments with RSS.

  1. On Monday, September 14, 2009 07:11 pm
    Sergio Maldonado wrote:
    This is great! Thank you very much.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: