设置单用户模式恢复备份

发布于 2024-08-09 21:24:56 字数 1826 浏览 3 评论 0原文

我有以下功能:

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

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

I have the following function:

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

I was trying to set the DB to single user mode first, before restoring the backup. I tried this code:

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

The problem seems to be that single user mode is for that connection, preventing anyone else from doing anything. I need it to be for the connection that restores the backup.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

垂暮老矣 2024-08-16 21:24:56

恢复需要在将数据库置于单用户模式的连接上进行,所以为什么不让 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;
}

The restore would need to occur on the connection which placed the DB into single user mode, so why not make your SetSingleUser function return the opened SqlConnection it executed on and then have your Restore code take in and use the same opened connection.

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;
}
指尖凝香 2024-08-16 21:24:56

达克沃斯的回答是非常正确的。但你也可以这样做:

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

duckworth's answer is quite correct. but you can also do it in this way:

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();
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文