如何终止SQL Server会话或会话ID

时间:2016-07-25 07:59:54

标签: c# sql-server winforms kill-process

我试图使用kill <spid>从C#windows窗体中杀死SQL Server 2012中的会话但是当我这样做时会出现错误:

  

无法使用KILL杀死您自己的进程

代码:

// 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();
        }
    }
}

2 个答案:

答案 0 :(得分:1)

始终使用&#34;使用&#34;对于一次性类(也是关闭和处理),从不在查询中连接字符串,使用参数化查询来避免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);
  }

答案 1 :(得分:0)

“不能使用KILL杀死你自己的进程”是有原因的。如果您已完成会话,请关闭连接:SqlConnectionIDisposable,因此将其包装在using() {}块中会在您完成使用后自动将其关闭。这将把连接句柄返回到池中,由SQL服务器客户端组件来决定是否保留它以进行后续连接,或者将其丢弃。 SQL服务器在管理其进程生命周期方面做得很好并且杀死它们是一个管理选项,但正常操作中的应用程序不应该做任何事情(除了一些原因,请参阅here

那就是说,要回答实际问题:要杀死进程A,你必须打开第二个连接B和KILL A的进程(SPID)。只要假设“一个SPID =一个连接=一个会话”成立(对于所有当前SQL Server版本都是如此),这将起作用。 此外,您的用户需要ALTER ANY CONNECTION权限。这通常仅限于sysadmin和processadmin角色,您的应用程序不太可能在生产环境中具有此功能。

参考文献:

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