【问题标题】:Restore multiple databases programmatically以编程方式恢复多个数据库
【发布时间】:2017-07-27 11:39:10
【问题描述】:

我正在做一个从 Microsoft SQL Server 恢复/备份数据库的应用程序。

如何实现捕获源文件夹中所有.bak文件的效果,而目标数据库的文本框作为新db的新名称并将其恢复到sql server?

我的验证是,如果目标数据库组框中的名称,它会提示错误而不是恢复它。

这是界面

这是我的代码

CheckDBExist

public List<string> CheckIfDatabaseExists(string SQLServer, string backupRestore)
{
    bool result = false;
    List<string> DBList = new List<string>();
    string sqlConnectionString = this.rbWindow.Checked ?
                "Server=" + this.cboSQLServer.Text.Trim() + ";Database=master;Trusted_Connection=Yes" :
                "Server=" + this.cboSQLServer.Text.Trim() + ";Database=master;uid=" + this.txtUsername.Text.Trim() + ";pwd=" + this.txtPassword.Text.Trim();
    foreach (Control c in groupBox1.Controls)
    {
        if (c.GetType() == typeof(TextBox))
        {
            SqlConnection tmpConn = new SqlConnection(sqlConnectionString);

            string sqlCreateDBQuery = string.Format("SELECT database_id FROM sys.databases WHERE Name = '{0}'", c.Text);

            using (tmpConn)
            {
                using (SqlCommand sqlCmd = new SqlCommand(sqlCreateDBQuery, tmpConn))
                {
                    tmpConn.Open();

                    object resultObj = sqlCmd.ExecuteScalar();

                    int databaseID = 0;

                    if (resultObj != null)
                    {
                        int.TryParse(resultObj.ToString(), out databaseID);
                    }

                    tmpConn.Close();

                    result = (databaseID > 0);
                    if ((!result) && (backupRestore == "backup"))
                    {
                        DBList.Add("[" + c.Text + "]");
                    }
                    else if ((result) && (backupRestore == "restore"))
                    {
                        DBList.Add("[" + c.Text + "]");
                    }

                }
            }
        }
    }
    return DBList;
}

按钮点击

private void btnRestore_Click(object sender, EventArgs e)
{
    string outputFolder = this.txtFolder.Text;
    if (string.IsNullOrEmpty(outputFolder))
    {
        MessageBox.Show("Please select source folder!", "Empty Source Folder", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    else
    {
        List<string> ExistDB = new List<string>();
        ExistDB = this.CheckIfDatabaseExists(this.cboSQLServer.Text, "restore");
        if (ExistDB.Count == 0)
        {
            RestoreDatabase(this.cboSQLServer.Text, this.txtFolder.Text);
        }
        else
        {
            MessageBox.Show("Databases " + string.Join(", ", ExistDB) + " exist!", "Database Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}

恢复数据库代码

public void RestoreDatabase(string SQLServer, string outputFolder) {

        ServerConnection con = new ServerConnection(SQLServer);
        Server server = new Server(con);            

            foreach (Control c in groupBox3.Controls)
            {

                //try
                //{
                    if (c.GetType() == typeof(TextBox))
                    {
                        Restore destination = new Restore();
                        destination.Action = RestoreActionType.Database;
                        destination.Database = c.Text;
                        string backUpFile = outputFolder + "\\" + destination.Database + ".bak";
                        BackupDeviceItem source = new BackupDeviceItem(backUpFile, DeviceType.File);

                        string logFile = Path.GetDirectoryName(backUpFile);
                        logFile = Path.Combine(logFile, destination.Database + "_Log.ldf");

                        string dataFile = Path.GetDirectoryName(backUpFile);
                        dataFile = Path.Combine(dataFile, destination.Database + ".mdf");


                        destination.Devices.Add(source);
                        DataTable logicalRestoreFiles = destination.ReadFileList(server);
                        destination.RelocateFiles.Add(new RelocateFile(logicalRestoreFiles.Rows[0][0].ToString(), dataFile));
                        destination.RelocateFiles.Add(new RelocateFile(logicalRestoreFiles.Rows[1][0].ToString(), logFile));
                        destination.ReplaceDatabase = true;
                        destination.SqlRestore(server);
                    }            
                //}
                //catch (Exception ex)
                //{
                //MessageBox.Show(ex.Message);
                //}                                                            
            }      
             }                   

这是触发异常的代码

错误提示:

“无法打开备份设备'D:\TestBackup\VSM642SP2QC__VfsWorkflow.bak'。?>操作系统错误2(系统找不到>指定的文件。)。\r\nRESTORE FILELIST异常终止。”

我该怎么办?

【问题讨论】:

  • 失败时;在第一个数据库上还是之后?
  • 这很奇怪。我从未使用过这些课程。但是使用 Sql Server 命令来代替呢?只需执行命令“从磁盘恢复[数据库名称] = [备份文件位置]。
  • 您声明了一个设备类型(源),但您从未将它与您的恢复对象挂钩。来自 MSDN,“还原实例必须在调用此方法之前声明一个 DeviceType。否则,将引发异常。”

标签: c# sql-server sql-server-2012 database-backups database-restore


【解决方案1】:

在您使用ReadFileList的行之前添加这行代码

destination.Devices.Add(source);

还原实例必须在调用ReadFileList 方法之前声明DeviceType。否则会抛出异常。您声明了 DeviceType,但从未将其连接到您的 Restore。

【讨论】:

  • 我明天试试。我把我的工作笔记本电脑留在了办公室。谢谢你的建议:)
  • 嗨@Richard Hansell。我确实有另一个问题,请您再次查看和提问并给我建议吗?
  • 看起来你的备份路径中有两个“\\”,这应该是一个“\”吧?
猜你喜欢
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
  • 1970-01-01
  • 2011-09-05
  • 2010-10-21
相关资源
最近更新 更多