我已使用smo restore方法成功恢复了数据库。但是当我尝试将相同的.bak
文件恢复到另一个数据库时,它会返回一个异常,如下所示
我从我使用的.bak
数据库模板创建了GC_BranchName
文件。 GC_Muntinlupa是我创建的第一个数据库,并成功恢复了.bak文件。有人可以就此提出建议吗?
这是我的恢复代码:
bool RestoreDB(string name)
{
try
{
var connection = new ServerConnection(Properties.Settings.Default.Well);
var sqlServer = new Server(connection);
var rstDatabase = new Restore();
rstDatabase.Database = name;
rstDatabase.Action = RestoreActionType.Database;
rstDatabase.Devices.AddDevice(System.Environment.CurrentDirectory + "\\GC.bak", DeviceType.File);
rstDatabase.ReplaceDatabase = true;
rstDatabase.SqlRestore(sqlServer);
connection.Disconnect();
return true;
}
catch (Exception ex)
{
MessageBox.Show("A problem occured when building the branch!" + ex, "Monytron Consolidator", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
答案 0 :(得分:0)
对不起J.P Masangcay,但到目前为止我还没来得及为你们所有人。 以下是适合您的解决方案,由我验证。
您的问题是,如果将数据库备份还原到新数据库,则会出现文件错误。
为什么文件冲突?
SQL Server的默认行为是使用文件路径和数据和日志文件的名称来恢复数据库,就像备份时一样。因此,如果在还原过程中存在该原始数据库,则会导致文件系统冲突。如果将数据库备份模板多次还原到另一台服务器,则会出现相同的冲突。
你的案子:
数据库:GC_BranchName
数据文件:GC_BranchName.mdf
日志文件:GC_BranchName_log.ldf
Resore数据库:GC_Muntinlupa
数据文件: GC_BranchName.mdf
日志文件: GC_BranchName_log.ldf
要解决问题,您必须重新定位文件以使数据库具有不同的文件名。这是一个解决方案,它简单地添加/预先设置了新的数据库名称"到所有文件。这种重新定位在引擎盖下使用TSQL恢复数据库" RESTORE DATABASE ... WITH MOVE"选项,如上面的例外情况所示。
Resore数据库:GC_Muntinlupa
数据文件: GC_Muntinlupa_GC_BranchName.mdf
日志文件: GC_Muntinlupa_GC_BranchName_log.ldf
bool RestoreDB(string name)
{
try
{
var connection = ServerConnection(Properties.Settings.Default.Well);
var sqlServer = new Server(connection);
var rstDatabase = new Restore();
rstDatabase.Database = name;
rstDatabase.Action = RestoreActionType.Database;
rstDatabase.Devices.AddDevice(System.Environment.CurrentDirectory + "\\GC.bak", DeviceType.File);
rstDatabase.ReplaceDatabase = true;
foreach (DataRow r in rstDatabase.ReadFileList(sqlServer).Rows)
{
var relocateFile = new RelocateFile();
relocateFile.LogicalFileName = r["LogicalName"].ToString();
// move/rename physical filename by prepending database name to prevent FileSystem conflicts
var physicalName = r["PhysicalName"].ToString();
var path = System.IO.Path.GetDirectoryName(physicalName);
var filename = System.IO.Path.GetFileName(physicalName);
physicalName = System.IO.Path.Combine(path, string.Format("{0}_{1}", name, filename));
relocateFile.PhysicalFileName = physicalName;
rstDatabase.RelocateFiles.Add(relocateFile);
}
rstDatabase.SqlRestore(sqlServer);
connection.Disconnect();
return true;
}
catch (Exception ex)
{
MessageBox.Show("A problem occured when building the branch!" + ex, "Monytron Consolidator", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
答案 1 :(得分:0)
这应该可以解决问题
namespace DB_Restore
{
class Program
{
static void Main(string[] args)
{
RestoreDatabase();
}
public static void RestoreDatabase()
{
try
{
ServerConnection connection = new ServerConnection(@"Server\instance", "uname", "PWD");
Server sqlServer = new Server(connection);
Restore rstDatabase = new Restore();
rstDatabase.Action = RestoreActionType.Database;
rstDatabase.Database = "H5MI_Automation_Restore_Backup";
BackupDeviceItem bkpDevice = new BackupDeviceItem(@"E:\DATA\QA_SP\MSSQL11.QA_SP\MSSQL\Backup\H5MI_Automation.bak", DeviceType.File);
rstDatabase.Devices.Add(bkpDevice);
rstDatabase.ReplaceDatabase = true;
//As mentioned in the above solution this code will take care .mdf and .ldf file location issue
foreach (DataRow r in rstDatabase.ReadFileList(sqlServer).Rows)
{
var relocateFile = new RelocateFile();
relocateFile.LogicalFileName = r["LogicalName"].ToString();
Console.WriteLine(relocateFile.LogicalFileName);
var physicalName = r["PhysicalName"].ToString();
Console.WriteLine(physicalName);
var path = System.IO.Path.GetDirectoryName(physicalName);
Console.WriteLine(path);
var filename = System.IO.Path.GetFileName(physicalName);
Console.WriteLine(filename);
physicalName = path + @"\H5MI_Automation_Restore_Backup_" + filename;
Console.WriteLine(physicalName);
relocateFile.PhysicalFileName = physicalName;
Console.WriteLine(relocateFile.PhysicalFileName);
Console.WriteLine(relocateFile);
rstDatabase.RelocateFiles.Add(relocateFile);
}
rstDatabase.SqlRestore(sqlServer);
connection.Disconnect();
}
catch (Exception e)
{
Console.Write(e);
}
}
}
}
添加代码说明。实质上,上述屏幕快照中的问题是由于.mdf和.ldf文件位置所致。当您尝试手动还原数据库时,u也会遇到相同的问题。附加屏幕截图。Manual DB restore
为什么会抛出错误? 这是因为该文件由实际的DB使用(从中生成.bak文件)
因此,这段代码将帮助您更改.mdf和.ldf文件路径的位置。
foreach (DataRow r in rstDatabase.ReadFileList(sqlServer).Rows)
{
var relocateFile = new RelocateFile();
relocateFile.LogicalFileName = r["LogicalName"].ToString();
Console.WriteLine(relocateFile.LogicalFileName);
var physicalName = r["PhysicalName"].ToString();
Console.WriteLine(physicalName);
var path = System.IO.Path.GetDirectoryName(physicalName);
Console.WriteLine(path);
var filename = System.IO.Path.GetFileName(physicalName);
Console.WriteLine(filename);
physicalName = path + @"\H5MI_Automation_Restore_Backup_" + filename;
Console.WriteLine(physicalName);
relocateFile.PhysicalFileName = physicalName;
Console.WriteLine(relocateFile.PhysicalFileName);
Console.WriteLine(relocateFile);
rstDatabase.RelocateFiles.Add(relocateFile);
}