Scott on Writing

Musings on technical writing...

Generating a List of Unattached Databases

SQL Server databases are implemented as physical files with the MDF extension. They can be attached and detached from the running SQL Server instance through Enterprise Manager/Management Studio or via the sp_attach_db and sp_detach_db system stored procedures. Alex B. recently asked a question on the sql_server_maint listserv I'm on about how to list the unattached databases:

Is there a way to find out what db's are unattached on your server?

In short, Alex was interested in having a list of those MDF files on his file system that were not registered with the SQL Server instance. Michael Campbell chimed in:

You won't be able to get a list of unattached dbs. SQL Server will keep track of which files it currently has its hooks into, but once you detach a DB, SQL Server no longer tracks it - it's like it no longer exists as far as SQL Server is concerned. (Which makes perfect sense - as the alternative would be something lame like "SQL Server can't start 'cuz it can't find a file that you detached 3 months ago, and just now deleted...")

Michael suggested trying to move a file to determine whether or not it was attached. If attempting to move the MDF file gave you a locked file error, it was (probably) because it was attached to the SQL Server instance.

Here's a more thorough solution, one that uses a bit of SQL, a bit of command-line goodness, and a little program called Excel. (Excel, believe it or not, has helped out with a sundry of development tasks, such as auto-generating code, turning a list of statements into a series of INSERT statements (to ease porting data from a text file into SQL Server), and so on.) Here's what to do:

  1. Open Excel
  2. Get a list of the attached databases for the SQL Server instance by running the following query in SQL Query Analyzer:

    select [filename] from master.dbo.sysdatabases
  3. Copy the results from the results grid directly into a column in Excel. (I started it at cell A1.)
  4. Next, we need a list of all of the MDF files in the file system. Drop to the command line and run:

    dir /s /b C:\*.MDF > dblist.txt

    This will recurse through all of the directories on C: looking for any file with the extension MDF, and will save the results in a file named dblist.txt.
  5. Open dblist.txt in Notepad, copy its contents, and paste them into Excel. (I started this at cell C1.)
  6. Using the tip discussed at Comparing Two Lists with Conditional Formatting, with a few clicks of the mouse you can name the two list ranges and then apply conditional formatting so that the two lists will be color-coded such to show:

    -- What files are similar between the two lists (these are the attached databases)
    -- What files are attached, but not in the file system (in which case you probably have the MDF files on another drive)
    -- What files are in the file system, but not attached, which was what Alex was after

    The screen shot below shows the attached DBs listed on the left and the MDF files in the file system on the right. Those entries shaded green are those that are found in the list on the right, but not in the list on the left; namely, those database files on my file system that are not attached.
 
Excel to the rescue again!  :-)

posted on Wednesday, April 26, 2006 6:37 PM

Feedback

# re: Generating a List of Unattached Databases 4/27/2006 11:14 AM David L. Penton

How about a SQL Server [Set-Based] solution? Hopefully this comes through OK. Note that I have code in here to handle various versions of SQL Server, and have commented the log file information:

declare
@rc int
, @cmdline nvarchar(4000)
, @hklm nvarchar(4000)
, @regSSvr nvarchar(4000)
, @directory nvarchar(4000)
, @dataDirectory nvarchar(4000)
--, @logDirectory nvarchar(4000)

set nocount on

if object_id('tempdb..#AllDataFiles') IS NOT NULL
drop table #AllDataFiles

create table #AllDataFiles (
"filename" nvarchar(4000)
)

select
@hklm = N'HKEY_LOCAL_MACHINE'
, @regSSvr = N'Software\Microsoft\MSSQLServer\Setup'

EXECUTE @rc = "master"."dbo"."xp_regread" @hklm, @regSSvr
, 'SQLDataRoot', @directory OUTPUT, 'no_output'

if @directory IS NOT NULL
BEGIN
select
@directory = @directory + N'\Data'
, @dataDirectory = @directory
--, @logDirectory = @directory
END ELSE BEGIN
select @regSSvr = N'Software\Microsoft\MSSQLServer\MSSQLServer'
EXECUTE @rc = "master"."dbo"."xp_regread" @hklm, @regSSvr
, 'DefaultData', @dataDirectory OUTPUT, 'no_output'
--EXECUTE @rc = "master"."dbo"."xp_regread" @hklm, @regSSvr
--, 'DefaultLog', @logDirectory OUTPUT, 'no_output'
END

--select @dataDirectory [Data Directory], @logDirectory [Log Directory]

select @cmdline = N'dir /s /b "' + @dataDirectory + '"\*.mdf'

insert into #AllDataFiles
execute "master"."dbo"."xp_cmdshell" @cmdline

select
COALESCE(db.filename, df.filename) [Filename]
, CASE WHEN db.filename IS NOT NULL THEN 'Yes' ELSE '' END [Attached?]
from
master.dbo.sysdatabases db
full outer join
#AllDataFiles df on db.filename = df.filename
where
df.filename is not null

if object_id('tempdb..#AllDataFiles') IS NOT NULL
drop table #AllDataFiles

Title:  
Name:  
Url:
Protected by Clearscreen.SharpHIPEnter the code you see:
Comments   

My Links

Ads Via DevMavens

Archives

Post Categories

 

I am a Microsoft MVP for ASP.NET.
I am an ASPInsider.
<March 2010>
SMTWTFS
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910

Comment Stats

DayTotal% of Total
Sunday 2056.8%
Monday 42514.1%
Tuesday 51917.2%
Wednesday 55618.4%
Thursday 58019.2%
Friday 54718.1%
Saturday 1886.2%
Total 3020100.0%

Hour1Total% of Total
12:00 AM 782.6%
1:00 AM 812.7%
2:00 AM 682.3%
3:00 AM 822.7%
4:00 AM 692.3%
5:00 AM 1264.2%
6:00 AM 1193.9%
7:00 AM 1816.0%
8:00 AM 1926.4%
9:00 AM 1585.2%
10:00 AM 1886.2%
11:00 AM 1936.4%
12:00 PM 2016.7%
1:00 PM 1846.1%
2:00 PM 1695.6%
3:00 PM 1354.5%
4:00 PM 1153.8%
5:00 PM 1073.5%
6:00 PM 1013.3%
7:00 PM 1073.5%
8:00 PM 923.0%
9:00 PM 882.9%
10:00 PM 913.0%
11:00 PM 953.1%
Total 3020100.0%

Comments by Blog Entry Date/Time

Day Entry MadeAvg.Total
Sunday 5.00160
Monday 4.80384
Tuesday 4.04477
Wednesday 7.39680
Thursday 6.26676
Friday 5.07466
Saturday 4.78177
Total 5.403020

Hour1 Entry MadeAvg.Total
12:00 AM 5.2937
1:00 AM 1.002
5:00 AM 0.000
7:00 AM 3.8550
8:00 AM 3.72134
9:00 AM 6.06297
10:00 AM 5.63276
11:00 AM 4.22194
12:00 PM 6.16351
1:00 PM 3.09133
2:00 PM 4.89230
3:00 PM 7.67322
4:00 PM 4.00108
5:00 PM 6.07170
6:00 PM 4.64116
7:00 PM 8.95188
8:00 PM 8.63164
9:00 PM 5.00115
10:00 PM 6.31101
11:00 PM 4.5732
Total 5.403020

Learn More About Comment Stats
1 - All times GMT -8...


Blog Stats

Favorite Web Sites

My Books

My MSDN Articles