Skip to content


MS SQL 2005 (T-SQL) Row Count for Each Table

At work I needed a solution to give me a count of how many rows each table contained. I've always liked phpMyAdmin's ability to list all the tables and show their size and row count. I've found it immensely helpful. However, I couldn't find anything similar for SQL Server Manager Studio 2005. I found a blog post that pointed me in the right direction on how to get the row counts, but I couldn't get their script to run on the SQL Server 2005. Since I figured this would be a useful script to have I would re-write it and comment it for others. Here it is:

SQL:
  1. -- Select Database
  2. -- This should be the only configuration you need
  3. USE Your_Database
  4. GO
  5.  
  6. -- Create a cursor to loop through the System Ojects and get each table name
  7. DECLARE TBL_CURSOR CURSOR
  8. -- Declare the SQL Statement to cursor through
  9. FOR ( SELECT Name FROM Sysobjects WHERE Type='U' )
  10.  
  11. -- Declare the @SQL Variable which will hold our dynamic sql
  12. DECLARE @SQL NVARCHAR(MAX);
  13. SET @SQL = '';
  14. -- Declare the @TblName Variable which will hold the name of the current table
  15. DECLARE @TblName NVARCHAR(MAX);
  16.  
  17. -- Open the Cursor
  18. OPEN TBL_CURSOR
  19.  
  20. -- Setup the Fetch While that will loop through our cursor and set @TblName
  21. FETCH NEXT FROM TBL_CURSOR INTO @TblName
  22. -- Do this while we are not at the end of the record set
  23. WHILE (@@FETCH_STATUS <> -1)
  24. BEGIN
  25. -- Appeand this table's select count statement to our sql variable
  26. SET @SQL = @SQL + ' ( SELECT '''+@TblName+''' AS Table_Name,COUNT(*) AS Count FROM '+@TblName+' ) UNION';
  27.  
  28. -- Pull the next record
  29. FETCH NEXT FROM TBL_CURSOR INTO @TblName
  30. -- End the Cursor Loop
  31. END
  32.  
  33. -- Close and Clean Up the Cursor
  34. CLOSE TBL_CURSOR
  35. DEALLOCATE TBL_CURSOR
  36.  
  37. -- Since we were adding the UNION at the end of each part, the last query will have
  38. -- an extra UNION. Lets  trim it off.
  39. SET @SQL = LEFT(@SQL,LEN(@SQL)-6);
  40.  
  41. -- Lets do an Order By. You can pick between Count and Table Name by picking which
  42. -- line to execute below.
  43. SET @SQL = @SQL + ' ORDER BY Count';
  44. --SET @SQL = @SQL + ' ORDER BY Table_Name';
  45.  
  46. -- Now that our Dynamic SQL statement is ready, lets execute it.
  47. EXEC (@SQL);
  48. GO

How it works

A basic description would be it gets a listing of each table inside the the System Objects table and creates a Dynamic SQL Statement that get a count from each table and return a record set with the Table's name and count. Pretty straight forward, and I commented just about every little thing in the script so it should be easy to follow along. Let me know if you have any suggestions or tips for making it better. Thanks!

Related Posts

  1. MySQL - Does Table Exist w/o Throwing Errors There are times where you would like to know if a table exists before executing an query. Most solutions require having MySQL throw an error saying "table does not exist," but I prefer a cleaner way. I found on this forum post a clean way to do it: PLAIN TEXT...
  2. MySQL & PHP - SQL_CALC_FOUND_ROWS - An easy way to get the total number of rows regardless of LIMIT Here is a little trick I found awhile back. I faced a challenge several months ago where I had to query a large, complex data result from MySQL. I "paged" through the results using LIMIT and OFFSET. However, I wanted to know the total number of rows w/o the LIMIT....
  3. PHP Design - Biggest Database Oversights Over the last three years I've had the opportunity to work on several PHP projects, some of them having grown rapidly and required to scale quickly. Three in particular have been a fantastic learning experience for me. Now I don't consider myself a total expert, but I thought I would...

Posted in Programming. Tagged with , , , , .

4 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Hans Callesen said

    replaced cursor with a table vriable & a while loop. More efficient , though not noticable with small datasets such as these:
    ——-
    – Select Database
    – This should be the only configuration you need
    USE Testing
    GO
    declare @Tables table (id integer identity(1,1),TName varchar(max))
    insert into @Tables (TName) SELECT Name FROM Sysobjects WHERE Type=’U’
    – Declare the @SQL Variable which will hold our dynamic sql
    DECLARE @SQL NVARCHAR(MAX);
    Declare @counter integer
    – Declare the @TblName Variable which will hold the name of the current table
    DECLARE @TblName NVARCHAR(MAX);
    SET @SQL = ”;
    select @counter = 1
    While @counter <= (select max(id) from @Tables)
    Begin–While Loop
    select @TblName = (select TName from @Tables where id = @Counter)
    – Appeand this table’s select count statement to our sql variable
    SET @SQL = @SQL + ‘ ( SELECT ”’+@TblName+”’ AS Table_Name,COUNT(*) AS Count FROM ‘+@TblName+’ ) UNION’;
    select @counter = @counter+1
    End–While Loop

    – Since we were adding the UNION at the end of each part, the last query will have
    – an extra UNION. Lets trim it off.
    SET @SQL = LEFT(@SQL,LEN(@SQL)-6);

    – Lets do an Order By. You can pick between Count and Table Name by picking which
    – line to execute below.
    SET @SQL = @SQL + ‘ ORDER BY Count’;
    –SET @SQL = @SQL + ‘ ORDER BY Table_Name’;

    – Now that our Dynamic SQL statement is ready, lets execute it.
    EXEC (@SQL);
    GO
    ——-

  2. try this
    use yourdatabasename

    SELECT name, rows FROM sysindexes where impid < 0 order by name

  3. Dos said

    The sysindexes query is fine but relies upon your database stats being up-to-date.

    Also I found that square brackets were needed around the tablename on line 26 - in the dynamic query (some of my tables begin with a numeric character)

    instead of:
    SET @SQL = @SQL + ‘ ( SELECT ”’+@TblName+”’ AS Table_Name,COUNT(*) AS Count FROM ‘+@TblName+’ ) UNION’

    use:
    SET @SQL = @SQL + ‘ ( SELECT ”’+@TblName+”’ AS Table_Name,COUNT(*) AS Count FROM ['+@TblName+'] ) UNION’

  4. Neal said

    Wouldn’t this be easier?!

    SELECT ’select ”’+ name + ”’, count(*) from ‘ + name + ‘ union’
    FROM Sysobjects
    WHERE Type=’U’
    ORDER BY 1;

    Copy + paste the results, remove the trailing ‘union’ and add your ‘order by’ clause.

Some HTML is OK

(required)

(required, but never shared)

or, reply to this post via trackback.

Powered by WP Hashcash