Проблемы с SqlRestore при использовании разных баз данных - PullRequest
0 голосов
/ 05 августа 2010

У меня есть проект, который может быть запущен в базах данных с разными именами.У меня есть некоторые функции в моей программе для резервного копирования базы данных и восстановления из них.Проблема в том, когда я пытаюсь восстановить базу данных из резервной копии в другую базу данных с другим именем и так далее.Мой код выглядит так:

        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);
        }
    }

Но SQL выводит такие ошибки:

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.

Я думаю, это потому, что резервные копии могут быть сделаны из баз данных с разными логическими именами, например, "Serve "," Serve2 "," serve3 "или что-то в этом роде.

ИЛИ он выводит какую-то другую ошибку, которая говорит, что файл не может быть перемещен, потому что другая база данных использует его.Может быть, есть какой-нибудь способ определить имя базы данных (например, «временная БД») для временной БД, из которой впоследствии можно было бы заменить файлы на исходные базы данных?Может быть, мой код где-то неверен, кто-нибудь может помочь?

1 Ответ

0 голосов
/ 17 августа 2010

Я решил это, оставив имя существующей базы данных, например:

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;
        }
...