Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help converting a Stored Procedure (2000 to 2005)

Status
Not open for further replies.

jpotucek

Technical User
Jan 26, 2005
144
US
I have been using this stored procedure to recover databases (from a Full Backup) on my SQL Server 2000 Instances for quite awhile now:

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_CSS_RestoreDir]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_CSS_RestoreDir]
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO


/***************************************************************************************/
-- Procedure Name: sp_CSS_RestoreDir
-- Purpose: Restore one or many database backups from a single directory. This script reads all
-- database backups that are found in the @restoreFromDir parameter.
-- Any database backup that matches the form %_db_% will be restored to
-- the file locations specified in the RestoreTo... parameter(s). The database
-- will be restored to a database name that is based on the database backup
-- file name. For example Insurance_db_200305212302.BAK will be restored to
-- a database named Insurance. The characters preceeding the '_db_' text determines
-- the name.
--
-- Input Parameters: @restoreFromDir - The directory where the database backups are located
-- @restoreToDataDir - The directory where the data files (i.e. MDF) will be restored to
-- @restoreToLogDir - The directory where the log files (i.e. LDF) will be restored to. If
-- this parameter is not provided then the log files are restored to @restoreToDataDir.
-- @MatchFileList - set to 'Y' to restore to same directory structure contained in the backup,
-- also allows for secondary data files 'ndf' to to be in a different dir than mdf files
-- @DBName - restore just this one database - selects the latest bak file
--
-- Output Parameters: None
--
-- Return Values:
--
--
-- Sample Execution: exec sp_CSS_RestoreDir 'C:\sqldb\sql_backup', 'C:\sqldb\sql_data', 'C:\sqldb\sql_log'
--
-- Alternate Execution: exec sp_CSS_RestoreDir 'C:\sqldb\sql_backup', @MatchFileList = 'Y'
--

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

CREATE proc sp_CSS_RestoreDir
@restoreFromDir varchar(255),
@restoreToDataDir varchar(255)= null,
@restoreToLogDir varchar(255) = null,
@MatchFileList char(1) = 'N',
@OneDBName varchar(255) = null
as

--If a directory for the Log file is not supplied then use the data directory
If @restoreToLogDir is null
set @restoreToLogDir = @restoreToDataDir

set nocount on
SET quoted_identifier on

declare @filename varchar(255),
@cmd varchar(500),
@cmd2 varchar(500),
@DataName varchar (255),
@LogName varchar (255),
@LogicalName varchar(255),
@PhysicalName varchar(255),
@Type varchar(20),
@FileGroupName varchar(255),
@Size varchar(20),
@MaxSize varchar(20),
@restoreToDir varchar(255),
@searchName varchar(255),
@DBName varchar(255),
@PhysicalFileName varchar(255)

create table #dirList (filename varchar(100))
create table #filelist (LogicalName varchar(255), PhysicalName varchar(255), Type varchar(20), FileGroupName varchar(255), Size varchar(20), MaxSize varchar(20) )

--Get the list of database backups that are in the restoreFromDir directory
if @OneDBName is null
select @cmd = 'dir /b /on "' +@restoreFromDir+ '"'
else
select @cmd = 'dir /b /o-d /o-g "' +@restoreFromDir+ '"'

insert #dirList exec master..xp_cmdshell @cmd

select * from #dirList where filename like '%_db_%' --order by filename

if @OneDBName is null
declare BakFile_csr cursor for
select * from #dirList where filename like '%_db_%bak' order by filename
else
begin -- single db, don't order by filename, take default latest date /o-d parm in dir command above
select @searchName = @OneDBName + '_db_%bak'
declare BakFile_csr cursor for
select top 1 * from #dirList where filename like @searchName
end

open BakFile_csr
fetch BakFile_csr into @filename

while @@fetch_status = 0
begin
select @cmd = "RESTORE FILELISTONLY FROM disk = '" + @restoreFromDir + "\" + @filename + "'"

insert #filelist exec ( @cmd )

if @OneDBName is null
select @dbName = left(@filename,datalength(@filename) - patindex('%_bd_%',reverse(@filename))-3)
else
select @dbName = @OneDBName

select @cmd = "RESTORE DATABASE " + @dbName +
" FROM DISK = '" + @restoreFromDir + "\" + @filename + "' WITH "

PRINT ''
PRINT 'RESTORING DATABASE ' + @dbName

declare DataFileCursor cursor for
select LogicalName, PhysicalName, Type, FileGroupName, Size, MaxSize
from #filelist

open DataFileCursor
fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

while @@fetch_status = 0
begin
if @MatchFileList != 'Y'
begin -- RESTORE with MOVE option
select @PhysicalFileName = reverse(substring(reverse(rtrim(@PhysicalName)),1,patindex('%\%',reverse(rtrim(@PhysicalName)))-1 ))

if @Type = 'L'
select @restoreToDir = @restoreToLogDir
else
select @restoreToDir = @restoreToDataDir

select @cmd = @cmd +
" MOVE '" + @LogicalName + "' TO '" + @restoreToDir + "\" + @PhysicalFileName + "', "
end
else
begin -- Match the file list, attempt to create any missing directory
select @restoreToDir = left(@PhysicalName,datalength(@PhysicalName) - patindex('%\%',reverse(@PhysicalName)) )
select @cmd2 = "if not exist " +@restoreToDir+ " md " +@restoreToDir
exec master..xp_cmdshell @cmd2
end

fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

end -- DataFileCursor loop

close DataFileCursor
deallocate DataFileCursor

select @cmd = @cmd + ' REPLACE, STATS = 10'
--select @cmd 'command'
EXEC (@CMD)

truncate table #filelist

fetch BakFile_csr into @filename

end -- BakFile_csr loop

close BakFile_csr
deallocate BakFile_csr

drop table #dirList

return

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

I need to now use it on my SQL Server 2005 Instances. I modified it to reflect the fact that 2000 backup files look like this: pubs_db_200801191728.BAK
where as 2005 backup files look like this: pubs_Backup_200801191728.BAK

AND I enabled CMD Shell on my 2005 Instance

the New SP looks like this:

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_CSS_RestoreDir]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_CSS_RestoreDir]
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO


/***************************************************************************************/
-- Procedure Name: sp_CSS_RestoreDir
-- Purpose: Restore one or many database backups from a single directory. This script reads all
-- database backups that are found in the @restoreFromDir parameter.
-- Any database backup that matches the form %_Backup_% will be restored to
-- the file locations specified in the RestoreTo... parameter(s). The database
-- will be restored to a database name that is based on the database backup
-- file name. For example Insurance_Backup_200305212302.BAK will be restored to
-- a database named Insurance. The characters preceeding the '_Backup_' text determines
-- the name.
--
-- Input Parameters: @restoreFromDir - The directory where the database backups are located
-- @restoreToDataDir - The directory where the data files (i.e. MDF) will be restored to
-- @restoreToLogDir - The directory where the log files (i.e. LDF) will be restored to. If
-- this parameter is not provided then the log files are restored to @restoreToDataDir.
-- @MatchFileList - set to 'Y' to restore to same directory structure contained in the backup,
-- also allows for secondary data files 'ndf' to to be in a different dir than mdf files
-- @DBName - restore just this one database - selects the latest bak file
--
-- Output Parameters: None
--
-- Return Values:
--
--
-- Sample Execution: exec sp_CSS_RestoreDir 'C:\sqldb\sql_backup', 'C:\sqldb\sql_data', 'C:\sqldb\sql_log'
--
-- Alternate Execution: exec sp_CSS_RestoreDir 'C:\sqldb\sql_backup', @MatchFileList = 'Y'
--

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

CREATE proc sp_CSS_RestoreDir
@restoreFromDir varchar(255),
@restoreToDataDir varchar(255)= null,
@restoreToLogDir varchar(255) = null,
@MatchFileList char(1) = 'N',
@OneDBName varchar(255) = null
as

--If a directory for the Log file is not supplied then use the data directory
If @restoreToLogDir is null
set @restoreToLogDir = @restoreToDataDir

set nocount on
SET quoted_identifier on

declare @filename varchar(255),
@cmd varchar(500),
@cmd2 varchar(500),
@DataName varchar (255),
@LogName varchar (255),
@LogicalName varchar(255),
@PhysicalName varchar(255),
@Type varchar(20),
@FileGroupName varchar(255),
@Size varchar(20),
@MaxSize varchar(20),
@restoreToDir varchar(255),
@searchName varchar(255),
@DBName varchar(255),
@PhysicalFileName varchar(255)

create table #dirList (filename varchar(100))
create table #filelist (LogicalName varchar(255), PhysicalName varchar(255), Type varchar(20), FileGroupName varchar(255), Size varchar(20), MaxSize varchar(20) )

--Get the list of database backups that are in the restoreFromDir directory
if @OneDBName is null
select @cmd = 'dir /b /on "' +@restoreFromDir+ '"'
else
select @cmd = 'dir /b /o-d /o-g "' +@restoreFromDir+ '"'

insert #dirList exec master..xp_cmdshell @cmd

select * from #dirList where filename like '%_Backup_%' --order by filename

if @OneDBName is null
declare BakFile_csr cursor for
select * from #dirList where filename like '%_Backup_%bak' order by filename
else
begin -- single db, don't order by filename, take default latest date /o-d parm in dir command above
select @searchName = @OneDBName + '_Backup_%bak'
declare BakFile_csr cursor for
select top 1 * from #dirList where filename like @searchName
end

open BakFile_csr
fetch BakFile_csr into @filename

while @@fetch_status = 0
begin
select @cmd = "RESTORE FILELISTONLY FROM disk = '" + @restoreFromDir + "\" + @filename + "'"

insert #filelist exec ( @cmd )

if @OneDBName is null
select @dbName = left(@filename,datalength(@filename) - patindex('%_bd_%',reverse(@filename))-3)
else
select @dbName = @OneDBName

select @cmd = "RESTORE DATABASE " + @dbName +
" FROM DISK = '" + @restoreFromDir + "\" + @filename + "' WITH "

PRINT ''
PRINT 'RESTORING DATABASE ' + @dbName

declare DataFileCursor cursor for
select LogicalName, PhysicalName, Type, FileGroupName, Size, MaxSize
from #filelist

open DataFileCursor
fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

while @@fetch_status = 0
begin
if @MatchFileList != 'Y'
begin -- RESTORE with MOVE option
select @PhysicalFileName = reverse(substring(reverse(rtrim(@PhysicalName)),1,patindex('%\%',reverse(rtrim(@PhysicalName)))-1 ))

if @Type = 'L'
select @restoreToDir = @restoreToLogDir
else
select @restoreToDir = @restoreToDataDir

select @cmd = @cmd +
" MOVE '" + @LogicalName + "' TO '" + @restoreToDir + "\" + @PhysicalFileName + "', "
end
else
begin -- Match the file list, attempt to create any missing directory
select @restoreToDir = left(@PhysicalName,datalength(@PhysicalName) - patindex('%\%',reverse(@PhysicalName)) )
select @cmd2 = "if not exist " +@restoreToDir+ " md " +@restoreToDir
exec master..xp_cmdshell @cmd2
end

fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

end -- DataFileCursor loop

close DataFileCursor
deallocate DataFileCursor

select @cmd = @cmd + ' REPLACE, STATS = 10'
--select @cmd 'command'
EXEC (@CMD)

truncate table #filelist

fetch BakFile_csr into @filename

end -- BakFile_csr loop

close BakFile_csr
deallocate BakFile_csr

drop table #dirList

return

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

When I execute the new stored procedure on my 2005 Instance , I get this errror:

Msg 213, Level 16, State 7, Line 1
Insert Error: Column name or number of supplied values does not match table definition.
Msg 3013, Level 16, State 1, Line 1
RESTORE FILELIST is terminating abnormally.

RESTORING DATABASE OFAC_backup_200807230245.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '.'.
Msg 319, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'with'. If this statement is a common table expression or an xmlnamespaces clause, the previous statement must be terminated with a semicolon.

CAN ANYONE HELP?
 
I would guess that restoring filelistonly returns more columns, now. So one of the temp tables will have to be modified:
Code:
select @cmd = "RESTORE FILELISTONLY FROM disk = '" + @restoreFromDir + "\" + @filename + "'"

       insert #filelist exec ( @cmd )

With that table being empty, the rest of the errors probably follow.
 
The list of columns returned by RESTORE FILELISTONLY can be found in BOL here:

ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/tsqlref9/html/0b4b4d11-eb9d-4f3e-9629-6c79cec7a81a.htm
 
Well for starters, the RESTORE FILELISTONLY returns more column that you have set for the temp table that is capturing it.

You are missing column like FileID, CreateLSN, DropLSN, UniqueID and about 10 others.

Take a look at Books Online under "RESTORE FILELISTONLY".

You need to have a placeholder for every field within your temp table even if you are not going to use it.

Thanks

J. Kusch
 
I guess I'm confused as to why it works in 2000 but not in 2005
 
Thank you!!! I modified the Stored Procedure to include the missing columns in the Temp Table..

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_CSS_RestoreDir]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_CSS_RestoreDir]
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO


/***************************************************************************************/
-- Procedure Name: sp_CSS_RestoreDir
-- Purpose: Restore one or many database backups from a single directory. This script reads all
-- database backups that are found in the @restoreFromDir parameter.
-- Any database backup that matches the form %_Backup_% will be restored to
-- the file locations specified in the RestoreTo... parameter(s). The database
-- will be restored to a database name that is based on the database backup
-- file name. For example Insurance_Backup_200305212302.BAK will be restored to
-- a database named Insurance. The characters preceeding the '_Backup_' text determines
-- the name.
--
-- Input Parameters: @restoreFromDir - The directory where the database backups are located
-- @restoreToDataDir - The directory where the data files (i.e. MDF) will be restored to
-- @restoreToLogDir - The directory where the log files (i.e. LDF) will be restored to. If
-- this parameter is not provided then the log files are restored to @restoreToDataDir.
-- @MatchFileList - set to 'Y' to restore to same directory structure contained in the backup,
-- also allows for secondary data files 'ndf' to to be in a different dir than mdf files
-- @DBName - restore just this one database - selects the latest bak file
--
-- Output Parameters: None
--
-- Return Values:
--
--
-- Sample Execution: exec sp_CSS_RestoreDir 'C:\sqldb\sql_backup', 'C:\sqldb\sql_data', 'C:\sqldb\sql_log'
--
-- Alternate Execution: exec sp_CSS_RestoreDir 'C:\sqldb\sql_backup', @MatchFileList = 'Y'
--

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

CREATE proc sp_CSS_RestoreDir
@restoreFromDir varchar(255),
@restoreToDataDir varchar(255)= null,
@restoreToLogDir varchar(255) = null,
@MatchFileList char(1) = 'N',
@OneDBName varchar(255) = null
as

--If a directory for the Log file is not supplied then use the data directory
If @restoreToLogDir is null
set @restoreToLogDir = @restoreToDataDir

set nocount on
SET quoted_identifier on

declare @filename varchar(255),
@cmd varchar(500),
@cmd2 varchar(500),
@DataName varchar (255),
@LogName varchar (255),
@LogicalName varchar(255),
@PhysicalName varchar(255),
@Type varchar(20),
@FileGroupName varchar(255),
@Size varchar(20),
@MaxSize varchar(20),
@restoreToDir varchar(255),
@searchName varchar(255),
@DBName varchar(255),
@PhysicalFileName varchar(255)

create table #dirList (filename varchar(100))
create table #filelist (LogicalName nvarchar(128), PhysicalName nvarchar(260), Type char(1), FileGroupName nvarchar(128), Size numeric(20,0), MaxSize numeric(20,0), FilID bigint, CreateLSN numeric(25,0), DropLSN numeric(25,0), UniqueID uniqueidentifier, ReadOnlyLSN numeric(25,0),
ReadWriteLSN numeric(25,0), BackupSizeInBytes bigint, SourceBlockSize int, FileGroupID int, LogGroupGUID uniqueidentifier, DifferentialBaseLSN numeric(25,0), DifferentialBaseGUID uniqueidentifier, IsReadOnly bit, IsPresent bit)

--Get the list of database backups that are in the restoreFromDir directory
if @OneDBName is null
select @cmd = 'dir /b /on "' +@restoreFromDir+ '"'
else
select @cmd = 'dir /b /o-d /o-g "' +@restoreFromDir+ '"'

insert #dirList exec master..xp_cmdshell @cmd

select * from #dirList where filename like '%_Backup_%' --order by filename

if @OneDBName is null
declare BakFile_csr cursor for
select * from #dirList where filename like '%_Backup_%bak' order by filename
else
begin -- single db, don't order by filename, take default latest date /o-d parm in dir command above
select @searchName = @OneDBName + '_Backup_%bak'
declare BakFile_csr cursor for
select top 1 * from #dirList where filename like @searchName
end

open BakFile_csr
fetch BakFile_csr into @filename

while @@fetch_status = 0
begin
select @cmd = "RESTORE FILELISTONLY FROM disk = '" + @restoreFromDir + "\" + @filename + "'"

insert #filelist exec ( @cmd )

if @OneDBName is null
select @dbName = left(@filename,datalength(@filename) - patindex('%_bd_%',reverse(@filename))-3)
else
select @dbName = @OneDBName

select @cmd = "RESTORE DATABASE " + @dbName +
" FROM DISK = '" + @restoreFromDir + "\" + @filename + "' WITH "

PRINT ''
PRINT 'RESTORING DATABASE ' + @dbName

declare DataFileCursor cursor for
select LogicalName, PhysicalName, Type, FileGroupName, Size, MaxSize
from #filelist

open DataFileCursor
fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

while @@fetch_status = 0
begin
if @MatchFileList != 'Y'
begin -- RESTORE with MOVE option
select @PhysicalFileName = reverse(substring(reverse(rtrim(@PhysicalName)),1,patindex('%\%',reverse(rtrim(@PhysicalName)))-1 ))

if @Type = 'L'
select @restoreToDir = @restoreToLogDir
else
select @restoreToDir = @restoreToDataDir

select @cmd = @cmd +
" MOVE '" + @LogicalName + "' TO '" + @restoreToDir + "\" + @PhysicalFileName + "', "
end
else
begin -- Match the file list, attempt to create any missing directory
select @restoreToDir = left(@PhysicalName,datalength(@PhysicalName) - patindex('%\%',reverse(@PhysicalName)) )
select @cmd2 = "if not exist " +@restoreToDir+ " md " +@restoreToDir
exec master..xp_cmdshell @cmd2
end

fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

end -- DataFileCursor loop

close DataFileCursor
deallocate DataFileCursor

select @cmd = @cmd + ' REPLACE, STATS = 10'
--select @cmd 'command'
EXEC (@CMD)

truncate table #filelist

fetch BakFile_csr into @filename

end -- BakFile_csr loop

close BakFile_csr
deallocate BakFile_csr

drop table #dirList

return

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

NOW WHEN I EXECUTE IT I GET THIS:

RESTORING DATABASE OFAC_backup_200807230245.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '.'.
Msg 319, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'with'. If this statement is a common table expression or an xmlnamespaces clause, the previous statement must be terminated with a semicolon.
 
In your SP, put a PRINT statement with the restore command that is being executed.

As in ..

PRINT @cmd

Lets see what the command being built looks like.

There obviously is a period in the wrong place or something like that

Thanks

J. Kusch
 
Hmmm,
I changed the double quotes to singles, and ran it - looks Ok to me - run this and see if it works for you:





SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO


/***************************************************************************************/
-- Procedure Name: sp_CSS_RestoreDir
-- Purpose: Restore one or many database backups from a single directory. This script reads all
-- database backups that are found in the @restoreFromDir parameter.
-- Any database backup that matches the form %_Backup_% will be restored to
-- the file locations specified in the RestoreTo... parameter(s). The database
-- will be restored to a database name that is based on the database backup
-- file name. For example Insurance_Backup_200305212302.BAK will be restored to
-- a database named Insurance. The characters preceeding the '_Backup_' text determines
-- the name.
--
-- Input Parameters: @restoreFromDir - The directory where the database backups are located
-- @restoreToDataDir - The directory where the data files (i.e. MDF) will be restored to
-- @restoreToLogDir - The directory where the log files (i.e. LDF) will be restored to. If
-- this parameter is not provided then the log files are restored to @restoreToDataDir.
-- @MatchFileList - set to 'Y' to restore to same directory structure contained in the backup,
-- also allows for secondary data files 'ndf' to to be in a different dir than mdf files
-- @DBName - restore just this one database - selects the latest bak file
--
-- Output Parameters: None
--
-- Return Values:
--
--
-- Sample Execution: exec sp_CSS_RestoreDir 'C:\sqldb\sql_backup', 'C:\sqldb\sql_data', 'C:\sqldb\sql_log'
--
-- Alternate Execution: exec sp_CSS_RestoreDir 'C:\sqldb\sql_backup', @MatchFileList = 'Y'
--

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

CREATE proc sp_CSS_RestoreDir
@restoreFromDir varchar(255),
@restoreToDataDir varchar(255)= null,
@restoreToLogDir varchar(255) = null,
@MatchFileList char(1) = 'N',
@OneDBName varchar(255) = null




as

--If a directory for the Log file is not supplied then use the data directory
If @restoreToLogDir is null
set @restoreToLogDir = @restoreToDataDir

set nocount on
SET quoted_identifier on

declare @filename varchar(255),
@cmd varchar(500),
@cmd2 varchar(500),
@DataName varchar (255),
@LogName varchar (255),
@LogicalName varchar(255),
@PhysicalName varchar(255),
@Type varchar(20),
@FileGroupName varchar(255),
@Size varchar(20),
@MaxSize varchar(20),
@restoreToDir varchar(255),
@searchName varchar(255),
@DBName varchar(255),
@PhysicalFileName varchar(255)

create table #dirList (filename varchar(100))
create table #filelist (LogicalName nvarchar(128), PhysicalName nvarchar(260), Type char(1), FileGroupName nvarchar(128), Size numeric(20,0), MaxSize numeric(20,0), FilID bigint, CreateLSN numeric(25,0), DropLSN numeric(25,0), UniqueID uniqueidentifier, ReadOnlyLSN numeric(25,0),
ReadWriteLSN numeric(25,0), BackupSizeInBytes bigint, SourceBlockSize int, FileGroupID int, LogGroupGUID uniqueidentifier, DifferentialBaseLSN numeric(25,0), DifferentialBaseGUID uniqueidentifier, IsReadOnly bit, IsPresent bit)

--Get the list of database backups that are in the restoreFromDir directory
if @OneDBName is null
select @cmd = 'dir /b /on "' +@restoreFromDir+ '"'
else
select @cmd = 'dir /b /o-d /o-g "' +@restoreFromDir+ '"'

insert #dirList exec master..xp_cmdshell @cmd

select * from #dirList where filename like '%_Backup_%' --order by filename

if @OneDBName is null
declare BakFile_csr cursor for
select * from #dirList where filename like '%_Backup_%bak' order by filename
else
begin -- single db, don't order by filename, take default latest date /o-d parm in dir command above
select @searchName = @OneDBName + '_Backup_%bak'
declare BakFile_csr cursor for
select top 1 * from #dirList where filename like @searchName
end

open BakFile_csr
fetch BakFile_csr into @filename

while @@fetch_status = 0
begin
select @cmd = 'RESTORE FILELISTONLY FROM disk = ' + @restoreFromDir + '\' + @filename + ''''

insert #filelist exec ( @cmd )

if @OneDBName is null
select @dbName = left(@filename,datalength(@filename) - patindex('%_bd_%',reverse(@filename))-3)
else
select @dbName = @OneDBName

select @cmd = 'RESTORE DATABASE ' + @dbName +
'FROM DISK = ' + @restoreFromDir + '\' + @filename + ' WITH '

PRINT ''
PRINT 'RESTORING DATABASE ' + @dbName

declare DataFileCursor cursor for
select LogicalName, PhysicalName, Type, FileGroupName, Size, MaxSize
from #filelist

open DataFileCursor
fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

while @@fetch_status = 0
begin
if @MatchFileList != 'Y'
begin -- RESTORE with MOVE option
select @PhysicalFileName = reverse(substring(reverse(rtrim(@PhysicalName)),1,patindex('%\%',reverse(rtrim(@PhysicalName)))-1 ))

if @Type = 'L'
select @restoreToDir = @restoreToLogDir
else
select @restoreToDir = @restoreToDataDir

select @cmd = @cmd +
' MOVE ' + @LogicalName + ' TO ' + @restoreToDir + '\' + @PhysicalFileName + ', '
end
else
begin -- Match the file list, attempt to create any missing directory
select @restoreToDir = left(@PhysicalName,datalength(@PhysicalName) - patindex('%\%',reverse(@PhysicalName)) )
select @cmd2 = 'if not exist ' +@restoreToDir+ ' md ' +@restoreToDir
exec master..xp_cmdshell @cmd2
end

fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

end -- DataFileCursor loop

close DataFileCursor
deallocate DataFileCursor

select @cmd = @cmd + ' REPLACE, STATS = 10'
--select @cmd 'command'
EXEC (@CMD)

truncate table #filelist

fetch BakFile_csr into @filename

end -- BakFile_csr loop

close BakFile_csr
deallocate BakFile_csr

drop table #dirList

return

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO










 

Thank you for your help with this!!!!!!!!

I dropped my SP and created with the code you posted (see below).

I placed a .bak file in 'e:\Backup' and then executed like this:

exec Sp_CSS_RestoreDir 'e:\Backup', 'E:\MSSQL\DR\DATAFILES', 'F:\MSSQL\DR\LOGFILES'

I did not get any errors but It also did not restore my .bak

ANY IDEAS????

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_CSS_RestoreDir]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_CSS_RestoreDir]
GO



SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO



CREATE proc sp_CSS_RestoreDir
@restoreFromDir varchar(255),
@restoreToDataDir varchar(255)= null,
@restoreToLogDir varchar(255) = null,
@MatchFileList char(1) = 'N',
@OneDBName varchar(255) = null




as

--If a directory for the Log file is not supplied then use the data directory
If @restoreToLogDir is null
set @restoreToLogDir = @restoreToDataDir

set nocount on
SET quoted_identifier on

declare @filename varchar(255),
@cmd varchar(500),
@cmd2 varchar(500),
@DataName varchar (255),
@LogName varchar (255),
@LogicalName varchar(255),
@PhysicalName varchar(255),
@Type varchar(20),
@FileGroupName varchar(255),
@Size varchar(20),
@MaxSize varchar(20),
@restoreToDir varchar(255),
@searchName varchar(255),
@DBName varchar(255),
@PhysicalFileName varchar(255)

create table #dirList (filename varchar(100))
create table #filelist (LogicalName nvarchar(128), PhysicalName nvarchar(260), Type char(1), FileGroupName nvarchar(128), Size numeric(20,0), MaxSize numeric(20,0), FilID bigint, CreateLSN numeric(25,0), DropLSN numeric(25,0), UniqueID uniqueidentifier, ReadOnlyLSN numeric(25,0),
ReadWriteLSN numeric(25,0), BackupSizeInBytes bigint, SourceBlockSize int, FileGroupID int, LogGroupGUID uniqueidentifier, DifferentialBaseLSN numeric(25,0), DifferentialBaseGUID uniqueidentifier, IsReadOnly bit, IsPresent bit)

--Get the list of database backups that are in the restoreFromDir directory
if @OneDBName is null
select @cmd = 'dir /b /on "' +@restoreFromDir+ '"'
else
select @cmd = 'dir /b /o-d /o-g "' +@restoreFromDir+ '"'

insert #dirList exec master..xp_cmdshell @cmd

select * from #dirList where filename like '%_Backup_%' --order by filename

if @OneDBName is null
declare BakFile_csr cursor for
select * from #dirList where filename like '%_Backup_%bak' order by filename
else
begin -- single db, don't order by filename, take default latest date /o-d parm in dir command above
select @searchName = @OneDBName + '_Backup_%bak'
declare BakFile_csr cursor for
select top 1 * from #dirList where filename like @searchName
end

open BakFile_csr
fetch BakFile_csr into @filename

while @@fetch_status = 0
begin
select @cmd = 'RESTORE FILELISTONLY FROM disk = ' + @restoreFromDir + '\' + @filename + ''''

insert #filelist exec ( @cmd )

if @OneDBName is null
select @dbName = left(@filename,datalength(@filename) - patindex('%_bd_%',reverse(@filename))-3)
else
select @dbName = @OneDBName

select @cmd = 'RESTORE DATABASE ' + @dbName +
'FROM DISK = ' + @restoreFromDir + '\' + @filename + ' WITH '

PRINT ''
PRINT 'RESTORING DATABASE ' + @dbName

declare DataFileCursor cursor for
select LogicalName, PhysicalName, Type, FileGroupName, Size, MaxSize
from #filelist

open DataFileCursor
fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

while @@fetch_status = 0
begin
if @MatchFileList != 'Y'
begin -- RESTORE with MOVE option
select @PhysicalFileName = reverse(substring(reverse(rtrim(@PhysicalName)),1,patindex('%\%',reverse(rtrim(@PhysicalName)))-1 ))

if @Type = 'L'
select @restoreToDir = @restoreToLogDir
else
select @restoreToDir = @restoreToDataDir

select @cmd = @cmd +
' MOVE ' + @LogicalName + ' TO ' + @restoreToDir + '\' + @PhysicalFileName + ', '
end
else
begin -- Match the file list, attempt to create any missing directory
select @restoreToDir = left(@PhysicalName,datalength(@PhysicalName) - patindex('%\%',reverse(@PhysicalName)) )
select @cmd2 = 'if not exist ' +@restoreToDir+ ' md ' +@restoreToDir
exec master..xp_cmdshell @cmd2
end

fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

end -- DataFileCursor loop

close DataFileCursor
deallocate DataFileCursor

select @cmd = @cmd + ' REPLACE, STATS = 10'
--select @cmd 'command'
EXEC (@CMD)

truncate table #filelist

fetch BakFile_csr into @filename

end -- BakFile_csr loop

close BakFile_csr
deallocate BakFile_csr

drop table #dirList

return

GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
 
OK Dude - its a bit clunky, and could do with a full re-write, but try this:
Make sure that you name your backup in the following way:
databasenamebackup.bak where databasename is the name of the DB you will be restoring. You can change this, but you will have to alter your code.
There were a couple of problems in your proc - most stemming from adding quotes.
Create the proc as below and run it with the parms you gave it:
Code:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_CSS_RestoreDir]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_CSS_RestoreDir]
GO



SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO



CREATE proc sp_CSS_RestoreDir 
     @restoreFromDir varchar(255),
       @restoreToDataDir varchar(255)= null,
        @restoreToLogDir varchar(255) = null,
       @MatchFileList char(1) = 'N',
       @OneDBName varchar(255) = null

as

--If a directory for the Log file is not supplied then use the data directory
If @restoreToLogDir is null
    set @restoreToLogDir = @restoreToDataDir

set nocount on
SET quoted_identifier on 

declare @filename     varchar(255),
     @cmd              varchar(500), 
     @cmd2             varchar(500), 
    @DataName         varchar (255),
     @LogName          varchar (255),
    @LogicalName      varchar(255), 
     @PhysicalName     varchar(255), 
     @Type             varchar(20), 
     @FileGroupName    varchar(255), 
     @Size             varchar(20), 
     @MaxSize          varchar(20),
     @restoreToDir     varchar(255),
    @searchName       varchar(255),
     @DBName           varchar(255),
    @PhysicalFileName varchar(255) 

create table #dirList (filename varchar(100))
create table #filelist (LogicalName nvarchar(128), PhysicalName nvarchar(260), Type char(1), FileGroupName nvarchar(128), Size numeric(20,0), MaxSize numeric(20,0), FilID bigint, CreateLSN numeric(25,0), DropLSN numeric(25,0), UniqueID uniqueidentifier, ReadOnlyLSN numeric(25,0), 
ReadWriteLSN numeric(25,0), BackupSizeInBytes bigint, SourceBlockSize int, FileGroupID int, LogGroupGUID uniqueidentifier, DifferentialBaseLSN numeric(25,0), DifferentialBaseGUID uniqueidentifier, IsReadOnly bit, IsPresent bit)

--Get the list of database backups that are in the restoreFromDir directory
if @OneDBName is null 

   select @cmd = 'dir /b /on "' + @restoreFromDir+ '"'


else
   select @cmd = 'dir /b /o-d /o-g "' +@restoreFromDir+ '"'

insert #dirList exec master..xp_cmdshell @cmd  

select * from #dirList where filename like '%_Backup_%' --order by filename

if @OneDBName is null 
   declare BakFile_csr cursor for 
      select * from #dirList where filename like '%_Backup_%bak' order by filename
else
   begin  -- single db, don't order by filename, take default latest date /o-d parm in dir command above
     select @searchName = @OneDBName + '_Backup_%bak'
     declare BakFile_csr cursor for 
       select top 1 * from #dirList where filename like @searchName
   end

open BakFile_csr
fetch BakFile_csr into @filename

while @@fetch_status = 0
   begin
       select @cmd = 'RESTORE FILELISTONLY FROM disk = ''' + @restoreFromDir + '\' + @filename + ''''


       insert #filelist exec ( @cmd )

       if @OneDBName is null 

          select @dbName = left(@filename,datalength(@filename) - patindex('%_bd_%',reverse(@filename))-10) -- -10, to allow for 'backup.bak' ending here, NOT -3!!

       else
       select @dbName = @OneDBName

       select @cmd = 'RESTORE DATABASE ' + @dbName + 
        ' FROM DISK = ''' + @restoreFromDir + '\' + @filename +'''' + ' WITH ' 

       PRINT '' 
       PRINT 'RESTORING DATABASE ' + @dbName

       declare DataFileCursor cursor for  
        select LogicalName, PhysicalName, Type, FileGroupName, Size, MaxSize
        from #filelist

    open DataFileCursor
       fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize



       while @@fetch_status = 0
          begin
              if @MatchFileList != 'Y'
                 begin  -- RESTORE with MOVE option 
               select @PhysicalFileName = reverse(substring(reverse(rtrim(@PhysicalName)),1,patindex('%\%',reverse(rtrim(@PhysicalName)))-1 )) 

               if @Type = 'L'
                   select @restoreToDir = @restoreToLogDir
               else
                   select @restoreToDir = @restoreToDataDir

               select @cmd = @cmd + 
                    ' MOVE ''' + @LogicalName + ''' TO ''' + @restoreToDir + '\' + @PhysicalFileName + ''', ' 
                 end
              else
                 begin  -- Match the file list, attempt to create any missing directory
                     select @restoreToDir = left(@PhysicalName,datalength(@PhysicalName) - patindex('%\%',reverse(@PhysicalName)) )
                     select @cmd2 = 'if not exist ' +@restoreToDir+ ' md ' +@restoreToDir
                     exec master..xp_cmdshell  @cmd2
                 end

              fetch DataFileCursor into @LogicalName, @PhysicalName, @Type, @FileGroupName, @Size, @MaxSize

          end  -- DataFileCursor loop

    close DataFileCursor
        deallocate DataFileCursor

       select @cmd = @cmd + ' REPLACE, STATS = 10'
       --select @cmd 'command'

       EXEC (@CMD)

       truncate table #filelist

       fetch BakFile_csr into @filename

   end -- BakFile_csr loop

close BakFile_csr
deallocate BakFile_csr

drop table #filelist
drop table #dirList

return

GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO
 
Many Thanks. That did work!!! Like I said, I didn't write it .. just been using on 2000 for several years!!!

I did change one thing.... my backup files are named MYBACKUP_backup_200808100245.bak because they are generated from the maintenance plans.

I changed this:


select @dbName = left(@filename,datalength(@filename) - patindex('%_bd_%',reverse(@filename))-10) -- -10, to allow for 'backup.bak' ending here, NOT -3!!

To this:

select @dbName = left(@filename,datalength(@filename) - patindex('%_bd_%',reverse(@filename))-24) -- -24, to allow for '_backup_200808100245.bak'
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top