Link to home
Get AccessLog in
Avatar of databarracks
databarracks

asked on

SQL Server show list of tables from a database with a parameter for the Database name

Hi Guys,

I have the below query that shows a list of tables and number of rows and total space in GB. This query works really well, however I would like to create a stored procedure whereby I can add a parameter to choose what database on the same server to query?

Currently this query would only work based on the current database that I am in.  Basically the premise is that I have a simple application where an admin can change the database name via a dropdown and that will show the below queries results bases on the db name selected.

I don't know how to create a stored proc without hardcoding an if statement to set the 'USE' statement. I would rather avoid dynamic sql if that makes sense but Google seems to be pointing that way. If I have to then so be it:)

I would kindly appreciate any assistance in helping me resolve this issue?

SELECT    s.name + '.' + t.name AS [Table Name], part.rows AS [Total Rows In Table - Modified], CAST(SUM(DISTINCT au.total_pages) 
                         * 8 / 1024.000 / 1024.000 AS NUMERIC(18, 3)) AS [Table's Total Space In GB]
FROM            sys.tables AS t INNER JOIN
                         sys.schemas AS s ON t.schema_id = s.schema_id INNER JOIN
                         sys.indexes AS idx ON t.object_id = idx.object_id INNER JOIN
                         sys.partitions AS part ON idx.object_id = part.object_id AND idx.index_id = part.index_id INNER JOIN
                         sys.allocation_units AS au ON part.partition_id = au.container_id INNER JOIN
                         sys.filegroups AS fGrp ON idx.data_space_id = fGrp.data_space_id INNER JOIN
                         sys.database_files AS Df ON Df.data_space_id = fGrp.data_space_id
WHERE        (t.is_ms_shipped = 0) AND (idx.object_id > 255)
GROUP BY t.name, s.name, part.rows
ORDER BY [Table's Total Space In GB] DESC

Open in new window

Avatar of Nitin Sontakke
Nitin Sontakke
Flag of India image

Not hugely encouraged by anybody, but here is what you are looking for.
Avatar of databarracks
databarracks

ASKER

Hi Nitin,

Thanks for that, however as you explicitly mentioned if it is not encouraged then I won't bother :(. Thanks for the tip so I can safely conclude that it isn't possible then?
A stored procedure is part of a database, so or you create it in the master database and use a dynamic query where you can change the database by using the USE command or you can have the same stored procedure replicated to every database and then you can call it like this:
EXEC database.dbo.sp_name

Open in new window

SOLUTION
Avatar of Nitin Sontakke
Nitin Sontakke
Flag of India image

Link to home
membership
This content is only available to members.
To access this content, you must be a member of Experts Exchange.
Get Access
Hi Vitor,

I did think of that approach but would you be kind as to elaborate on how I could declare the DB name in the stored proc within the master database?
Ahh I see what you mean Nitin.
Personally, I don't have nothing against creating objects in master database. Especially if they intended to perform generic tasks.
What most of DBAs do, is to creating their private database in all SQL Server instances that they manage so they can use it for this kind of stuffs that will help with their daily tasks.
I did think of that approach but would you be kind as to elaborate on how I could declare the DB name in the stored proc within the master database?
It's only creating a dynamic SQL:
CREATE PROC sp_getFileSizes (@DB_Name AS system)
AS

DECLARE @MySQL VARCHAR(MAX)

SET @MySQL = 'USE ' + @DB_Name + '

SELECT    s.name + ''.'' + t.name AS [Table Name], part.rows AS [Total Rows In Table - Modified], CAST(SUM(DISTINCT au.total_pages) 
                         * 8 / 1024.000 / 1024.000 AS NUMERIC(18, 3)) AS [Tables Total Space In GB]
FROM            sys.tables AS t INNER JOIN
                         sys.schemas AS s ON t.schema_id = s.schema_id INNER JOIN
                         sys.indexes AS idx ON t.object_id = idx.object_id INNER JOIN
                         sys.partitions AS part ON idx.object_id = part.object_id AND idx.index_id = part.index_id INNER JOIN
                         sys.allocation_units AS au ON part.partition_id = au.container_id INNER JOIN
                         sys.filegroups AS fGrp ON idx.data_space_id = fGrp.data_space_id INNER JOIN
                         sys.database_files AS Df ON Df.data_space_id = fGrp.data_space_id
WHERE        (t.is_ms_shipped = 0) AND (idx.object_id > 255)
GROUP BY t.name, s.name, part.rows
ORDER BY [Tables Total Space In GB] DESC'

EXEC @MySQL

Open in new window

Hi Vitor,

Thanks for the stored proc, I am getting an error on the parameter variale @DB_Name has  an invalid type. I am guessing it should be a VARCHAR(256)??
ASKER CERTIFIED SOLUTION
Link to home
membership
This content is only available to members.
To access this content, you must be a member of Experts Exchange.
Get Access
Do you know why I cannot see the sp in my viewer on SSMS?
You might need to refresh the SSMS.
@databarracks, however, from your original post, I gather you were averse to dynamic sql. Not too keen to use it if it is the only option available.
Yes I was, what I was trying to say is that if it was the only option then I would use it..hence 'If I have to then so be it:)'
Again this is something that is only used by 3 people within the organisation nothing public about it
I can't see another way besides the ones I've explained.
I am happy with it and have created the sp in another database as means of 'best practises' because they say not to create new objects in the master db.
Thank you to Vitor and Nitin for helping me out on this issue. Nitin assisted me in providing a useful link and Vitor provided the final solution of which I chose to use in my environment as it was a direct improvement of my original query