【问题标题】:How to kill a SQL Server session or session ID如何终止 SQL Server 会话或会话 ID
【发布时间】:2016-07-25 07:59:53
【问题描述】:

我正在尝试使用 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();
        }
    }
}

【问题讨论】:

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


【解决方案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);
  }

【讨论】:

    【解决方案2】:

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

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

    参考资料:

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

    【讨论】:

      猜你喜欢
      • 2011-07-16
      • 2013-08-29
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      • 1970-01-01
      • 2013-12-19
      相关资源
      最近更新 更多