views:

23

answers:

1

Hello, i have some project, which can be running on databases with different names. I have some functionality in my program to do database backups and to restoring from them. The problem is when i try to restore database from backup to other database with a different name and so on. My code looks like this:

        public void Restore(string backupFilePath, string toDatabase)
    {
        // Kill database if exists
        Database db = server.Databases[toDatabase];
        RecoveryModel recoverymod = RecoveryModel.Full; 
        if (db != null)
        {
            recoverymod = db.DatabaseOptions.RecoveryModel;
            server.KillAllProcesses(toDatabase);
        }

        // Restore to database
        var bdi = new BackupDeviceItem(backupFilePath, DeviceType.File);
        var restore = new Restore();
        restore.Devices.Add(bdi);
        restore.FileNumber = restore.Devices.IndexOf(bdi);
        restore.Database = toDatabase;
        restore.KeepReplication = true;
        restore.Action = RestoreActionType.Database;
        restore.ReplaceDatabase = true;
        //restore.Restart = true;
        restore.NoRecovery = false;
        string dbFolder = Path.Combine(server.InstallDataDirectory, "DATA");

        string backupDBName = toDatabase; //Path.GetFileName(backupFilePath).Split('_')[0]; 
        restore.RelocateFiles.Add(new RelocateFile(backupDBName, Path.Combine(dbFolder, toDatabase + ".MDF")));
        restore.RelocateFiles.Add(new RelocateFile(backupDBName + "_log",
                                                   Path.Combine(dbFolder, toDatabase + ".LDF")));
        restore.SqlRestore(server);

        // Startup database
        db = server.Databases[toDatabase];
        db.DatabaseOptions.RecoveryModel = recoverymod; 
        db.SetOnline();
        while (((int)db.Status & (int)DatabaseStatus.Normal) != (int)DatabaseStatus.Normal)
        {
            Thread.Sleep(1000);
        }
    }

But SQL outputs errors like these:

Msg 3234, Level 16, State 2, Line 1
Logical file 'ServeDB7' is not part of database 'ServeDB7'. Use RESTORE FILELISTONLY to list the logical file names.
Msg 3013, Level 16, State 1, Line 1
RESTORE DATABASE is terminating abnormally.

I think this is becouse backups can be made from databases with different logical names, such as "Serve", "Serve2", "serve3" or something like this.

OR it puts some other error, which says, that file cannot be moved, becouse other database are using it. Maybe Is there some way to define a database name (like "temporaryDB") for temporary DB, from which files later could be replaced on a original databas? Maybe my code is somewhere incorect, could anyone help?

A: 

I solved this by leaving existing database name, like this:

string backupDBName = GetDbNameFromBackup(restore);
            restore.RelocateFiles.Add(new RelocateFile(backupDBName, Path.Combine(dbFolder, toDatabase + ".MDF")));
            restore.RelocateFiles.Add(new RelocateFile(backupDBName + "_log", Path.Combine(dbFolder, toDatabase + ".LDF")));
            restore.SqlRestore(server);

private string GetDbNameFromBackup(Restore restore)
        {
            string originalDbName = null;
            if (restore != null && this.server != null)
            {
                DataTable restoreInfo = restore.ReadFileList(this.server);
                if (restoreInfo.Rows.Count > 0)
                {
                    object[] cols = restoreInfo.Rows[0].ItemArray;
                    if (cols != null && cols.Count() > 0)
                    {
                        if (cols[0] is string && !String.IsNullOrEmpty((string)cols[0]))
                        {
                            originalDbName = (string)cols[0];
                        }
                    }
                }
            }
            return originalDbName;
        }
Vytas999