远程数据库备份到本地(本地无数据库)

时间:2024-11-07 16:51:15

最近查了一下网上远程备份数据库的方法,好像还是个挺麻烦的事情。但是项目里必须加入这个模块,所以也只有死磕出一个了。最后总结出2个方案:

第一种方案,是我个人比较喜欢的方案:

首先用SqlDataAdapter将所有表加载到DataSet中,用DataSet类的写入XML方法,将所有的信息全部写入到XML中。

需要还原的时候,首先用SqlDataAdapter去查询加载数据库的内容,然后再读取DataSet,最后用SqlDataAdapter的update()就行了。

具体代码就不写了,这种方法很简单,用起来也方便。

 

 

第二种方案,是真正的备份数据库文件。

我们都知道,直接远程备份数据库并没有什么问题,但是备份文件只能在服务器上,通过什么传送到客户端是个难点。但是数据库有个功能是cmdshell,可以通过它向数据库所在的服务器发送DOS命令,直接操作服务器。呵呵,是不是很有黑客的味道?但是这种做法并不难,可以完全通过SQL语句来完成。

 

1.首先需要开启数据库的cmdshell功能:

EXEC sp_configure 'show advanced options', 1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell', 1;RECONFIGURE;

好了,现在我们已经完全控制了服务器。如果服务器的登录用户名不允许操作服务器,你可以新建用户,提升权限

exec   xp_cmdshell 'net user mm 123 /add' --添加一用户
exec xp_cmdshell 'net localgroup administrators mm /add' --为用户添加管理员权限

 

2.在客户端建立一个共享文件夹。

3.服务器建立到共享文件夹的映射。

exec master..xp_cmdshell 'net use z: //客户端IP/共享文件夹的共享名 "客户端的WINDOWS登录密码" /user:服务器IP/客户端的WINDOWS用户名'

Z,就是映射名。如果不知道什么是映射,可以自己试着建一个。右键我的电脑,映射网络驱动器。随便映射到某个共享文件夹。这样在我的电脑里面,就会多一个"Z盘",进去后直接就是这个共享文件夹了。需要注意的是,这里涉及到一些网络方面的知识,比如你和服务器不在同一个域,建映射可能就会出问题。而数据库给你的提示总是很奇怪的,比如什么错误的用户名。

 

4.备份服务器上的数据库  with init覆盖 ¦ noinit添加

backup database 库名 to disk='C:/备份文件名.bak' with init

 

5.将备份文件拷贝到映射盘

exec master..xp_cmdshell 'copy C:/备份文件名.bak z:'

 

6.清除痕迹(黑客来过了,当然要清理痕迹啦)

--exec master..xp_cmdshell 'del C:/备份文件名.bak'   删除备份文件

--exec master..xp_cmdshell 'net use z: /delete'       删除映射

 

注意点:
需要注意的是,如果建立映射失败,或者删除映射失败,数据库只是返回一个失败原因,对于程序来说依然算“得到查询结果”,而不是返回异常。所以在用C#写代码的时候,不要用catch去捕获失败的操作。而是因为根据返回结果的值来判断。

 

 

再附上设置本地文件夹为共享的代码:

/// <summary>
        /// 设置文件夹共享
        /// </summary>
        /// <param name="FolderPath">文件夹路径</param>
        /// <param name="ShareName">共享名</param>
        /// <param name="Description">共享注释</param>
        /// <returns></returns>
        public int ShareNetFolder(string FolderPath, string ShareName, string Description)
        {

            try
            {
                ManagementClass managementClass = new ManagementClass("Win32_Share");
                // Create ManagementBaseObjects for in and out parameters
                ManagementBaseObject inParams = ("Create");
                ManagementBaseObject outParams;
                // Set the input parameters
                inParams["Description"] = Description;
                inParams["Name"] = ShareName;
                inParams["Path"] = FolderPath;
                inParams["Type"] = 0x0; // Disk Drive
                //Another Type:
                //        DISK_DRIVE = 0x0
                //        PRINT_QUEUE = 0x1
                //        DEVICE = 0x2
                //        IPC = 0x3
                //        DISK_DRIVE_ADMIN = 0x80000000
                //        PRINT_QUEUE_ADMIN = 0x80000001
                //        DEVICE_ADMIN = 0x80000002
                //        IPC_ADMIN = 0x8000003
                //inParams["MaximumAllowed"] = int maxConnectionsNum;
                // Invoke the method on the ManagementClass object
                outParams = ("Create", inParams, null);
                // Check to see if the method invocation was successful
                if ((uint)(["ReturnValue"].Value) != 0)
                {
                    throw new Exception("Unable to share directory.");
                }
            }
            catch
            {
                return -1;
            }
            return 0;
        }

 

 

/// <summary>
        /// 取消文件夹共享
        /// </summary>
        /// <param name="ShareName">文件夹的共享名</param>
        /// <returns></returns>
        public int CancelShareNetFolder(string ShareName)
        {
            try
            {
                SelectQuery selectQuery = new SelectQuery("Select * from Win32_Share Where Name = '" + ShareName + "'");
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(selectQuery);
                foreach (ManagementObject mo in ())
                {
                    ("Delete", null, null);
                }
            }
            catch
            {
                return -1;
            }
            return 0;
        }