2016-07-25 118 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); 
    }