2015-10-05 42 views
3

我的课有两种方法。第一个是创建一个数据库,完成了。然后,创建正在从sql文件读取的存储过程。然后分离该数据库。现在看来,我的存储过程查询需要一段时间才能完成,并且我的分离方法在数据库繁忙时被调用。那么如何判断数据库是否空闲呢?唯一的例外云C#如何检查数据库是否不忙?

方法“因为它正在使用中不能分离数据库”:

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

Click事件:

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"); 
      } 
     } 
+0

首先,对所有连接使用(var conn = new SqlConnection ...){''。 – rene

+0

@rene这是指出。 –

+0

好的,它有帮助吗? – rene

回答

0

你不应该把它看成数据库是“忙“,但错误消息使用良好的verbage:正在使用。要确定数据库当前是否正在使用,最准确的方法是查询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; 
     } 
    } 

注:请确保您的初始目录的连接字符串中是不是你正在努力使“不是数据库在使用中“,因为这会将当前会话置于数据库的上下文中,不允许该操作完成

+0

接下来如果OP运行这个,它返回'true'? – rene

+0

@Orene OP将不得不决定要做什么。这里的有效选项是1)等到轮询不再使用它,或者2)终止当前在数据库中有锁的会话。 –

+0

我可能会杀死会议。 –

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; 
    } 
+0

我有我的分离方法与create stored proc方法分开。 –

+0

@JoshuaMasangcay不知道我是否理解那条评论。这个答案也包含两种方法? – rene

+0

不幸的是,这种方法没有解决问题。尝试运行detach方法时,它仍显示数据库繁忙。 –

2

机会是它越来越挂在自己的连接。 sp_detach_db的MSDN https://msdn.microsoft.com/en-CA/library/ms188031.aspx有部分下以下建议获得专门的访问:

USE master; 
ALTER DATABASE [DBName] SET SINGLE_USER; 

你DetachBackup方法已经连接到主,运行ALTER和sp_detach_db过程。

+0

这并不总是如此,你不能依赖数据库的假设。 –