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

来源:互联网 发布:哈登数据库 编辑:程序博客网 时间:2024/05/16 04:00

最近查了一下网上远程备份数据库的方法,好像还是个挺麻烦的事情。但是项目里必须加入这个模块,所以也只有死磕出一个了。最后总结出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 = managementClass.GetMethodParameters("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 = managementClass.InvokeMethod("Create", inParams, null);

                // Check to see if the method invocation was successful

                if ((uint)(outParams.Properties["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 searcher.Get())

                {

                    mo.InvokeMethod("Delete", null, null);

                }

            }

            catch

            {

                return -1;

            }

            return 0;

        }