2013-01-17 118 views
12

我使用SQL Server SMO將.bak恢復到新數據庫,但失敗。smo恢復數據庫

的SQL Server 2012是和SMO對象版本是最新的SDK版本11.0

.bak的文件是使用SQL管理工作室2012年,同樣的本地PC,在相同的編碼PC以及創建。

該錯誤消息我得到的是:

還原失敗的服務器 '服務器'。

我的代碼有什麼問題?

string dbPath = Path.Combine(@"d:\my data", dbName + "_db" + ".mdf"); 
string logPath = Path.Combine(@"d:\my data", dbName + "_db" + "_Log.ldf"); 

Restore restore = new Restore(); 

BackupDeviceItem deviceItem = new BackupDeviceItem("d:\template.BAK", DeviceType.File); 
restore.Devices.Add(deviceItem); 
restore.Database = dbName + "_db"; 

RelocateFile relocateDataFile = new RelocateFile("Data", dbPath); 
RelocateFile relocateLogFile = new RelocateFile("Log", logPath); 

restore.RelocateFiles.Add(relocateDataFile); 
restore.RelocateFiles.Add(relocateLogFile); 

restore.Action = RestoreActionType.Database; 
restore.ReplaceDatabase = true; 
restore.SqlRestore(server); 

更新:我surrended SMO解決方案,並試圖

using (SqlConnection connection = new SqlConnection("Data Source=server;user id=sa;password=xxxxx;")) 
     { 

      using (SqlCommand command = new SqlCommand(@"RESTORE DATABASE beauty01 FROM DISK = 'd:\template.bak' WITH RECOVERY, MOVE 'beauty1' TO 'D:\MyData\beauty01_Data.mdf', MOVE 'beauty1_log' TO 'd:\Mydata\beauty01_Log.ldf', REPLACE", connection)) 
      { 
       connection.Open(); 
       // Add the parameters for the SelectCommand. 


       command.CommandType = CommandType.Text; 
       command.ExecuteNonQuery(); 
      } 

     } >> work good. 

感謝所有。

+0

是否存在內部異常?請檢查調試,這可能會給你真正的原因。 – Bridge

+0

另外,你確定你沒有試圖覆蓋已經存在的文件嗎?如果使用相同的'dbName',則可以使用相同名稱的數據和日誌文件 - 嘗試檢查文件是否先存在,如果存在,則不要嘗試再次創建它。 – Bridge

+0

無法打開備份設備'd:\ template.BAK'。操作系統錯誤123(文件名,目錄名稱或卷標語法不正確。)。 >> .bak由sql management studio 2012創建,smo是正確的版本(版本11)。 –

回答

21

我成功地使用了SMO來恢復數據庫。我會分享我的代碼。希望能幫助到你。這個解決方案雖然有一個警告,但它認爲你只有一個主數據文件。使日誌和數據文件相匹配非常棘手,在許多方面可能會出現問題。無論如何,儘量讓我知道這有助於。

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.IO; 
using System.Text; 
using System.Threading; 
using Microsoft.SqlServer.Management.Common; 
using Microsoft.SqlServer.Management.Smo; 
using Microsoft.Win32; 

namespace DatabaseUtility 
{ 
    public class BackupRestore 
    { 
     static Server srv; 
     static ServerConnection conn; 

     public static void BackupDatabase(string serverName, string databaseName, string filePath) 
     { 
      conn = new ServerConnection(); 
      conn.ServerInstance = serverName; 
      srv = new Server(conn); 

      try 
      { 
       Backup bkp = new Backup(); 

       bkp.Action = BackupActionType.Database; 
       bkp.Database = databaseName; 

       bkp.Devices.AddDevice(filePath, DeviceType.File); 
       bkp.Incremental = false; 

       bkp.SqlBackup(srv); 

       conn.Disconnect(); 
       conn = null; 
       srv = null; 
      } 

      catch (SmoException ex) 
      { 
       throw new SmoException(ex.Message, ex.InnerException); 
      } 
      catch (IOException ex) 
      { 
       throw new IOException(ex.Message, ex.InnerException); 
      } 
     } 

     public static void RestoreDatabase(string serverName, string databaseName, string filePath) 
     { 

      conn = new ServerConnection(); 
      conn.ServerInstance = serverName; 
      srv = new Server(conn); 

      try 
      { 
       Restore res = new Restore(); 

       res.Devices.AddDevice(filePath, DeviceType.File); 

       RelocateFile DataFile = new RelocateFile(); 
       string MDF = res.ReadFileList(srv).Rows[0][1].ToString(); 
       DataFile.LogicalFileName = res.ReadFileList(srv).Rows[0][0].ToString(); 
       DataFile.PhysicalFileName = srv.Databases[databaseName].FileGroups[0].Files[0].FileName; 

       RelocateFile LogFile = new RelocateFile(); 
       string LDF = res.ReadFileList(srv).Rows[1][1].ToString(); 
       LogFile.LogicalFileName = res.ReadFileList(srv).Rows[1][0].ToString(); 
       LogFile.PhysicalFileName = srv.Databases[databaseName].LogFiles[0].FileName; 

       res.RelocateFiles.Add(DataFile); 
       res.RelocateFiles.Add(LogFile); 

       res.Database = databaseName; 
       res.NoRecovery = false; 
       res.ReplaceDatabase = true; 
       res.SqlRestore(srv); 
       conn.Disconnect(); 
      } 
      catch (SmoException ex) 
      { 
       throw new SmoException(ex.Message, ex.InnerException); 
      } 
      catch (IOException ex) 
      { 
       throw new IOException(ex.Message, ex.InnerException); 
      } 
     } 

     public static Server Getdatabases(string serverName) 
     { 
      conn = new ServerConnection(); 
      conn.ServerInstance = serverName; 

      srv = new Server(conn); 
      conn.Disconnect(); 
      return srv; 

     } 
    } 
} 
+0

這段代碼真的幫了我一些修改。我需要將數據庫恢復到不同的位置,並且'RelocateFiles'東西很複雜,運行良好。 – Jez

+0

嗨,在數據庫恢復操作中重定位文件的目的是什麼? –

+0

@RustyWizard有時數據庫文件不在默認位置。在這種情況下,我們需要找到該文件並在還原命令中使用它,以便在還原時沒有錯誤。 –