C#数据库备份及还原

    1.在用户的配置时,我们需要列出当前局域网内所有的数据库服务器,并且要列出指定服务器的所有数据库,实现代码如下:

    取得数据库服务器列表:

1. public
2. {   
3. ArrayList alServers = new
4. SQLDMO.Application sqlApp = new
5. try
6. {   
7. SQLDMO.NameList serverList = sqlApp.ListAvailableSQLServers() ;   
8. for(int
9. {   
10. alServers.Add(serverList.Item(i)) ;   
11. }   
12. }   
13. catch(Exception e)   
14. {   
15. throw(new Exception("取数据库服务器列表出错:"+e.Message)) ;   
16. }   
17. finally
18. {   
19. sqlApp.Quit() ;   
20. }   
21. return
22. }
取得指定数据库服务器的数据库列表
1. public ArrayList GetDbList(string strServerName,string strUserName,string
2. {   
3. ServerName = strServerName ;   
4. UserName = strUserName ;   
5. Password = strPwd ;   
6.  
7. ArrayList alDbs = new
8. SQLDMO.Application sqlApp = new
9. SQLDMO.SQLServer svr = new
10. try
11. {   
12. svr.Connect(ServerName,UserName,Password) ;   
13. foreach(SQLDMO.Database db in
14. {   
15. if(db.Name!=null)   
16. alDbs.Add(db.Name) ;   
17. }   
18. }   
19. catch(Exception e)   
20. {   
21. throw(new Exception("连接数据库出错:"+e.Message)) ;   
22. }   
23. finally
24. {   
25. svr.DisConnect() ;   
26. sqlApp.Quit() ;   
27. }   
28. return
29. }

    2.数据库的备份和实时进度显示代码: 

1. public bool BackUPDB(string strDbName,string strFileName, ProgressBar pgbMain)   
2. {   
3. PBar = pgbMain
4. SQLDMO.SQLServer svr = new
5. try   
6. {   
7. svr.Connect(ServerName,UserName,Password) ;   
8. SQLDMO.Backup bak = new
9. bak.Action = 0
10. bak.Initialize = true
11. SQLDMO.BackupSink_PercentCompleteEventHandler pceh
12. new
13. bak.PercentComplete += pceh;   
14. bak.Files = strFileName;   
15. bak.Database = strDbName;   
16. bak.SQLBackup(svr);   
17. return true ;   
18. }   
19. catch(Exception err)   
20. {   
21. throw(new Exception("备份数据库失败"+err.Message)) ;   
22. }   
23. finally   
24. {   
25. svr.DisConnect() ;   
26. }   
27. }   
28.  
29. private void Step(string message,int percent)   
30. {   
31. PBar.Value = percent
32. }

    其中,这两个语句实现了进度的实时显示:

    SQLDMO.BackupSink_PercentCompleteEventHandler pceh = new     SQLDMO.BackupSink_PercentCompleteEventHandler(Step); 
    bak.PercentComplete += pceh;

    Step就是上面private void Step(string message,int percent) 的方法名称,它用来显示进度条的当前进度。

    3.数据库的恢复和杀死进程的代码:

1. public bool RestoreDB(string strDbName,string
2. {   
3. PBar = pgbMain ;   
4. SQLDMO.SQLServer svr = new
5. try
6. {   
7. svr.Connect(ServerName,UserName,Password) ;   
8. SQLDMO.QueryResults qr = svr.EnumProcesses(-1) ;   
9. int
10. int
11. for(int
12. {   
13. string
14. if (strName.ToUpper().Trim() == "SPID")   
15. {   
16. iColPIDNum = i ;   
17. }   
18. else if (strName.ToUpper().Trim() == "DBNAME")   
19. {   
20. iColDbName = i ;   
21. }   
22. if
23. break
24. }   
25.  
26. for(int
27. {   
28. int
29. string
30. if
31. svr.KillProcess(lPID) ;   
32. }   
33.  
34. SQLDMO.Restore res = new
35. res.Action = 0 ;   
36. SQLDMO.RestoreSink_PercentCompleteEventHandler pceh = 
37. new
38. res.PercentComplete += pceh;   
39. res.Files = strFileName ;   
40.  
41. res.Database = strDbName ;   
42. res.ReplaceDatabase = true
43. res.SQLRestore(svr) ;   
44. return true
45. }   
46. catch(Exception err)   
47. {   
48. throw(new Exception("恢复数据库失败,请关闭所有和该数据库连接的程序!"+err.Message)) ;   
49. }   
50. finally
51. {   
52. svr.DisConnect() ;   
53. }   
54. }

    其中这个语句取得了所有的进程列表:

    SQLDMO.QueryResults qr = svr.EnumProcesses(-1) ;

    下面的语句找到和要恢复数据库相关的进程并杀死:

1. int
2. int
3. for(int
4. {   
5. string
6. if (strName.ToUpper().Trim() == "SPID")   
7. {   
8. iColPIDNum = i ;   
9. }   
10. else if (strName.ToUpper().Trim() == "DBNAME")   
11. {   
12. iColDbName = i ;   
13. }   
14. if
15. break
16. }   
17.  
18. for(int
19. {   
20. int
21. string
22. if
23. svr.KillProcess(lPID) ;   
24. }

    C#数据库备份及还原就介绍到这里,希望对你有所帮助。

 

 

/////////////////////////////////////////////////////

 利用C#还原数据库(SQL SERVER)备份文件到指定路径

利用C#还原数据库(SQL SERVER)备份文件到指定路径

 

摘要:   最近在做一个数据采集模块,遇到这样一个场景,就是需要将数据库备份文件还原到指定数据库实例下再采集数据。本机测试都没有问题,可一拿到真实环境中测试却发现了一个很大的Bug。所有的数据库都还原不上,很纠 ...

 

 

  最近在做一个数据采集模块,遇到这样一个场景,就是需要将数据库备份文件还原到指定数据库实例下再采集数据。本机测试都没有问题,可一拿到真实环境中测试却发现了一个很大的Bug。所有的数据库都还原不上,很纠结。因为我本以为SQL SERVER 会还原到默认路径下,其实不然。

  当我拿到真实数据库备份文件时,我首先在数据库中运行 restore database RestoreDbName from disk ='H:\DBFolder\Db_Back' ,执行结果如下:

 


  到现在我依然不知道是怎么回事,因为我自己创建的数据库再还原是好使的。怎么会这样?一个意外让我发现原来我建的数据库是在数据库实例默认的路径下,而真实数据库备份文件则不是,它的路径是客户机器上的,肯定不一样。为了验证这个发现,我做了如下的工作。

       第一步:创建数据库,create database TestDb 。

       第二步:备份数据库。

       第三步:直接还原数据库,restore database RestoreDbName from disk ='I:\TestDatabase'  ,执行成功。

       第四步:还原数据库,这时候我不是采用默认还原,而是将数据库还原到系统的另一个路径下,代码如下: 


restore database RestoreDbName from disk ='I:\TestDatabase'   with  replace, move 'TestDb' to 'H:\DBFolder\RestoreDbName_Data.mdf', move 'TestDb_log' to 'H:\DBFolder\RestoreDbName_Log.ldf'


   执行结果:

  第五步:再次备份数据库RestoreDbName。备份后我们用 filelistonly 可以看到当前数据库备份文件的备份路径( restore filelistonly from disk = 'I:\RestoreDb' ), 执行后结果如下:

  从这里我们可以看到当前数据库备份文件的真实物理路径。

     第六步:当我再次执行 restore database RestoreDbName from disk ='I:\RestoreDb' ,执行错误。出现了和真实环境一样的错误。原来如上文所述那样,数据库备份文件在还原时,如果当前数据库实例的默认路径和数据库备份文件不相符时需要通过move来解决,而不能单纯的 Restore。

 

     于是我又重新写了一下数据库备份文件还原的相关方法,如下所示。通过这个方法就能简单的实现数据库备份文件还原了。

View Code


/// <summary>
/// 还原数据库文件
/// </summary>
/// <param name="basePath">电子账簿所在根目录</param>
/// <param name="fileName">数据库备份文件名称</param>
/// <param name="databaseName">需要还原的数据库名称</param>
/// <param name="conn">数据库连接</param>
        private bool RestoreDataBase(string basePath, string fileName, string databaseName, SqlConnection conn)
        {
            SqlCommand command = null;
try
            {
string restoreStr = string.Empty;
string getLogicFileName = string.Format("restore   filelistonly   from   disk    ='{0}'", Path.Combine(basePath, fileName));
                DataSet ds = new DataSet();
                SqlDataAdapter da = new SqlDataAdapter(getLogicFileName, conn);
                da.Fill(ds);
if (ds.Tables == null || ds.Tables[0].Rows.Count == 0) return false;

foreach (DataRow dr in ds.Tables[0].Rows)
                {
//查找数据库逻辑文件名称
                    if ("D".Equals(dr["Type"].ToString()))
                        restoreStr += string.Format("move '{0}' to '{1}',", dr["LogicalName"].ToString(), Path.Combine(basePath, databaseName) + "_Data.mdf");
//查找数据库日志文件名称
                    else if ("L".Equals(dr["Type"].ToString()))
                        restoreStr += string.Format("move '{0}' to '{1}',", dr["LogicalName"].ToString(), Path.Combine(basePath, databaseName) + "_Log.ldf");
                }
if (string.IsNullOrEmpty(restoreStr))
                    restoreStr = string.Format("restore   database  {0}   from   disk    ='{1}'", databaseName, Path.Combine(basePath, fileName));
else
                {
                    restoreStr = string.Format("restore   database  {0}   from   disk    ='{1}' with replace,", databaseName, Path.Combine(basePath, fileName)) + restoreStr.TrimEnd(',');
                }
                command = new SqlCommand(restoreStr, conn);
                conn.Open();
                command.ExecuteNonQuery();
return true;
            }
catch (Exception ex)
            {
return false;
            }
finally
            {
                conn.Close();
            }
        }



/// <summary>
/// 还原数据库文件
/// </summary>
/// <param name="basePath">电子账簿所在根目录</param>
/// <param name="fileName">数据库备份文件名称</param>
/// <param name="databaseName">需要还原的数据库名称</param>
/// <param name="conn">数据库连接</param>
        private bool RestoreDataBase(string basePath, string fileName, string databaseName, SqlConnection conn)
        {
            SqlCommand command = null;
try
            {
string restoreStr = string.Empty;
string getLogicFileName = string.Format("restore   filelistonly   from   disk    ='{0}'", Path.Combine(basePath, fileName));
                DataSet ds = new DataSet();
                SqlDataAdapter da = new SqlDataAdapter(getLogicFileName, conn);
                da.Fill(ds);
if (ds.Tables == null || ds.Tables[0].Rows.Count == 0) return false;

foreach (DataRow dr in ds.Tables[0].Rows)
                {
//查找数据库逻辑文件名称
                    if ("D".Equals(dr["Type"].ToString()))
                        restoreStr += string.Format("move '{0}' to '{1}',", dr["LogicalName"].ToString(), Path.Combine(basePath, databaseName) + "_Data.mdf");
//查找数据库日志文件名称
                    else if ("L".Equals(dr["Type"].ToString()))
                        restoreStr += string.Format("move '{0}' to '{1}',", dr["LogicalName"].ToString(), Path.Combine(basePath, databaseName) + "_Log.ldf");
                }
if (string.IsNullOrEmpty(restoreStr))
                    restoreStr = string.Format("restore   database  {0}   from   disk    ='{1}'", databaseName, Path.Combine(basePath, fileName));
else
                {
                    restoreStr = string.Format("restore   database  {0}   from   disk    ='{1}' with replace,", databaseName, Path.Combine(basePath, fileName)) + restoreStr.TrimEnd(',');
                }
                command = new SqlCommand(restoreStr, conn);
                conn.Open();
                command.ExecuteNonQuery();
return true;
            }
catch (Exception ex)
            {
return false;
            }
finally
            {
                conn.Close();
            }
        }