2016-07-25 68 views
0

我試圖用kill <spid>殺從C#Windows窗體在SQL Server 2012中的會話,但發生的事情是,當我這樣做,就會出現錯誤:如何殺死一個SQL Server會話或會話ID

無法使用殺來殺自己的進程

代碼:

// to do DB backup 
private void spid2_Click(object sender, EventArgs e) 
{ 
    string SQLDataBases; 
    SQLDataBases = "select @@spid "; 
    SQLDataBases += "BACKUP DATABASE School TO DISK = \'C:\\Program Files\\Microsoft SQL Server\\MSSQL11.MSSQLSERVER\\MSSQL\\Backup\\AdventureWorks333.BAK\' "; 
    string svr = "Server=" + localsrv + ";Initial Catalog=master;Integrated Security = SSPI;"; 

    SqlConnection cnBk = new SqlConnection(svr); 
    Command = new SqlCommand(SQLDataBases, cnBk); 
    Command.CommandText = SQLDataBases; 

    SqlDataAdapter da = new SqlDataAdapter(Command); 
    DataTable dtDatabases = new DataTable(); 

    try 
    { 
     cnBk.Open(); 
     da.Fill(dtDatabases); 
     label1.Text = dtDatabases.Rows[0][0].ToString(); 
    } 
    catch (Exception ex) 
    { 
     string s = ex.ToString(); 
     MessageBox.Show(s); 
     label1.Text = dtDatabases.Rows[0][0].ToString(); 
    } 
    finally 
    { 
     if (cnBk.State == ConnectionState.Open) 
     { 
      cnBk.Close(); 
      cnBk.Dispose();     
     } 
    } 
} 

// to kill backup session 
private void kill_Click(object sender, EventArgs e) 
{ 
    string SQLRestor; 

    SQLRestor = "Use master; kill " + label1.Text; 
    string svr = "Server=" + localsrv + ";Initial Catalog=master;Integrated Security = SSPI;"; 

    SqlConnection cnRestore = new SqlConnection(svr); 
    SqlCommand cmdBkUp = new SqlCommand(SQLRestor, cnRestore); 

    try 
    { 
     cnRestore.Open(); 
     cmdBkUp.ExecuteNonQuery(); 
    } 
    catch (Exception ex) 
    { 
     string s = ex.ToString(); 
    } 
    finally 
    { 
     if (cnRestore.State == ConnectionState.Open) 
     { 
      cnRestore.Close(); 
      cnRestore.Dispose(); 
     } 
    } 
} 
+4

所以,你必須[數據庫名爲'school'和你正在構建與字符串連接SQL命令(http://stackoverflow.com/q/332365/11683)... – GSerg

+0

可能的重複[c#sql處理什麼](http://stackoverflow.com/questions/1158665/c-sharp-sql-what-to-dispose) – GSerg

回答

0

「無法使用殺來殺自己的過程」是有原因的。如果您完成了會話,請關閉連接:SqlConnectionIDisposable,因此將其包裝在using() {}區塊中會在您完成使用後自動關閉它。這會將連接句柄返回到池中,並由SQL服務器客戶端組件決定是否將其保留以供後續連接使用或處置。 SQL Server會管理的流程生命週期,並殺死他們是一個管理選項的好工作,但沒有在正常運行的應用程序應該做的(除了少數的原因,看here

這就是說,回答的實際問題:要殺死進程A,您必須打開第二個連接B和KILL A的進程(SPID)。只要假設「一個SPID =一個連接=一個會話」就可以工作(對於所有當前的SQL服務器版本都爲true)。 此外,您的用戶需要ALTER ANY CONNECTION權限。這通常僅限於sysadmin和processadmin角色,並且您的應用程序不太可能在生產環境中具有此功能。

參考文獻:

http://www.sqlservercentral.com/Forums/Topic1503836-1292-1.aspx http://sqlserverplanet.com/dba/spid-what-is-it

1

始終使用 「使用」 一次性類(也收和處置),從來沒有在查詢串聯字符串,總是使用參數化查詢避免SQL注射。這是示例如何使用的SqlConnection,SqlDataAdapter的,和SqlCommand的:

var connectionString = "..."; 
    var sqlQuery = "..."; 

    // Sample using SqlCommand 
    try 
    { 
    using (var conn = new SqlConnection(connectionString)) 
    { 
     conn.Open(); 
     using (var cmd = new SqlCommand(sqlQuery, conn)) 
     { 
     cmd.ExecuteNonQuery(); 
     } 
    } 
    MessageBox.Show("OK, SqlConnection and SqlCommand are closed and disposed properly"); 
    } 
    catch (Exception ex) 
    { 
    MessageBox.Show("Error : " + ex); 
    } 

    // Sample using SqlDataAdapter 
    try 
    { 
    var dataTable = new DataTable(); 
    using (var conn = new SqlConnection(connectionString)) 
    { 
     conn.Open(); 
     using (var sda = new SqlDataAdapter(sqlQuery, conn)) 
     { 
     sda.Fill(dataTable); 
     } 
    } 
    MessageBox.Show("OK, SqlConnection and SqlDataAdapter are closed and disposed properly, use DataTable here..."); 
    } 
    catch (Exception ex) 
    { 
    MessageBox.Show("Error : " + ex); 
    }