【问题标题】:Backup and Restore SQL Database备份和恢复 SQL 数据库
【发布时间】:2012-02-22 21:26:56
【问题描述】:

我需要将 SQL 2005 数据库备份(使用 C#)到 *.bak 文件。我正在尝试从该文件恢复到同一台服务器上的新数据库。

备份工作正常,然后我的 C# 代码调用 restore 方法,它似乎一直在工作,直到它最终“超时”。我检查了“innerExceptions”,他们发现 RESTORE 达到了 90%,然后返回了异常。

以下是我用于备份和恢复的代码。

有人可以告诉我哪里出错了吗?它必须是我可以设置的超时参数,但我不知道它是什么或如何做。

public class JRBackupRestoreDB
{
    public static void BackupDatabase(String databaseName, String userName, String password, String serverName, String destinationPath)
    {
        Backup sqlBackup = new Backup();

        sqlBackup.Action = BackupActionType.Database;
        sqlBackup.BackupSetDescription = "ArchiveDataBase:" + DateTime.Now.ToShortDateString();
        sqlBackup.BackupSetName = "Archive";

        sqlBackup.Database = databaseName;

        BackupDeviceItem deviceItem = new BackupDeviceItem(destinationPath, DeviceType.File);
        ServerConnection connection = new ServerConnection(serverName, userName, password);
        Server sqlServer = new Server(connection);

        Database db = sqlServer.Databases[databaseName];

        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.FormatMedia = false;

        sqlBackup.SqlBackup(sqlServer);
    }

    public static void RestoreDatabase(String databaseName, String filePath,
    String serverName, String userName, String password,
    String dataFilePath, String logFilePath)
    {
        Restore sqlRestore = new Restore();

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

        ServerConnection connection = new ServerConnection(serverName, userName, password);
        Server sqlServer = new Server(connection);

        Database db = sqlServer.Databases[databaseName];
        sqlRestore.Action = RestoreActionType.Database;
        String dataFileLocation = dataFilePath + databaseName + ".mdf";
        String logFileLocation = logFilePath + databaseName + "_Log.ldf";
        db = sqlServer.Databases[databaseName];
        RelocateFile rf = new RelocateFile(databaseName, dataFileLocation);

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

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

}

【问题讨论】:

  • 如果你想恢复到完全相同的服务器上的数据库,你可以创建一个存储过程,传递 mdf 和 ldf 路径。
  • 我已经尝试添加超时参数并现在尝试。存储过程的性能会更高效吗?

标签: c# sql-server-2005 smo


【解决方案1】:

您是否尝试过使用ServerConnection.StatementTimeout 设置一个值,看看会发生什么?

MSDN 参考here

【讨论】:

  • 我现在正在尝试 StatementTimeout 连接。这需要一些时间。说到这里......克里斯提到的存储过程会在这种情况下表现更好吗?
【解决方案2】:

这在普通的 sql 中非常容易做到......

您是否考虑过那样尝试?您只需要编写 sql 脚本或过程来执行此操作,然后运行它。这就是我们所做的(针对不同的情况,但类似):

backup database {{DATABASE NAME HERE}}
to disk = N'{{FILE_NAME_HERE}}'
    with
        name = N'{{BACKUP_DATABASE_NAME_HERE}}'
GO

restore database {{NEW_DATABASE_NAME}}
from disk = N'{{FILE_NAME_HERE}}'
    with
        file = 1
go

【讨论】:

  • 也很有帮助。由于我使用我的 C 类使其工作,因此仅调用存储过程会更好吗?
  • @dellbingham 我会用另一种方式问这个问题 - 通过在 C# 代码中抽象 SQL 命令可以获得什么?在我工作过/咨询过的每一家商店,应用程序代码都充当调用存储过程的管道,而不是替代 T-SQL 和 DDL。
  • @dellbingham 找出哪个性能更好的最佳方法是尝试两种方法。 (不是一个完美的衡量标准,但System.Diagnostic.Stopwatch 是一个很棒的工具)。如果有帮助 +1 ;)
猜你喜欢
  • 2011-12-10
  • 1970-01-01
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多