分离正在运行的数据库
我在分离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;
}