日期:2014-05-20  浏览次数:20968 次

分离正在运行的数据库
我在分离sqlexpress数据库是总是显示$exception {"无法分离 数据库'MSRPKJAData2006',因为它当前正在使用。"}。
应该怎么做?我的代码:
strMasterConn = "Data Source=.\\SQLExpress;Database=master;Integrated Security=True;Connect Timeout=10;User Instance=False";
  try
  {
  using (SqlConnection sqlConn = new SqlConnection(strMasterConn))
  {
  strSql = "SELECT name FROM sys.databases WHERE name='DatabaseName'";
  string strLogFileName = this.m_LocalDBFileName.ToLower().Replace(".mdf", "_log.ldf");
  SqlCommand sqlCmd = new SqlCommand(strSql, sqlConn);
  sqlConn.Open();
  object objValue = sqlCmd.ExecuteScalar();
  //如果数据库已经存在先将其分离或删除
  if (objValue != null && string.IsNullOrEmpty(objValue.ToString()) == false)
  {
  strSql = "SELECT state_desc FROM sys.databases WHERE name='DatabaseName'";
  sqlCmd.CommandText = strSql;
  objValue = sqlCmd.ExecuteScalar();
  if (objValue.ToString().ToUpper() == "RECOVERY_PENDING" || objValue.ToString().ToUpper() == "SUSPECT")
  strSql = "drop database " + "DatabaseName";
  else
  strSql = "sp_detach_db " + "DatabaseName";
  try
  {
  sqlCmd.CommandText = strSql;
  sqlCmd.ExecuteNonQuery();
  }
  catch (Exception)
  {
  }
  }
  //重新附加数据库
  strSql = "CREATE DATABASE DatabaseName ON (FILENAME='" + this.m_LocalDBFileName
  + "'),(FILENAME='" + strLogFileName + "') FOR ATTACH";
  sqlCmd.CommandText = strSql;
  sqlCmd.ExecuteNonQuery();
  sqlConn.Close();
  }

------解决方案--------------------
很简单,你先让数据库脱机,然后就可以分离了。
------解决方案--------------------
停止SQLSERVER服务
------解决方案--------------------
分离和恢复前都断开用户连接

Kill All Connection
------解决方案--------------------
获取独占访问权限

分离数据库需要对数据库有独占访问权限。如果要分离的数据库正在使用当中,则必须先将该数据库设置为 SINGLE_USER 模式以获取独占访问权限,然后才能对其进行分离。

例如,下面的 ALTER DATABASE 语句将在所有当前用户断开与 AdventureWorks 数据库的连接后获取对该数据库的独占访问权限。

USE master;
ALTER DATABASE AdventureWorks
SET SINGLE_USER;
GO

ms188031.note(zh-cn,SQL.100).gif注意:
若要强制当前用户即刻离开数据库或在指定的秒数内离开数据库,请外加使用 ROLLBACK 选项:ALTER DATABASE database_name SET SINGLE_USER WITH ROLLBACK rollback_option。有关详细信息,请参阅 ALTER DATABASE (Transact-SQL)。
------解决方案--------------------
USE master;
ALTER DATABASE AdventureWorks
SET SINGLE_USER
with ROLLBACK IMMEDIATE

就是在执行sp_detach之前先执行下类似这个语句的,强制把别的用户断开。

------解决方案--------------------
4楼的连接可以,是存贮过程.楼主可能没看清楚.
下面是我写的C#+SQL语句方式的.
C# code

internal static bool SqldbUserProcessKill(string sqlServerName, string sqlUserID, string sqlPWD, string dbName)    //强行关闭当前数据库的用户进程
{
    string sqlconstr = "";
    sqlconstr += "   USER ID     = " + sqlUserID;
    sqlconstr += " ; PWD         = " + sqlPWD;
    sqlconstr += " ; DATA SOURCE = " + sqlServerName;
    sqlconstr += " ; DATABASE    = master";
    using (SqlConnection sqlcon = new SqlConnection(sqlconstr))
    {
        try
        {
            sqlcon.Open();
            string cmtxt = "SELECT spid FROM master..sysprocesses WHERE dbid=db_id('" + dbName + "')";     //获取所有用户进程
            SqlDataAdapter sqlda = new SqlDataAdapter(cmtxt, sqlcon);
            DataTable dt = new DataTable();
            sqlda.Fill(dt);

            SqlCommand sqlcmd = new SqlCommand();
            sqlcmd.CommandType = CommandType.Text;
            sqlcmd.Connection = sqlcon;
            for (int i = 0; i <= dt.Rows.Count - 1; i++)
            {
                sqlcmd.CommandText = " KILL " + dt.Rows[i][0].ToString();                               //强行关闭用户进程
                sqlcmd.ExecuteNonQuery();
            }
        }
        catch (SqlException ex) { MessageBox.Show(ex.Message); return false; }
    }
    return true;
}