简体   繁体   English

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

[英]How to kill a SQL Server session or session ID

I'm trying to kill a session in SQL Server 2012 from C# windows Form using kill <spid> but what happens is that when I do that, an error appears: 我正在尝试使用kill <spid>从C#Windows Form kill <spid> SQL Server 2012中的会话,但是发生的是,当我这样做时,出现错误:

Cannot use KILL to kill your own process 无法使用KILL杀死自己的进程

Code: 码:

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

Always use "using" for disposable classes (also to close and dispose), never concatenate string in query , use always parameterized query to avoid sql injection. 始终对一次性类使用“ using”(也用于关闭和处置), 不要在查询中连接字符串 ,请始终使用参数化查询以避免sql注入。 This is sample how to use SqlConnection, SqlDataAdapter, and SqlCommand : 这是如何使用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);
  }

The "Cannot use KILL to kill your own process" is there for a reason. 出现“无法使用KILL杀死自己的进程”是有原因的。 If you're finished using your session, close the connection: SqlConnection is an IDisposable , so wrapping it in an using() {} block will close it automatically when you're done using it. 如果您已完成会话的使用,请关闭连接: SqlConnection是一个IDisposable ,因此将其包装在using() {}块中后,将在using() {}完毕后自动将其关闭。 This will return the connection handle back to the pool, and it is up to the SQL server client components to decide whether to keep it around for follow-up connections, or dispose it. 这会将连接句柄返回到池中,并且由SQL Server客户端组件决定是否保留它以进行后续连接,还是将其处置。 SQL server does a good job of managing its process lifecycle and killing them is an administrative option, but nothing that an application in normal operation should do (except for a few reasons, see here ) SQL Server在管理其进程生命周期方面表现出色,并且杀死它们是一个管理选项,但是处于正常运行状态的应用程序不应该执行任何操作(出于某些原因,请参见此处

That said, to answer the actual question: to kill process A, you'd have to open a second connection B and KILL A's process (SPID). 也就是说,要回答实际问题:要杀死进程A,您必须打开第二个连接B和KILL A的进程(SPID)。 This will work as long as the assumption "one SPID = one connection = one session" holds (true for all current SQL server versions). 只要假设“一个SPID =一个连接=一个会话”成立(对于所有当前SQL Server版本为true),这将起作用。 Furthermore, your user needs the ALTER ANY CONNECTION privilege. 此外,您的用户需要ALTER ANY CONNECTION特权。 This is usually limited to sysadmin and processadmin roles, and your application is unlikely to have this in a production environment. 这通常仅限于sysadmin和processadmin角色,并且您的应用程序不太可能在生产环境中具有此角色。

References: 参考文献:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM