Technical Article

Script to Rename Many .ndf Physical Files

,

At my job, I have a large database that's partitioned and has about 115 separate .ndf files. Recently, when I restored it on our DR site, I didn't do it correctly and so instead of .ndf files named like this:

MYDATABASE_Services_2008_01.ndf
MYDATABASE_Services_2008_02.ndf
MYDATABASE_Services_2008_03.ndf
...
...
MYDATABASE_Services_2010_02.ndf
MYDATABASE_Services_2010_03.ndf
MYDATABASE_Events_2008_01.ndf
MYDATABASE_Events_2008_02.ndf
...
...
MYDATABASE_Events_2008_01.ndf
MYDATABASE_Events_2008_02.ndf
MYDATABASE_Events_2008_03.ndf

... and so on.

What happened was that the files wound up named like this:

MY_DATABASE_16.ndf
MY_DATABASE_17.ndf
MY_DATABASE_18.ndf
MY_DATABASE_19.ndf
...
...
MY_DATABASE_33.ndf
MY_DATABASE_34.ndf
MY_DATABASE_35.ndf
...
...
MY_DATABASE_105.ndf
MY_DATABASE_106.ndf
MY_DATABASE_107.ndf

In addition to this, many of the files are on different drives. For example, the files for Services are on drive I: while the files for Events are on drive F:

Now, this database is well over 300GB in size and even with SQL 2008 backup compression the .BAK file is still 43GB. I was not looking forward to copying it across the country again to redo the restore so I could get the filenames right.

Forturnately, I am consistent in my naming of the filegroups, though. They are named thusly:

FG_Services_2008_01
FG_Services_2008_02
FG_Services_2008_03
...
...
FG_Services_2010_02
FG_Services_2010_03
FG_Events_2008_01
FG_Events_2008_02
...
...
FG_Events_2008_01
FG_Events_2008_02.ndf
FG_Events_2008_03.ndf

 

So I created a script that will take the filegroup names and rename the files for you. What it does is create 2 scripts you can run. The first one is a set of ALTER DATABASE commands to rename how the files will appear in the system tables. The second thing it spits out is a set of DOS commands you can run from a batch file to rename the physical files.

What you wind up with after all is said and done, are .ndf files named like this:

MYDATABASE_Services_2008_01.ndf
MYDATABASE_Services_2008_02.ndf
MYDATABASE_Services_2008_03.ndf

 

/**********************************************************************

SCRIPT NAME: Rename FileNames 02.sql

PURPOSE: Rename multiple filenames on the database. 

Change History: 
 03/19/2010 4:15 PM - gmilner: Created. 

**********************************************************************/
SET NOCOUNT ON

DECLARE @DATABASE_NAME VARCHAR(64) 
SET @DATABASE_NAME = 'REC_DW_Automation' 

PRINT '----------------------------------------------------------------------------'
PRINT ' RUN THESE IN A SEPARATE SSMS WINDOW' 
PRINT '----------------------------------------------------------------------------'

-- create the ALTER DATABASE files to change the file names in the sys

/* 
 NOTE: "This will only alter SQL Server's internal definition of the filename, 
 it will not change the actual name of the file in the OS file system." 
*/ 
SELECT 
 'ALTER DATABASE '+ @DATABASE_NAME + CHAR(13) + 
 ' MODIFY FILE (NAME = ' + [name] + ', ' + CHAR(13) + ' FILENAME = ''' + 
 /* the line below strips the path only from the whole (old) filename
 so the new files are mapped to the same place as the old */ SUBSTRING(physical_name,1,PATINDEX('%'+REVERSE(SUBSTRING(REVERSE(physical_name),1,CHARINDEX('\',REVERSE(physical_name))-1))+'%' ,physical_name)-1) + 
 @DATABASE_NAME + '_' + 
 REPLACE([name],'FG_','') + '.ndf'');' /* NOTE: all filegroups start with 'FG' but files should not. */ + CHAR(13) /* put in a blank line between each command */FROM sys.master_files
WHERE database_id = DB_ID(@DATABASE_NAME)
    AND physical_name LIKE '%.ndf';
    

-- Now we need DOS BATCH commandS to rename the actual files.
-- We run them as Administrator on the box itself

PRINT '----------------------------------------------------------------------------'
PRINT ' NOW, DETACH THE DATABASE AND THEN ... ' 
PRINT ' RUN THESE IN A DOS BATCH AS ADMINISTRATOR' 
PRINT '----------------------------------------------------------------------------'


SELECT 'rename "' + physical_name + 
 '" "' + 
 @DATABASE_NAME + '_' + 
 REPLACE([name],'FG_','') + '.ndf";' /* NOTE: all filegroups start with 'FG' but files should not. */

FROM sys.master_files
WHERE database_id = DB_ID(@DATABASE_NAME)
    AND physical_name LIKE '%.ndf';


PRINT '----------------------------------------------------------------------------'
PRINT ' AFTER THE DOS BATCH IS RUN, REATTACH THE DATABASE' 
PRINT '----------------------------------------------------------------------------'


SET NOCOUNT OFF    

Rate

5 (1)

You rated this post out of 5. Change rating

Share

Share

Rate

5 (1)

You rated this post out of 5. Change rating