2013-01-17 40 views
12

Tôi sử dụng SQL Server SMO để khôi phục tệp .bak sang cơ sở dữ liệu mới, nhưng không hoạt động.smo khôi phục cơ sở dữ liệu

sql server 2012 và smo phiên bản đối tượng là từ phiên bản sdk mới nhất 11.0

tập tin bak đã được tạo ra sử dụng quản lý phòng thu sql 2012, cùng pc địa phương, trên pc mã hóa giống như tốt.

Thông báo lỗi tôi nhận được là:

Khôi phục thất bại cho Server 'MÁY CHỦ'.

Mã của tôi có vấn đề gì?

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

CẬP NHẬT: Tôi surrended giải pháp SMO, và cố gắng

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. 

Cảm ơn tất cả.

+0

Có ngoại lệ bên trong không? Vui lòng kiểm tra trong gỡ lỗi, điều đó có thể sẽ cung cấp cho bạn lý do thực sự. – Bridge

+0

Ngoài ra, bạn có chắc chắn bạn không cố gắng ghi đè lên các tệp đã tồn tại không? Nếu bạn sử dụng cùng một 'dbName', bạn có thể có dữ liệu và tệp nhật ký có cùng tên - hãy thử kiểm tra xem tệp có tồn tại trước không, và nếu có, đừng thử tạo lại nó. – Bridge

+0

Không thể mở thiết bị sao lưu 'd: \ template.BAK'. Lỗi hệ điều hành 123 (Tên tệp, tên thư mục hoặc cú pháp nhãn khối lượng không chính xác.). >> .bak được tạo bởi studio quản lý sql 2012 và smo là phiên bản chính xác (phiên bản 11). –

Trả lời

21

Tôi đã sử dụng thành công SMO để khôi phục cơ sở dữ liệu. Tôi sẽ chia sẻ mã của tôi. Hy vọng nó giúp. Tuy nhiên, giải pháp này có một cảnh báo trước, nó cho rằng bạn chỉ có một tệp dữ liệu chính. Bắt để phù hợp với các tập tin đăng nhập và dữ liệu thực sự phức tạp và một cái gì đó có thể đi sai theo nhiều cách. Dù sao thì hãy thử và cho tôi biết điều này có ích.

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

Mã này thực sự đã giúp tôi, với một vài sửa đổi. Tôi cần khôi phục một DB đến một vị trí khác và công cụ 'RelocateFiles', phức tạp như nó hoạt động tốt. – Jez

+0

Xin chào, mục đích của việc di chuyển tệp trong hoạt động khôi phục cơ sở dữ liệu là gì? –

+0

@RustyWizard Đôi khi các tệp cơ sở dữ liệu không có ở vị trí mặc định. Trong trường hợp đó, chúng ta cần tìm tệp và sử dụng nó trong lệnh khôi phục để không có lỗi trong khi khôi phục. –

Các vấn đề liên quan