3

我已经阅读了十几个不同的博客,以及阅读了 msdn 示例,但它们对我不起作用。

最终,我要做的是自动将数据库从我们的生产实例移动到我们的开发实例,或其他方向。

因此,我采取的方法是:

  1. 备份/恢复到临时数据库
  2. 分离临时数据库
  3. 将 mdf 和 ldf 文件复制到另一个实例
  4. 重新连接。

我被困在 1 上,我不明白为什么。我读过的所有内容都声称这应该有效。

注意:我已设置dbName为要恢复到的数据库。我也设置了restore.Database = dbName,其中是命名空间中类的restore一个实例。Restoresmo

mdf.LogicalFileName = dbName;
mdf.PhysicalFileName = String.Format(@"{0}\{1}.mdf", server.Information.MasterDBPath, dbName);
ldf.LogicalFileName = dbName + "_log";
ldf.PhysicalFileName = String.Format(@"{0}\{1}.ldf", server.Information.MasterDBPath, dbName);

restore.RelocateFiles.Add(mdf);
restore.RelocateFiles.Add(ldf);
restore.SqlRestore(server);

这是我得到的例外:

文件“D:\MSSQL.MIQ_Dev\MSSQL.2\MSSQL\Data\MIQDesign2Detach.mdf”不能被覆盖。数据库“MIQDesignTest2”正在使用它。
文件“MIQDesign”无法恢复到“D:\MSSQL.MIQ_Dev\MSSQL.2\MSSQL\Data\MIQDesign2Detach.mdf”。使用 WITH MOVE 标识文件的有效位置。
文件“D:\MSSQL.MIQ_Dev\MSSQL.2\MSSQL\Data\MIQDesign2Detach.ldf”不能被覆盖。数据库“MIQDesignTest2”正在使用它。
文件“MIQDesign_log”无法恢复到“D:\MSSQL.MIQ_Dev\MSSQL.2\MSSQL\Data\MIQDesign2Detach.ldf”。使用 WITH MOVE 标识文件的有效位置。
在规划 RESTORE 语句时发现了问题。以前的消息提供了详细信息。

为什么这试图覆盖原始的 mdf?不是RelocateFiles应该指定您希望将其保存到不同的物理文件名的东西吗?

4

2 回答 2

5

这是作品。

public class DatabaseManager
{
    public Action<int, string> OnSqlBackupPercentComplete;
    public Action<int, string> OnSqlRestorePercentComplete;
    public Action<SqlError> OnSqlBackupComplete;
    public Action<SqlError> OnSqlRestoreComplete;

    public bool IsConnected { get; private set; }

    private ServerConnection _connection;

    public void Connect(string userName, string password, string serverName, bool useInteratedLogin)
    {
        if (useInteratedLogin)
        {
            var sqlCon = new SqlConnection(string.Format("Data Source={0}; Integrated Security=True; Connection Timeout=5", serverName));
            _connection = new ServerConnection(sqlCon);
            _connection.Connect();
            IsConnected = true;
        }
        else
        {
            _connection = new ServerConnection(serverName, userName, password);
            _connection.ConnectTimeout = 5000;
            _connection.Connect();
            IsConnected = true;
        }

    }

    public void BackupDatabase(string databaseName, string destinationPath)
    {
        var sqlServer = new Server(_connection);


        databaseName = databaseName.Replace("[", "").Replace("]", "");
        var sqlBackup = new Backup
            {
                Action = BackupActionType.Database,
                BackupSetDescription = "ArchiveDataBase:" + DateTime.Now.ToShortDateString(),
                BackupSetName = "Archive",
                Database = databaseName
            };

        var deviceItem = new BackupDeviceItem(destinationPath, DeviceType.File);

        sqlBackup.Initialize = true;
        sqlBackup.Checksum = true;
        sqlBackup.ContinueAfterError = true;

        sqlBackup.Devices.Add(deviceItem);
        sqlBackup.Incremental = false;
        sqlBackup.ExpirationDate = DateTime.Now.AddDays(3);

        sqlBackup.LogTruncation = BackupTruncateLogType.Truncate;
        sqlBackup.PercentCompleteNotification = 10;
        sqlBackup.PercentComplete += (sender, e) => OnSqlBackupPercentComplete(e.Percent, e.Message);
        sqlBackup.Complete += (sender, e) => OnSqlBackupComplete(e.Error);
        sqlBackup.FormatMedia = false;
        sqlBackup.SqlBackup(sqlServer);


    }

    public DatabaseCollection GetDatabasesList()
    {
        if (IsConnected)
        {
            var sqlServer = new Server(_connection);
            return sqlServer.Databases;
        }
        return null;
    }



    public void RestoreDatabase(string databaseName, string filePath)
    {
        var sqlServer = new Server(_connection);

        databaseName = databaseName.Replace("[", "").Replace("]", "");

        var sqlRestore = new Restore();
        sqlRestore.PercentCompleteNotification = 10;
        sqlRestore.PercentComplete += (sender, e) => OnSqlRestorePercentComplete(e.Percent, e.Message);
        sqlRestore.Complete += (sender, e) => OnSqlRestoreComplete(e.Error);

        var deviceItem = new BackupDeviceItem(filePath, DeviceType.File);
        sqlRestore.Devices.Add(deviceItem);
        sqlRestore.Database = databaseName;

        DataTable dtFileList = sqlRestore.ReadFileList(sqlServer);

        int lastIndexOf = dtFileList.Rows[1][1].ToString().LastIndexOf(@"\");
        string physicalName = dtFileList.Rows[1][1].ToString().Substring(0, lastIndexOf + 1);
        string dbLogicalName = dtFileList.Rows[0][0].ToString();
        string dbPhysicalName = physicalName + databaseName + ".mdf";
        string logLogicalName = dtFileList.Rows[1][0].ToString();
        string logPhysicalName = physicalName + databaseName + "_log.ldf";
        sqlRestore.RelocateFiles.Add(new RelocateFile(dbLogicalName, dbPhysicalName));
        sqlRestore.RelocateFiles.Add(new RelocateFile(logLogicalName, logPhysicalName));

        sqlServer.KillAllProcesses(sqlRestore.Database);

        Database db = sqlServer.Databases[databaseName];
        if (db != null)
        {
            db.DatabaseOptions.UserAccess = DatabaseUserAccess.Single;
            db.Alter(TerminationClause.RollbackTransactionsImmediately);
            sqlServer.DetachDatabase(sqlRestore.Database, false);
        }

        sqlRestore.Action = RestoreActionType.Database;
        sqlRestore.ReplaceDatabase = true;

        sqlRestore.SqlRestore(sqlServer);
        db = sqlServer.Databases[databaseName];
        db.SetOnline();
        sqlServer.Refresh();
        db.DatabaseOptions.UserAccess = DatabaseUserAccess.Multiple;
    }

    public void Disconnect()
    {
        if (IsConnected)
            _connection.Disconnect();

        IsConnected = false;
    }
}
于 2014-01-28T16:26:39.857 回答
-3

我遇到了类似的问题,我发现这个解决方案很有帮助。

看看 - http://www.eggheadcafe.com/software/aspnet/32188436/smorestore-database-name-change.aspx

于 2010-11-23T21:34:53.167 回答