2013-01-17 20 views
12

SQL Server SMO'yu bir .bak dosyasını yeni bir veritabanına geri yüklemek için kullanıyorum, ancak çalışmadı.smo geri yükleme veritabanı

sql server 2012 ve smo nesne sürüm 11.0

dosya .bak yanı aynı kodlama pc, sql yönetim stüdyo 2012, aynı yerel pc kullanılarak oluşturuldu son sdk sürümü olmasıdır.

alıyorum hata iletisi:

Server 'SERVER' için geri yüklenemedi.

Kodumda neyin var?

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

GÜNCELLEME: Ben SMO çözümlerini surrended ve tüm

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. 

Teşekkür çalıştı.

+0

İç bir istisna var mı? Lütfen hata ayıklamasını kontrol edin, bu muhtemelen size gerçek sebebi verecektir. – Bridge

+0

Ayrıca, önceden varolan dosyaların üzerine yazmaya çalıştığınızdan emin misiniz? Aynı dbName işlevini kullanırsanız, aynı ada sahip veri ve günlük dosyalarınız olabilir. Dosyanın önce var olup olmadığını kontrol etmeyi deneyin, eğer varsa, tekrar oluşturmayı deneyin. – Bridge

+0

Yedekleme aygıtı 'd: \ template.BAK' açılamıyor. İşletim sistemi hatası 123 (Dosya adı, dizin adı veya birim etiketi sözdizimi yanlış.). >> .bak, sql management studio 2012 tarafından oluşturuldu ve smo, doğru sürüm (sürüm 11). –

cevap

21

Veritabanını geri yüklemek için başarıyla SMO kullandım. Kodumu paylaşırım. Umarım yardımcı olur. Bu çözüm bir uyarıya sahip olsa da, yalnızca bir tane birincil veri dosyanız olduğunu düşünür. Günlüğü ve veri dosyalarını eşleştirmek gerçekten zor ve bir şey birçok yönden yanlış gidebilir. Her neyse, bana yardım edelim.

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

Bu kod, birkaç değişiklikle bana gerçekten yardımcı oldu. Bir DB'yi farklı bir konuma geri yüklemem gerekiyordu ve bu RelocateFiles'in işleri karmaşık, iyi çalışıyordu. – Jez

+0

Merhaba, veritabanı geri yükleme işleminde yeniden yerleştirme dosyalarının amacı nedir? –

+0

@RustyWizard Bazen veritabanı dosyaları varsayılan konumda bulunmaz. Bu durumda, dosyayı bulup geri yükleme sırasında kullanmalıyız, böylece geri yükleme sırasında hata oluşmaz. –

İlgili konular