2009-09-23 40 views
14

Tôi có một SQL 2008 DB. Tôi đang chạy một hình thức sao lưu DB đó, sau đó cố gắng cập nhật nó. Nếu cập nhật thất bại, ý tưởng là khôi phục bản sao lưu đó. Đây là mã tôi đang sử dụng để khôi phục bản sao lưu.Cách khôi phục cơ sở dữ liệu từ C#

public void RestoreDatabase(String databaseName, String backUpFile, String serverName, String userName, String password) 
{ 
    Restore sqlRestore = new Restore(); 
    BackupDeviceItem deviceItem = new BackupDeviceItem(backUpFile, DeviceType.File); 
    sqlRestore.Devices.Add(deviceItem); 
    sqlRestore.Database = databaseName; 
    ServerConnection connection = new ServerConnection(serverName, userName, password); 
    Server sqlServer = new Server(connection); 
    sqlRestore.Action = RestoreActionType.Database; 

    string logFile = System.IO.Path.GetDirectoryName(backUpFile); 
    logFile = System.IO.Path.Combine(logFile, databaseName + "_Log.ldf"); 

    string dataFile = System.IO.Path.GetDirectoryName(backUpFile); 
    dataFile = System.IO.Path.Combine(dataFile, databaseName + ".mdf"); 

    Database db = sqlServer.Databases[databaseName]; 
    RelocateFile rf = new RelocateFile(databaseName, dataFile); 
    sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFile)); 
    sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFile)); 
    sqlRestore.SqlRestore(sqlServer); 
    db = sqlServer.Databases[databaseName]; 
    db.SetOnline(); 
    sqlServer.Refresh(); 
} 

Vấn đề dường như là tên tệp tôi chọn khác với DB trực tuyến. Về cơ bản tôi muốn thay thế cơ sở dữ liệu trên máy chủ bằng bản sao lưu. Tôi nhận được một ngoại lệ khi tôi gọi SqlRestore.

Ngoại lệ chính nói

{ "Khôi phục thất bại cho Server 'localhost'."}

Đào vào trường hợp ngoại lệ bên trong cho thấy các lỗi

Một ngoại lệ xảy ra trong khi thực hiện câu lệnh hoặc lệnh Transact-SQL.

và sau đó

tập tin logic 'DB' không phải là một phần của cơ sở dữ liệu 'DB'. Sử dụng RESTORE FILELISTONLY để liệt kê tệp hợp lệ tên. \ R \ nRESTORE DATABASE là chấm dứt bất thường.

Tôi giả sử có một số cách để nói điều này chỉ sử dụng thay thế DB hiện tại như hiện tại.

Tôi sử dụng bit mã này để lấy đường dẫn tệp của DB để có thư mục để sao lưu. Có lẽ điều này có thể được sử dụng để có được tên tập tin để tạo lại.

public string GetDBFilePath(String databaseName, String userName, String password, String serverName) 
{ 
    ServerConnection connection = new ServerConnection(serverName, userName, password); 
    Server sqlServer = new Server(connection); 
    Database db = sqlServer.Databases[databaseName]; 
    return sqlServer.Databases[databaseName].PrimaryFilePath; 
} 

Trả lời

18

tôi đã thay đổi lưng tôi lưu và khôi phục chức năng giống như thế này:

public void BackupDatabase(SqlConnectionStringBuilder csb, string destinationPath) 
{ 
    ServerConnection connection = new ServerConnection(csb.DataSource, csb.UserID, csb.Password); 
    Server sqlServer = new Server(connection); 

    Backup bkpDatabase = new Backup(); 
    bkpDatabase.Action = BackupActionType.Database; 
    bkpDatabase.Database = csb.InitialCatalog; 
    BackupDeviceItem bkpDevice = new BackupDeviceItem(destinationPath, DeviceType.File); 
    bkpDatabase.Devices.Add(bkpDevice); 
    bkpDatabase.SqlBackup(sqlServer); 
    connection.Disconnect(); 

} 

public void RestoreDatabase(String databaseName, String backUpFile, String serverName, String userName, String password) 
{ 
    ServerConnection connection = new ServerConnection(serverName, userName, password); 
    Server sqlServer = new Server(connection); 
    Restore rstDatabase = new Restore(); 
    rstDatabase.Action = RestoreActionType.Database; 
    rstDatabase.Database = databaseName; 
    BackupDeviceItem bkpDevice = new BackupDeviceItem(backUpFile, DeviceType.File); 
    rstDatabase.Devices.Add(bkpDevice); 
    rstDatabase.ReplaceDatabase = true; 
    rstDatabase.SqlRestore(sqlServer); 
} 

Bằng cách đó họ chỉ cần sử dụng bất cứ file đang có. Không còn chỉ thị và chỉ thị để di chuyển tệp.

+3

Bạn không cần phải di chuyển tệp nếu bạn khôi phục từ bản sao lưu của cùng một db trên cùng một máy.Việc di dời chỉ cần thiết khi di chuyển và sao chép cơ sở dữ liệu thông qua sao lưu/phục hồi. –

+3

Ok, ở đây một số mẹo: liên quan đến đường dẫn tệp sao lưu luôn chú ý nếu tệp thực sự tồn tại trên thư mục nguồn của bạn. Về việc di dời, có thể là vấn đề về quyền để viết tệp mdf. Chú ý nếu ứng dụng của bạn có quyền đọc tệp .bak, trong trường hợp này, hãy kiểm tra Trình quản lý cấu hình SQL: Dịch vụ MSSQLServer phải đang chạy dưới người dùng LocalSystem. –

4

Bạn đang thêm RelocateFile tùy chọn dựa trên tên cơ sở dữ liệu, đó là không chính xác. Bạn nên thêm chúng dựa trên tên tệp logic cho mỗi tệp được di chuyển. Sử dụng Restore.ReadFileList để truy xuất danh sách tên tệp logic.

+0

Có vẻ như tôi không thể thêm tất cả các tùy chọn này cùng nhau. –

12

Cảm ơn Remus vì câu trả lời của bạn!

tôi đã sửa đổi

sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFileLocation)); 
sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFileLocation)); 

hai dòng này để

System.Data.DataTable logicalRestoreFiles = sqlRestore.ReadFileList(sqlServer); 
sqlRestore.RelocateFiles.Add(new RelocateFile(logicalRestoreFiles.Rows[0][0].ToString(), dataFileLocation)); 
sqlRestore.RelocateFiles.Add(new RelocateFile(logicalRestoreFiles.Rows[1][0].ToString(), logFileLocation)); 

và mã của tôi đang chạy thành công.

Cảm ơn sự hỗ trợ!

+0

@Pallavi Giải pháp của bạn đã làm việc ngay lập tức cho tôi .. Nhưng tôi không thể hiểu được giải pháp, Bạn vui lòng trả lời câu trả lời của bạn. –

+1

Giải pháp này cũng hoàn hảo cho tôi. Đối với những người muốn nhiều hơn, những gì localRestoreFiles nắm giữ là cơ sở dữ liệu nguồn "Danh sách tệp". Danh sách tệp của cơ sở dữ liệu đó, chẳng hạn như tất cả các tệp MDF, Nhật ký và tệp chỉ mục đã được tạo. Tuy nhiên, các số hàng này [X] giả sử bạn có DB bình thường chỉ với 1 MDF và 1 LDF (ví dụ: không có tệp nhật ký hoặc tệp chỉ mục bổ sung). Nếu trường hợp đó xảy ra, Hàng [0] chứa tệp MDF đầu tiên, Hàng [1] sẽ là tệp nhật ký. Và hàng [0] [0] và hàng [1] [0] sẽ chứa tên cơ sở dữ liệu lôgic (có nghĩa là trường hợp nhạy cảm!) Mà bạn có thể sử dụng để "di chuyển". – eduncan911

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