【问题标题】:Setting single user mode to restore backup设置单用户模式以恢复备份
【发布时间】:2010-12-13 01:12:01
【问题描述】:

我有以下功能:

public void RestoreDatabase(String databaseName, String backUpFile, 
                            String serverName, String userName, String password)
{
    SqlConnection.ClearAllPools();
    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);
}

我试图先将数据库设置为单用户模式,然后再恢复备份。我试过这段代码:

        private string singleUserCmd = "alter database db-name set SINGLE_USER";
        private string multiUserCmd = "alter database db-name  set MULTI_USER";

        private void SetSingleUser(bool singleUser, 
                                   SqlConnectionStringBuilder csb)
        {
            string v;
            if (singleUser)
            {
                v = singleUserCmd.Replace("db-name", csb.InitialCatalog);
            }
            else
            {
                v = multiUserCmd.Replace("db-name", csb.InitialCatalog);
            }
            SqlCommand cmd = new SqlCommand(v, new SqlConnection
                                                     (csb.ToString()));
            try
            {
                cmd.Connection.Open();
                cmd.ExecuteNonQuery();
            }
            finally
            {
                cmd.Connection.Close();
            }
        }

问题似乎是单用户模式适用于该连接,从而阻止其他任何人做任何事情。我需要它用于恢复备份的连接。

【问题讨论】:

    标签: c# sql-server backup single-user


    【解决方案1】:

    需要在将数据库置于单用户模式的连接上进行恢复,所以为什么不让您的 SetSingleUser 函数返回它执行的打开的 SqlConnection,然后让您的恢复代码接受并使用相同的打开连接。

    private string singleUserCmd = "alter database db-name set SINGLE_USER";
    private string multiUserCmd = "alter database db-name  set MULTI_USER";
    
    private SqlConnection SetSingleUser(bool singleUser, SqlConnectionStringBuilder csb)
    {
        string v;
        if (singleUser)
        {
            v = singleUserCmd.Replace("db-name", csb.InitialCatalog);
        }
        else
        {
            v = multiUserCmd.Replace("db-name", csb.InitialCatalog);
        }
        SqlConnection connection = new SqlConnection(csb.ToString());
        SqlCommand cmd = new SqlCommand(v, connection);
    
            cmd.Connection.Open();
            cmd.ExecuteNonQuery();
    
        return connection;
    }
    

    【讨论】:

    • 喜欢这个答案,这正是我最终做的。我没有意识到您可以将打开的连接传递给 ServerConnection 构造函数。
    【解决方案2】:

    duckworth 的回答非常正确。但你也可以这样做:

    using System;
    using System.Data.SqlClient;
    using Microsoft.SqlServer.Management.Common;
    using Microsoft.SqlServer.Management.Smo;
    
    public class DatabaseRestoreHelper
    {
        private const string _SingleUserCmd = "ALTER DATABASE {0} SET SINGLE_USER WITH ROLLBACK IMMEDIATE";
        private const string _MultiUserCmd = "ALTER DATABASE {0} SET MULTI_USER";
    
        public static void RestoreDatabase(string connectionString, string backupSetPath, bool verify)
        {
            SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder(connectionString);
            string database = cb.InitialCatalog;
    
            cb.InitialCatalog = "master";
    
            SqlConnection sqlConnection = new SqlConnection(cb.ConnectionString);
            ServerConnection serverConnection = new ServerConnection(sqlConnection);
    
            try
            {
                //Make Database Single User
                serverConnection.ExecuteNonQuery(String.Format(_SingleUserCmd, database));
    
                Server server = new Server(serverConnection);
                Restore restore = new Restore();
    
                BackupDeviceItem destination = new BackupDeviceItem(backupSetPath, DeviceType.File);
    
                restore.Action = RestoreActionType.Database;
                restore.Database = database;
                restore.Devices.Add(destination);
                restore.ReplaceDatabase = true;
    
                if (verify)
                {
                    string errorMessage;
    
                    if (!restore.SqlVerify(server, out errorMessage))
                    {
                        throw new Exception(errorMessage);
                    }
                }
    
                restore.SqlRestore(server);
            }
            catch
            {
                throw;
            }
            finally
            {
                //Make Database Multi User
                serverConnection.ExecuteNonQuery(String.Format(_MultiUserCmd, database));
                serverConnection.Disconnect();
            }
        }
    
        public static void BackupDatabase(string connectionString, string backupSetPath, bool verify)
        {
            SqlConnectionStringBuilder cb = new SqlConnectionStringBuilder(connectionString);
            string database = cb.InitialCatalog;
    
            cb.InitialCatalog = "master";
    
            SqlConnection sqlConnection = new SqlConnection(cb.ConnectionString);
            ServerConnection serverConnection = new ServerConnection(sqlConnection);
    
            try
            {
                //Make Database Single User
                serverConnection.ExecuteNonQuery(String.Format(_SingleUserCmd, database));
    
                Server server = new Server(serverConnection);
                Backup backup = new Backup();
    
                BackupDeviceItem destination = new BackupDeviceItem(backupSetPath, DeviceType.File);
    
                backup.Action = BackupActionType.Database;
                backup.Database = database;
                backup.Devices.Add(destination);
                backup.SqlBackup(server);
    
                if (verify)
                {
                    Restore restore = new Restore();
    
                    restore.Action = RestoreActionType.Database;
                    restore.Database = database;
                    restore.Devices.Add(destination);
                    restore.ReplaceDatabase = true;
    
                    string errorMessage;
    
                    if (!restore.SqlVerify(server, out errorMessage))
                    {
                        throw new Exception(errorMessage);
                    }
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                //Make Database Multi User
                serverConnection.ExecuteNonQuery(String.Format(_MultiUserCmd, database));
                serverConnection.Disconnect();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-11
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 1970-01-01
      相关资源
      最近更新 更多