您的位置:首页 > 数据库

SQL server 2000数据还原小小经验谈

2006-06-13 13:34 579 查看
RESTORE DATABASE  DatabaseName 
                   FROM Filename
                   WITH RESTARTE
是最基本的数据库还原命令,可是执行的时候多半会出现错误提示:“为数据库正在使用,所以未能获得对数据库的排它访问权。”,数据库正在使用的解决办法很简单,就是进行还原操作时,连接的数据库为“Master”就好。但是接下来的问题是“排它访问权”。SQL Server 对现有数据库进行还原时需要切断现有的连接,即杀掉所有连接该数据库的进程。
         首先,获取所用连接该数据库的进程(strDBName 为要还原的数据库名称):
 SELECT spid FROM master..sysprocesses WHERE dbid=db_id('" + strDBName + "')
得到的便是SPID数据集,取得每个spid, 在利用 Kill   spid  命令就可以杀掉所有连接进程 ,然后执行还原语句。
在实际的应用中,可以结合开发语言特点进行编程实现。下面是我用C#做的




//TODO: 以程序的方式实现关闭当前连接数据库的连接进程




  /**//// <summary>


  /// 关闭当前连接数据库的连接进程


  /// </summary>


  /// <param name="DBName">要关闭进程的数据库名称</param>


  private void KillSPID(string DBName)




  

{


   string strDBName = DBName ;


   string strSQL = String.Empty ,strSQLKill = String.Empty;


    //因为DataReader独占连接,本程序需要两个Connection,并且连接的数据库是master,所以要初始化新的连接字符串


   string tmpConnectionString = "server=(local);uid=sa;pwd=;database=master" ;


   


   try




   

{


    SqlConnection TmpConn = new SqlConnection();


    SqlConnection conn = new SqlConnection() ;


    TmpConn.ConnectionString = tmpConnectionString;


    conn.ConnectionString = tmpConnectionString;


    TmpConn.Open();


    conn.Open();


   


    //读取连接当前数据库的进程


    strSQL = "select spid from master..sysprocesses where dbid=db_id('" + strDBName + "')";


    SqlCommand mycmd = new SqlCommand( strSQL, TmpConn);


    SqlDataReader mydr = mycmd.ExecuteReader() ;


   


    //开取杀进程的数据连接


    SqlCommand mycmd1 = new SqlCommand();


    mycmd1.Connection = conn ;


            


    while (mydr.Read())




    

{


     strSQLKill = "kill " + mydr["spid"].ToString();


     mycmd1.CommandText = strSQLKill ;


     mycmd1.CommandType = CommandType.Text ;


     mycmd1.ExecuteNonQuery(); //杀进程


    }


    mydr.Close();


    TmpConn.Close();
        conn.Close();


   }


   catch (Exception Err)




   

{


    MessageBox.Show(Err.Message );


   }


  }
 

有个随SQL Server一起发布的组件SQLDMO,使用它可以轻松实现数据库备份与还原,而且还提供带进度的事件,但这个COM中的参数Files不支持长文件名,就是说带有空格的文件名将会抛出异常,只有调用系统API进行转换方可解决。


[DllImport("kernel32")]


        public static extern int GetShortPathName(string path, StringBuilder shortPath,int shortPathLength);


private void DBRestore()






{
string strRestoreFileName = String.Empty ; //要还原的数据文件包含路径的全名
  
   fBDRestore.ShowDialog();
   
   strRestoreFileName = fBDRestore.FileName; //获得要还原的数据文件名称
  
   if (g_strRestoreFileName .Length == 0 ) //是否选取路径
   {
    return ;
   }


SQLDMO.SQLServer  m_Svr = new SQLDMO.SQLServerClass();


m_Svr.Connect("(local)","sa",  strPassword) ;//连接服务器


if ( m_Svr.Status == SQLDMO.SQLDMO_SVCSTATUS_TYPE.SQLDMOSvc_Running )//连接是否成功






{
    SQLDMO.Restore m_Restore = new SQLDMO.RestoreClass();
//带进度条事件
    SQLDMO.RestoreSink_PercentCompleteEventHandler pceh =new SQLDMO.RestoreSink_PercentCompleteEventHandler(Step);
    m_Restore.PercentComplete += pceh ;
    m_Restore.Action = SQLDMO.SQLDMO_RESTORE_TYPE.SQLDMORestore_Database ;
     StringBuilder strRestoreFileNameShort=new StringBuilder(255);
   GetShortPathName(strRestoreFileName, strRestoreFileNameShort,255); //转换成短文件名
   strRestoreFileName=strBackupFileNameShort.ToString();
    m_Restore.Files = strRestoreFileName;    
    m_Restore.Database = "test";//要还原的数据库名称
     m_Restore.ReplaceDatabase = true;
    m_Restore.Restart = true ;
    m_Restore.SQLRestore( m_Svr) ;


           }
        else
{
MessageBox.Show("密码错误","提示", MessageBoxButtons.OK, MessageBoxIcon.Information );
return ; //密码错误,退出
}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息