C#如何检查数据库是否不忙?

时间:2015-10-05 19:08:00

标签: c# sql-server

我班上有几种方法。第一个是创建一个数据库,完成了。然后,创建从sql文件中读取的存储过程。然后分离那个DB。现在看来我的存储过程查询需要一段时间才能完成,并且在数据库繁忙时调用我的分离方法。那么我该如何判断数据库是否空闲。例外是“无法分离数据库,因为它当前正在使用”

方法:

void CreateStoredProcedures(string type)
        {
            string spLocation = File.ReadAllText("CreateStoredProcedures.sql");
            var conn = new SqlConnection(connectionString + ";database=" + type + DateTime.Now.ToString("yyyyMMdd"));            

            try
            {
                Server server = new Server(new ServerConnection(conn));
                server.ConnectionContext.ExecuteNonQuery(spLocation);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

bool DetachBackup(string type)
        {
            var conn = new SqlConnection(connectionString);
            SqlCommand command = new SqlCommand("", conn);
            command.CommandText = @"sys.sp_detach_db '" + type + DateTime.Now.ToString("yyyyMMdd") + "'";

            try
            {
                conn.Open();
                command.ExecuteNonQuery();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
            finally
            {
                if ((conn.State == ConnectionState.Open))
                {
                    conn.Close();
                }
            }
            return true;
        }

点击活动:

private void btnFullBackup_Click(object sender, EventArgs e)
        {
            lblStatus.Text = "Starting full backup...";
            Execute("FULL");
            progressBar.Value = 20;                       
            lblStatus.Text = "Copying tables...";
            progressBar.Value = 60;            
            CopyTables("FULL");
            progressBar.Value = 70;
            lblStatus.Text = "Creating stored procedures...";
            CreateStoredProcedures("FULL");

            progressBar.Value = 80;
            CheckDBSize(newBackupLocation, "FULL");

            progressBar.Value = 100;
            MessageBox.Show("Backup was created successfully", "",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);            

            lblStatus.Text = "Done";
            progressBar.Value = 0;

            if (DetachBackup("FULL") == false)
            {
                DetachBackup("FULL");
            }
        }

3 个答案:

答案 0 :(得分:2)

它可能会挂在自己的连接上。 sp_detach_db的MSDN https://msdn.microsoft.com/en-CA/library/ms188031.aspx在“获取独占访问权”一节中有以下建议:

USE master; 
ALTER DATABASE [DBName] SET SINGLE_USER;

您的DetachBackup方法将连接到master,运行ALTER和sp_detach_db过程。

答案 1 :(得分:1)

您没有在CreateStoredProcedures方法中关闭连接。像我在这里展示的那样使用语句,它应该解决问题。 (Brief using statement explanation from Microsoft.

为您的方法试用此代码:

    void CreateStoredProcedures(string type)
    {
        string spLocation = File.ReadAllText("CreateStoredProcedures.sql");
        using (var conn = new SqlConnection(connectionString + ";database=" + type + DateTime.Now.ToString("yyyyMMdd")))
        {
            try
            {
                Server server = new Server(new ServerConnection(conn));
                server.ConnectionContext.ExecuteNonQuery(spLocation);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        } // End of using, connection will always close when you reach this point.
    }

    bool DetachBackup(string type)
    {
        using (var conn = new SqlConnection(connectionString))
        {
            SqlCommand command = new SqlCommand(@"sys.sp_detach_db '" + type + DateTime.Now.ToString("yyyyMMdd") + "'", conn);

            try
            {
                conn.Open();
                command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
        } // End of using, connection will always close when you reach this point.
        return true;
    }

答案 2 :(得分:0)

您不应该将其视为数据库“忙碌”,但错误消息使用了良好的情况:正在使用中。要确定数据库当前是否正在使用,最准确的方法是通过查询sys.dm_tran_locks来查明特定数据库中是否有任何会话锁定。这是一个帮助函数,无论数据库是否正在使用,都返回bool

    bool IsDatabaseInUse(string databaseName)
    {
        using (SqlConnection sqlConnection = new SqlConnection("... your connection string ..."))
        using (SqlCommand sqlCmd = new SqlCommand())
        {
            sqlCmd.Connection = sqlConnection;
            sqlCmd.CommandText =
                @"select count(*)
                from sys.dm_tran_locks
                where resource_database_id = db_id(@database_name);";
            sqlCmd.Parameters.Add(new SqlParameter("@database_name", SqlDbType.NVarChar, 128)
            {
                Value = databaseName
            });

            sqlConnection.Open();
            int sessionCount = Convert.ToInt32(sqlCmd.ExecuteScalar());

            if (sessionCount > 0)
                return true;
            else
                return false;
        }
    }

注意:确保连接字符串中的初始目录不是您尝试“未使用”的数据库,因为这会将您当前的会话置于数据库的上下文中,而不是允许该操作完成