Using XP_EXECRESULTSET To Obtain Database Size Information and More

  • Comments posted to this topic are about the content posted at

    -- J.T.

    "I may not always know what I'm talking about, and you may not either."

  • After exchanging questions with J.T. this morning I am including the information as additonal information...

    Since the SID column is the SID of the db creator this column may not be useful in this script for comparison of SID>1. The issue I encountered and discussed was that all my databases, save one, were created by sa so the SID column was 1 for all of them, only the database created under my individual user ID had a SID >1. J.T.'s solution is to replace the comparison with the follwing statement.



     I thank J.T. again for a wonderful article and responsiveness to queries about my results.


    edited to fix tipos...

  • Thanks for taking the time to raise questions, Scott. Glad to help.

    The SID column is the SID of the creator. Scott pointed out that some servers may have databases that were created by sid=1 (sa) and would be excluded by this logic.

    My intent was to prevent the system databases from appearing.

    To see all the databases, including the system databases, remove the sid>1 conditonal.

    Conversely, you can restrain the results by changing the sid>1 phrase to name not in ('msdb','master','tempdb') or whatever databases you want to exclude.

    -- J.T.

    "I may not always know what I'm talking about, and you may not either."

  • You could try replacing the "sid>1" with "dbid>6". I think that works, too.

  • What are the security issues of letting application developers use xp_execresultset?  Is it susceptible to SQL Injection?  And if so, wouldn't it run under the authority of the SQL Server owner?

  • I have user databases numbered beginning at 5, system databases respectively are:

    1- master

    2- tempdb

    3- model

    4- msdb

    5- starts user created dbs


    so maybe dbid >4?

  • We have pub and northwind. That's why I used "dbid>6".

  • You have Pub and Northwind on a production server?

    Typically, they can be removed as they are demo data and really have no place on a production SQL server. Is there a reason you still have them, if this is a production server?

    -- J.T.

    "I may not always know what I'm talking about, and you may not either."

  • Well, on general principle I wouldn't let developers use sp_execresultset as it is undocumented. This means Microsoft may choose to change or remove it, as they did in SQL2005, or not support it in versions where it does exist.

    As for sql injection, I'm no expert but I am of the belief that a well-written interface would prevent that and not SQL iteself. SQL injection, and someone correct me if I am wrong, is an interface vulnerability and not a SQL one, per se.

    I'm pretty sure the sp_execresultset stored proc runs under the authority of the current user. The current user, however, must have rights to query the master database table sysdatabases and each database to sysfiles.

    -- J.T.

    "I may not always know what I'm talking about, and you may not either."

  • I have used NW to do some testing in our prod environments. For example, I wanted to test latency across replicated servers, so I first set up my scripts and jobs, and debugged it using NW. You can't always duplicate a prod environment - at least not with our budget!

  • J.T.

    Wanted to get your opinion on using this method you proposed versus using Dynamic SQL and say sp_executesql or EXECUTE?

    1. does the optimizer handle them diffrently. 

        a. Are they treated as two seperate query plans for the same query or one.

        b. Can XP_EXECRESULTSET take advantage of the caching of multiple calls from various users that sp_executesql can

        c. do you execute a XP_EXECRESULTSET  query with the same SPID as the current connection or is a new one made?


    This is all I can think of off the top of my head anyone have other comparisions to ask let them rip.

  • Make sense. Thanks for the explanation.

    -- J.T.

    "I may not always know what I'm talking about, and you may not either."

  • I'm not sure how the optimizer would handle them. It would be easy enough to come up with a test query and then execute it via xp_execresultset and a dynamic sql method.


    The main advantage of xp_execresultset is that is allows a query to be run in the context of another database without having to switch the current connection to that context. In the article I used FILEPROPERTY which only runs against the current database. I could do this in dynamic SQL (and someone in the forums of Boris Baliner’s article on “Quickly Viewing Available Space” ( did just that) However, the result was quite long and required a lot of context switching.


    I don't know if xp_execresultset can take advantage of caching but I wouldn't use it in any situation where that might be necessary in any case. As I stated, this is an undocumented procedure and Microsoft dropped it in SQL 2005. Using this procedure in an application would be ill-advised. I presented it as a tool for administrators as an alternative to writing long dynamic sql-based scripts.


    Yes, it executes under the same SPID. To determine this add a ,@@SPID to the end of the query in the script, as shown below:


               SET @SQLCmd='SELECT ''SELECT name AS [File],

                      filename as [File Name],

                      CAST(size/128.0 as DECIMAL(10,2)) AS [Size in MB],

                      CAST(FILEPROPERTY(name, ''''SpaceUsed'''')/128.0 as DECIMAL(10,2)) as [Space Used],

                      CAST(size/128.0-(FILEPROPERTY(name, ''''SpaceUsed'''')/128.0) AS DECIMAL(10,2)) AS [Available Space] ,@@SPID

                      FROM SYSFILES'''

    -- J.T.

    "I may not always know what I'm talking about, and you may not either."

  • Two questions:

    1: the "sid > 1" 

       If the "sa" create a product database,the sid in the sysdatabases table will be 'Ox01'.Then the command doesn't work well.


    2:the query listed below

    Declare @DBName sysname

    Declare @SqlCmd Nvarchar(2000)

    Set @DBName = ''

    While @DBName Is not NULL


     Select @DBName = Min(Name) From master..sysdatabases Where sid > 1 And Name > @DBName

     Set @SqlCmd = 'SELECT ''SELECT name AS [File], filename as [File Name]

        , CAST(size/128.0 as DECIMAL(10,2)) AS [Size in MB]

        , CAST(FILEPROPERTY(name, ''''SpaceUsed'''')/128.0 as DECIMAL(10,2)) as [Space Used]

       , CAST(size/128.0-(FILEPROPERTY(name, ''''SpaceUsed'''')/128.0) AS DECIMAL(10,2)) AS [Available Space] FROM SYSFILES'''

     IF @DBName is NULL Break

     Exec Master..xp_execresultset @SqlCmd,@DBName


    It just return "Command(s) completed successfully."



  • Thanks for mentioning that the xp_execresultset is missing from SQL Server 2005.  Yikes!  Before retiring your SQL Server 2000 servers, do this--


    1) Copy proc sp_execresultset from the master database of any server, and create it in the master database of the SQL Server 2005 server.  (The xp_execresultset is unike other xp_ procs; it isn't compiled and reading it shows that it calls sp_execresultset.)


    2) Copy proc xp_execresultset from the master database of any server, and create it in the master database of the SQL Server 2005 server, named sp_execresultset2.  (Doesn't work if you name it xp_ -- and, proc can be named sp_ to be called from databases other than master without "exec master.." -- at least that is true in SQL Server 2000.)


    3) Edit the script to refer to sp_execresultset2 in place of master.dbo.xp_execresultset.

    "Look, those sheep have been shorn."
    data analyst replies, "On the sides that we can see.."

Viewing 15 posts - 1 through 15 (of 22 total)

You must be logged in to reply to this topic. Login to reply