C#解压并恢复SQL SERVER备份到数据库

拿到一个财务系统的备份文件,是以MSS为后缀的,分析看一下,就是一个SQL SERVER的备份文件压缩包,恢复的话,先解压再恢复就好了,开发环境:VS2010,数据库SQL SERVER 2008 R2,相关界面设计如下图。

private bool restoreFile(string TargetFile, string dataBaseName, ref string msg)
        {            
            string rootFile = "";
            msg = "";            
            try
            {

               //读取压缩文件准备解压缩
                ZipInputStream inputstream = new ZipInputStream(File.OpenRead(TargetFile.Trim()));
                ZipEntry entry;
                string fileDir = Application.StartupPath + "\\temp\\";
                string path = fileDir;
                //解压出来的文件保存路径
                string rootDir = "";
                //根目录下的第一个子文件夹的名称                
                while ((entry = inputstream.GetNextEntry()) != null)
                {                    
                    rootDir = Path.GetDirectoryName(entry.Name);
                    //得到根目录下的第一级子文件夹的名称
                    if (rootDir.IndexOf("\\") >= 0)
                    {
                        rootDir = rootDir.Substring(0, rootDir.IndexOf("\\") + 1);
                    }
                    string dir = Path.GetDirectoryName(entry.Name);
                    //得到根目录下的第一级子文件夹下的子文件夹名称
                    string fileName = Path.GetFileName(entry.Name);
                    //根目录下的文件名称
                    if (dir != "")
                    {
                        //创建根目录下的子文件夹,不限制级别
                        if (!Directory.Exists(fileDir + "\\" + dir))
                        {
                            path = fileDir + "\\" + dir;
                            //在指定的路径创建文件夹
                            Directory.CreateDirectory(path);
                        }
                    }
                    else if (dir == "" && fileName != "")
                    {
                        //根目录下的文件
                        path = fileDir;
                        rootFile = fileName;
                    }
                    else if (dir != "" && fileName != "")
                    {
                        //根目录下的第一级子文件夹下的文件
                        if (dir.IndexOf("\\") > 0)
                        {
                            //指定文件保存路径
                            path = fileDir + "\\" + dir;
                        }
                    }
                    if (dir == rootDir)
                    {
                        //判断是不是需要保存在根目录下的文件
                        path = fileDir + "\\" + rootDir;
                    }

                    //解压 后缀为BAK的文件,其它不管
                    string fileSuffix = fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf("."));
                    if (fileName != String.Empty && fileSuffix.ToLower() == ".bak")
                    {
                        databaseBackupFilePath=path + "\\" + fileName;
                        FileStream fs = File.Create(databaseBackupFilePath);                        
                        byte[] data = new byte[2048];
                        int size = inputstream.Read(data, 0, data.Length);
                        while (size > 0)
                        {
                            fs.Write(data, 0, size);
                            size = inputstream.Read(data, 0, data.Length);                            
                        }
                        fs.Close();
                    }                   
                } //end while
                inputstream.Close();                
            }
            catch (Exception ex)
            {
                msg = "解压缩文件错误:"+ex.Message;
                return false;
            }
           
            if (databaseBackupFilePath == String.Empty)
            {
                msg = "文件解析错误:目标文件中没有找到数据库备份文件!";
                return false;
            }

            //数据库变量
            string strconn = "Data Source=" + shareInfo.HostIP + ";Initial Catalog=master;User ID=" + shareInfo.dbUser + ";pwd =" + shareInfo.dbPassword + "";            
            SqlConnection conn = new SqlConnection(strconn);
            SqlCommand cmd = null;
            SqlDataReader dr=null;
            DataTable dt = null;
            SqlDataAdapter adapter = null;
            string mdf = "", log = "", sql = "";

            //解析备份文件信息
            try
            {                
                sql = "restore  filelistonly from disk = '" + databaseBackupFilePath + "'";
                adapter = new SqlDataAdapter(sql, strconn);
                dt = new DataTable();
                lock (adapter)
                {
                    adapter.Fill(dt);
                }

                mdf = dt.Rows[0][0].ToString();
                log = dt.Rows[1][0].ToString();
            }
            catch (Exception ex)
            {
                msg = "备份文件解析错误:"+ex.Message;
                return false;
            }            
          
            //如果需要覆盖,则先删除已有数据库
            if (overWrite)
            {
                //断开所有和数据库相关的连接
                try
                {                   
                    conn.Open();
                    sql = "SELECT spid FROM sysprocesses ,sysdatabases WHERE sysprocesses.dbid=sysdatabases.dbid AND sysdatabases.Name='" + dataBaseName + "'";
                    cmd = new SqlCommand(sql, conn);
                    ArrayList list = new ArrayList();

                    dr = cmd.ExecuteReader();
                    while (dr.Read())
                    {
                        list.Add(dr.GetInt16(0));
                    }
                    dr.Close();
                    
                    for (int i = 0; i < list.Count; i++)
                    {                        
                        cmd = new SqlCommand(string.Format("KILL {0}", list[i].ToString()), conn);
                        cmd.ExecuteNonQuery();                                              
                    }
                }
                catch (SqlException eee)
                {
                    msg = "恢复文件错误:" + eee.ToString();
                    return false;
                }
                finally
                {
                    conn.Close();
                }               
                sql = string.Format("drop database {0}", dataBaseName);                                
                try
                {
                    conn.Open();
                    cmd = new SqlCommand(sql, conn);
                    cmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    msg = "删除数据库错误:"+ex.Message;
                    return false;
                }
                finally
                {
                    conn.Close();
                }
            }

            //开始恢复文件            
            try
            {                
                string dataDir = Application.StartupPath + "\\data\\";                
                sql = @"restore database {0} from disk = '{1}' with REPLACE, move '{2}' to '" + dataDir + "{3}.mdf',move '{4}' to '" + dataDir + "{5}.ldf'";
                string restore = string.Format(sql,dataBaseName,databaseBackupFilePath, mdf, dataBaseName, log, dataBaseName);                                
                conn.Open();
                cmd = new SqlCommand(restore, conn);
                cmd.CommandTimeout = 0;
                cmd.ExecuteNonQuery();

                //更改所有者
                cmd = new SqlCommand(restore, conn);
                dbHelper db = new dbHelper();
                db.ExecuteNonQuery(dataBaseName, "exec sp_msforeachtable 'sp_changeobjectowner ''?'', ''dbo'''");                
            }
            catch (Exception ex)
            {
                msg ="恢复数据错误:"+ ex.Message;
                return false;
            }
            finally
            {
                conn.Close();
            }

            //删除临时文件
            try
            {               
                string tempDir = Application.StartupPath + "\\temp\\";
                DirectoryInfo dir = new DirectoryInfo(tempDir);
                FileSystemInfo[] fileinfo = dir.GetFileSystemInfos();  //返回目录中所有文件和子目录
                foreach (FileSystemInfo i in fileinfo)
                {
                    if (i is DirectoryInfo)            //判断是否文件夹
                    {
                        DirectoryInfo subdir = new DirectoryInfo(i.FullName);
                        subdir.Delete(true);          //删除子目录和文件
                    }
                    else
                    {
                        File.Delete(i.FullName);      //删除指定文件
                    }
                }
            }
            catch (Exception e)
            {
                msg = "删除临时文件错误:" + e.Message;
                return false;
            }

            return true;
        }

步骤比较清晰,解压文件->解析文件->覆盖/不覆盖已有数据库->还原到指定名称数据库。

猜你喜欢

转载自blog.csdn.net/qq_42213965/article/details/88997869