2015-10-05 66 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

這並不總是如此,你不能依賴數據庫的假設。 –