2009-10-26 108 views
3

我已經閱讀了十幾個不同的博客,並閱讀了msdn示例,他們只是不適合我。SMO:恢復到不同的數據庫

最終,我試圖做的是將數據庫從我們的生產實例自動移動到我們的開發實例或其他方向。

我採取的方法是這樣的:

  1. 備份/
  2. 分離臨時DB
  3. 複製MDF和LDF文件恢復到一個臨時DB到其他實例
  4. 重新掛接。

我被困在1,我不明白爲什麼。我讀過的所有東西都聲稱這應該是有效的。

注意:我已將dbName設置爲要恢復到的分貝。我還設置了restore.Database = dbName,其中restoresmo命名空間中的Restore類的實例。

mdf.LogicalFileName = dbName; 
mdf.PhysicalFileName = String.Format(@"{0}\{1}.mdf", server.Information.MasterDBPath, dbName); 
ldf.LogicalFileName = dbName + "_log"; 
ldf.PhysicalFileName = String.Format(@"{0}\{1}.ldf", server.Information.MasterDBPath, dbName); 

restore.RelocateFiles.Add(mdf); 
restore.RelocateFiles.Add(ldf); 
restore.SqlRestore(server); 

這是我收到的例外:

文件 'd:\ MSSQL.MIQ_Dev \ MSSQL.2 \ MSSQL \ DATA \ MIQDesign2Detach.mdf' 不能被覆蓋。它正在被數據庫'MIQDesignTest2'使用。
文件'MIQDesign'無法恢復爲'D:\ MSSQL.MIQ_Dev \ MSSQL.2 \ MSSQL \ Data \ MIQDesign2Detach.mdf'。使用WITH MOVE標識文件的有效位置。
文件'D:\ MSSQL.MIQ_Dev \ MSSQL.2 \ MSSQL \ Data \ MIQDesign2Detach.ldf'不能被覆蓋。它正在被數據庫'MIQDesignTest2'使用。
文件'MIQDesign_log'無法恢復到'D:\ MSSQL.MIQ_Dev \ MSSQL.2 \ MSSQL \ Data \ MIQDesign2Detach.ldf'。使用WITH MOVE標識文件的有效位置。
規劃RESTORE語句時發現問題。先前的消息提供了細節
RESTORE DATABASE正在異常終止。

爲什麼這會試圖覆蓋原來的mdf?是不是RelocateFiles的東西應該指定,你希望它被保存到不同的物理文件名?

回答

-1

我遇到了類似的問題,我發現這個解決方案非常有幫助。

看看 - http://www.eggheadcafe.com/software/aspnet/32188436/smorestore-database-name-change.aspx

+0

謝謝伯博爾,我從來沒有能夠解決這個問題,因爲我已經移動到更大更好的東西,但我一定會記住這一點,如果我發現自己通過SMO再次自動化的事情: ) – Fred 2010-11-25 21:27:17

+2

死鏈接。這是LINK ONLY答案的問題。如果您不打算複製該信息,則應該在答案中發佈信息,並將該信息與「深入」建議關聯起來。 – StarPilot 2014-07-14 21:53:53

5

它的作品。

public class DatabaseManager 
{ 
    public Action<int, string> OnSqlBackupPercentComplete; 
    public Action<int, string> OnSqlRestorePercentComplete; 
    public Action<SqlError> OnSqlBackupComplete; 
    public Action<SqlError> OnSqlRestoreComplete; 

    public bool IsConnected { get; private set; } 

    private ServerConnection _connection; 

    public void Connect(string userName, string password, string serverName, bool useInteratedLogin) 
    { 
     if (useInteratedLogin) 
     { 
      var sqlCon = new SqlConnection(string.Format("Data Source={0}; Integrated Security=True; Connection Timeout=5", serverName)); 
      _connection = new ServerConnection(sqlCon); 
      _connection.Connect(); 
      IsConnected = true; 
     } 
     else 
     { 
      _connection = new ServerConnection(serverName, userName, password); 
      _connection.ConnectTimeout = 5000; 
      _connection.Connect(); 
      IsConnected = true; 
     } 

    } 

    public void BackupDatabase(string databaseName, string destinationPath) 
    { 
     var sqlServer = new Server(_connection); 


     databaseName = databaseName.Replace("[", "").Replace("]", ""); 
     var sqlBackup = new Backup 
      { 
       Action = BackupActionType.Database, 
       BackupSetDescription = "ArchiveDataBase:" + DateTime.Now.ToShortDateString(), 
       BackupSetName = "Archive", 
       Database = databaseName 
      }; 

     var deviceItem = new BackupDeviceItem(destinationPath, DeviceType.File); 

     sqlBackup.Initialize = true; 
     sqlBackup.Checksum = true; 
     sqlBackup.ContinueAfterError = true; 

     sqlBackup.Devices.Add(deviceItem); 
     sqlBackup.Incremental = false; 
     sqlBackup.ExpirationDate = DateTime.Now.AddDays(3); 

     sqlBackup.LogTruncation = BackupTruncateLogType.Truncate; 
     sqlBackup.PercentCompleteNotification = 10; 
     sqlBackup.PercentComplete += (sender, e) => OnSqlBackupPercentComplete(e.Percent, e.Message); 
     sqlBackup.Complete += (sender, e) => OnSqlBackupComplete(e.Error); 
     sqlBackup.FormatMedia = false; 
     sqlBackup.SqlBackup(sqlServer); 


    } 

    public DatabaseCollection GetDatabasesList() 
    { 
     if (IsConnected) 
     { 
      var sqlServer = new Server(_connection); 
      return sqlServer.Databases; 
     } 
     return null; 
    } 



    public void RestoreDatabase(string databaseName, string filePath) 
    { 
     var sqlServer = new Server(_connection); 

     databaseName = databaseName.Replace("[", "").Replace("]", ""); 

     var sqlRestore = new Restore(); 
     sqlRestore.PercentCompleteNotification = 10; 
     sqlRestore.PercentComplete += (sender, e) => OnSqlRestorePercentComplete(e.Percent, e.Message); 
     sqlRestore.Complete += (sender, e) => OnSqlRestoreComplete(e.Error); 

     var deviceItem = new BackupDeviceItem(filePath, DeviceType.File); 
     sqlRestore.Devices.Add(deviceItem); 
     sqlRestore.Database = databaseName; 

     DataTable dtFileList = sqlRestore.ReadFileList(sqlServer); 

     int lastIndexOf = dtFileList.Rows[1][1].ToString().LastIndexOf(@"\"); 
     string physicalName = dtFileList.Rows[1][1].ToString().Substring(0, lastIndexOf + 1); 
     string dbLogicalName = dtFileList.Rows[0][0].ToString(); 
     string dbPhysicalName = physicalName + databaseName + ".mdf"; 
     string logLogicalName = dtFileList.Rows[1][0].ToString(); 
     string logPhysicalName = physicalName + databaseName + "_log.ldf"; 
     sqlRestore.RelocateFiles.Add(new RelocateFile(dbLogicalName, dbPhysicalName)); 
     sqlRestore.RelocateFiles.Add(new RelocateFile(logLogicalName, logPhysicalName)); 

     sqlServer.KillAllProcesses(sqlRestore.Database); 

     Database db = sqlServer.Databases[databaseName]; 
     if (db != null) 
     { 
      db.DatabaseOptions.UserAccess = DatabaseUserAccess.Single; 
      db.Alter(TerminationClause.RollbackTransactionsImmediately); 
      sqlServer.DetachDatabase(sqlRestore.Database, false); 
     } 

     sqlRestore.Action = RestoreActionType.Database; 
     sqlRestore.ReplaceDatabase = true; 

     sqlRestore.SqlRestore(sqlServer); 
     db = sqlServer.Databases[databaseName]; 
     db.SetOnline(); 
     sqlServer.Refresh(); 
     db.DatabaseOptions.UserAccess = DatabaseUserAccess.Multiple; 
    } 

    public void Disconnect() 
    { 
     if (IsConnected) 
      _connection.Disconnect(); 

     IsConnected = false; 
    } 
}