-- Run this script in your user database -- There are two procedure create statements in this script. The first one reports the size -- of each user table in the current database. The second procedure provides support for -- table names that are longer than 20 characters (a limitation of system stored procedure sp_spaceused) -- It will support tablenames of 50 characters or less, which should be sufficient in most cases if exists(select * from sysobjects where id=object_id('usp_gettablesizes') and objectproperty(id,'isprocedure')=1) drop proc usp_gettablesizes go create procedure usp_GetTableSizes @sortby varchar(5)='rows',@updateusage varchar(5)='False' as /* ** Date: August 17, 2000 ** Author: Neil Mederich ** Purpose: Report row counts and data size of user tables ** Input Parameter: @sortby = column to sort results by ('rows' or 'data' or 'name') ** Input Parameter: @updateusage = update statistics ('true' or 'false') */ set nocount on declare @dependency char(1) if exists(select * from sysobjects where id=object_id('sp_spaceused2') and objectproperty(id,'isprocedure')=1) set @dependency='T' else set @dependency='F' if @updateusage='True' Begin DBCC UPDATEUSAGE (0) with NO_INFOMSGS End create table #sdtt ([name] nvarchar(50),[rows] int,[reserved] varchar(18), [data] varchar(18),[index_size] varchar(18),[unused] varchar(18)) select convert(varchar(50),a.name) as tablename into #sdt from sysobjects a where a.type='u' and objectproperty(a.id,'istable')=1 declare @x varchar(50), @y varchar(255) declare cOne cursor for select distinct tablename from #sdt order by tablename open cOne fetch next from cOne into @x While @@fetch_status=0 begin if @dependency = 'T' set @y = 'exec sp_spaceused2 @objname=' + @x else set @y = 'exec sp_spaceused @objname=' + @x set @y = 'insert #sdtt ' + @y execute(@y) fetch next from cOne into @x end close cOne deallocate cOne declare @z varchar(255) if @sortby='name' set @z = 'select * from #sdtt order by ' + @sortby + ' asc' else set @z = 'select * from #sdtt order by ' + @sortby + ' desc' exec (@z) go if exists(select * from sysobjects where id=object_id('sp_spaceused2') and objectproperty(id,'isprocedure')=1) drop proc sp_spaceused2 go CREATE procedure sp_spaceused2 /* ** The Original version (sp_spaceused) truncates table name at 20 characters. ** Sp_spaceused2 is a slightly modified version that allows the usp_GetTableSizes stored procedure to ** report on tables that have a name up to 50 characters in length. ** If all your user table names are 20 characters or less you can get by without adding this procedure. */ @objname nvarchar(776) = null, -- The object we want size on. @updateusage varchar(5) = false -- Param. for specifying that -- usage info. should be updated. as declare @id int -- The object id of @objname. declare @type character(2) -- The object type. declare @pages int -- Working variable for size calc. declare @dbname sysname declare @dbsize dec(15,0) declare @bytesperpage dec(15,0) declare @pagesperMB dec(15,0) /*Create temp tables before any DML to ensure dynamic ** We need to create a temp table to do the calculation. ** reserved: sum(reserved) where indid in (0, 1, 255) ** data: sum(dpages) where indid < 2 + sum(used) where indid = 255 (text) ** indexp: sum(used) where indid in (0, 1, 255) - data ** unused: sum(reserved) - sum(used) where indid in (0, 1, 255) */ create table #spt_space ( rows int null, reserved dec(15) null, data dec(15) null, indexp dec(15) null, unused dec(15) null ) /* ** Check to see if user wants usages updated. */ if @updateusage is not null begin select @updateusage=lower(@updateusage) if @updateusage not in ('true','false') begin raiserror(15143,-1,-1,@updateusage) return(1) end end /* ** Check to see that the objname is local. */ if @objname IS NOT NULL begin select @dbname = parsename(@objname, 3) if @dbname is not null and @dbname <> db_name() begin raiserror(15250,-1,-1) return (1) end if @dbname is null select @dbname = db_name() /* ** Try to find the object. */ select @id = null select @id = id, @type = xtype from sysobjects where id = object_id(@objname) /* ** Does the object exist? */ if @id is null begin raiserror(15009,-1,-1,@objname,@dbname) return (1) end if not exists (select * from sysindexes where @id = id and indid < 2) if @type in ('P ','D ','R ','TR','C ','RF') --data stored in sysprocedures begin raiserror(15234,-1,-1) return (1) end else if @type = 'V ' -- View => no physical data storage. begin raiserror(15235,-1,-1) return (1) end else if @type in ('PK','UQ') -- no physical data storage. --?!?! too many similar messages begin raiserror(15064,-1,-1) return (1) end else if @type = 'F ' -- FK => no physical data storage. begin raiserror(15275,-1,-1) return (1) end end /* ** Update usages if user specified to do so. */ if @updateusage = 'true' begin if @objname is null dbcc updateusage(0) with no_infomsgs else dbcc updateusage(0,@objname) with no_infomsgs print ' ' end set nocount on /* ** If @id is null, then we want summary data. */ /* Space used calculated in the following way ** @dbsize = Pages used ** @bytesperpage = d.low (where d = master.dbo.spt_values) is ** the # of bytes per page when d.type = 'E' and ** d.number = 1. ** Size = @dbsize * d.low / (1048576 (OR 1 MB)) */ if @id is null begin select @dbsize = sum(convert(dec(15),size)) from dbo.sysfiles select @bytesperpage = low from master.dbo.spt_values where number = 1 and type = 'E' select @pagesperMB = 1048576 / @bytesperpage select database_name = db_name(), database_size = ltrim(str(@dbsize / @pagesperMB,15,2) + ' MB'), 'unallocated space' = ltrim(str((@dbsize - (select sum(convert(dec(15),reserved)) from sysindexes where indid in (0, 1, 255) )) / @pagesperMB,15,2)+ ' MB') print ' ' /* ** Now calculate the summary data. ** reserved: sum(reserved) where indid in (0, 1, 255) */ insert into #spt_space (reserved) select sum(convert(dec(15),reserved)) from sysindexes where indid in (0, 1, 255) /* ** data: sum(dpages) where indid < 2 ** + sum(used) where indid = 255 (text) */ select @pages = sum(convert(dec(15),dpages)) from sysindexes where indid < 2 select @pages = @pages + isnull(sum(convert(dec(15),used)), 0) from sysindexes where indid = 255 update #spt_space set data = @pages /* index: sum(used) where indid in (0, 1, 255) - data */ update #spt_space set indexp = (select sum(convert(dec(15),used)) from sysindexes where indid in (0, 1, 255)) - data /* unused: sum(reserved) - sum(used) where indid in (0, 1, 255) */ update #spt_space set unused = reserved - (select sum(convert(dec(15),used)) from sysindexes where indid in (0, 1, 255)) select reserved = ltrim(str(reserved * d.low / 1024.,15,0) + ' ' + 'KB'), data = ltrim(str(data * d.low / 1024.,15,0) + ' ' + 'KB'), index_size = ltrim(str(indexp * d.low / 1024.,15,0) + ' ' + 'KB'), unused = ltrim(str(unused * d.low / 1024.,15,0) + ' ' + 'KB') from #spt_space, master.dbo.spt_values d where d.number = 1 and d.type = 'E' end /* ** We want a particular object. */ else begin /* ** Now calculate the summary data. ** reserved: sum(reserved) where indid in (0, 1, 255) */ insert into #spt_space (reserved) select sum(reserved) from sysindexes where indid in (0, 1, 255) and id = @id /* ** data: sum(dpages) where indid < 2 ** + sum(used) where indid = 255 (text) */ select @pages = sum(dpages) from sysindexes where indid < 2 and id = @id select @pages = @pages + isnull(sum(used), 0) from sysindexes where indid = 255 and id = @id update #spt_space set data = @pages /* index: sum(used) where indid in (0, 1, 255) - data */ update #spt_space set indexp = (select sum(used) from sysindexes where indid in (0, 1, 255) and id = @id) - data /* unused: sum(reserved) - sum(used) where indid in (0, 1, 255) */ update #spt_space set unused = reserved - (select sum(used) from sysindexes where indid in (0, 1, 255) and id = @id) update #spt_space set rows = i.rows from sysindexes i where i.indid < 2 and i.id = @id -- Line below is the line that was changed to allow table names up to 50 characters select name = substring(object_name(@id), 1, 50), rows = convert(char(11), rows), reserved = ltrim(str(reserved * d.low / 1024.,15,0) + ' ' + 'KB'), data = ltrim(str(data * d.low / 1024.,15,0) + ' ' + 'KB'), index_size = ltrim(str(indexp * d.low / 1024.,15,0) + ' ' + 'KB'), unused = ltrim(str(unused * d.low / 1024.,15,0) + ' ' + 'KB') from #spt_space, master.dbo.spt_values d where d.number = 1 and d.type = 'E' end return (0)