简体   繁体   English

从bak文件还原数据库

[英]Restore Database from bak file

I'm trying to restore a database from a bak file. 我正在尝试从bak文件还原数据库。 I found some code on how to do it grammatically but I'm not sure what I'm doing wrong. 我找到了一些有关如何语法上的代码,但是我不确定自己做错了什么。 I'm getting an error: 我收到一个错误:

Error: Restore failed for Server 'www.freegamedata.com'. 错误:服务器“ www.freegamedata.com”的还原失败。

I assume because i'm remotely connected? 我认为是因为我已远程连接? I'm not sure. 我不确定。 The bak file is not on the server machine. bak文件不在服务器计算机上。 I'm trying to build a desktop application that will install my database on the users server using my file. 我正在尝试构建一个桌面应用程序,它将使用我的文件将数据库安装在用户服务器上。 Here is my code: 这是我的代码:

 private void Restore_Database()
    {
        try
        {
            Server server = new Server(Properties.Settings.Default.SQL_Server);
            string filename = "Test.bak";
            string filepath = System.IO.Directory.GetCurrentDirectory() + "\\file\\" + filename;
            Restore res = new Restore();

            res.Database = Properties.Settings.Default.SQL_Database;      
            res.Action = RestoreActionType.Database;
            res.Devices.AddDevice(filepath, DeviceType.File);
            res.PercentCompleteNotification = 10;
            res.ReplaceDatabase = true;
            res.PercentComplete += new PercentCompleteEventHandler(res_PercentComplete);  
            res.SqlRestore(server);
        }
        catch(Exception ex)
        {

        }
    }  

I'm not sure if I'm going about this the correct way. 我不确定是否要采用正确的方法。 I'd like to add my database with my data to the users server as a base database. 我想将我的数据库连同我的数据作为基本数据库添加到用户服务器。 Am I doing something wrong? 难道我做错了什么? My connection string is good so I know its not a connection issue. 我的连接字符串很好,所以我知道它不是连接问题。

Restore file must be on server. 恢复文件必须在服务器上。 For installation use SQL script. 对于安装,请使用SQL脚本。 This can be generated by SQL Server Management Studio (including data). 这可以由SQL Server Management Studio生成(包括数据)。

Right click on database. 右键单击数据库。 Choose "Tasks" - "Generate scripts". 选择“任务”-“生成脚本”。 On second page of wizard choose "Advanced" and find "Types of data to script". 在向导的第二页上,选择“高级”,然后找到“要编写脚本的数据类型”。 Select "Schema and data" and save script to file. 选择“架构和数据”并将脚本保存到文件。

Then use this code to run script on database 然后使用此代码在数据库上运行脚本

string scriptText = File.ReadAllText(scriptFile, Encoding.Default);
ExecuteBatch executeBatch = new ExecuteBatch();
StringCollection commandTexts = executeBatch.GetStatements(scriptText);

using (SqlConnection sqlConnection = new SqlConnection(conn))
{
    sqlConnection.InfoMessage += SqlConnection_InfoMessage;
    sqlConnection.Open();

    for (int i = 0; i < commandTexts.Count; i++)
    {
        try
        {
            log.InfoFormat("Executing statement {0}", i + 1);
            string commandText = commandTexts[i];

            using (SqlCommand sqlCommand = sqlConnection.CreateCommand())
            {
                log.Debug(commandText);
                sqlCommand.CommandText = commandText;
                sqlCommand.CommandTimeout = 300;
                int r = sqlCommand.ExecuteNonQuery();
                log.DebugFormat("{0} rows affected", r);
            }
        }
        catch (Exception ex)
        {
            log.Warn("Executing command failed", ex);

            try
            {
                sqlConnection.Open();
            }
            catch (Exception ex2)
            {
                log.Error("Cannot reopen connection", ex2);
            }
        }
    }

    sqlConnection.Close();
}

I have found a workaround for those whom do not have local access. 对于那些没有本地访问权限的人,我已经找到了解决方法。 This is a bit involved so I hope I explain this correctly and it makes sense. 这涉及到一点,所以我希望我能正确解释,这是有道理的。

Also note you will need to export your data to an excel spreadsheet before you do the steps listed below. 另请注意,在执行以下步骤之前,您需要将数据导出到excel电子表格。

Exporting Data Part 1: Backup Your DATA! 导出数据第1部分:备份数据!

This is a pretty simple process. 这是一个非常简单的过程。 Open SQL Management Studio and right click on your database. 打开SQL Management Studio,然后右键单击数据库。 Choose export data and export it as an excel spreadsheet 2007. I'm not going to give detailed steps on this part because its pretty basic and you can google it. 选择导出数据并将其导出为ex​​cel电子表格2007。在这部分中,我将不提供详细的步骤,因为它非常基础,您可以对其进行Google搜索。 Sorry for the inconvenience. 抱歉给你带来不便。

Part 2: Delete your database for testing purposes but make sure you have a working backup before you delete your database. 第2部分:出于测试目的删除数据库,但是在删除数据库之前,请确保您具有有效的备份。

Importing Data Part 1: You need to create a script that will build your database for you automatically. 导入数据第1部分:您需要创建一个脚本,该脚本将自动为您构建数据库。 You can do this by logging into SQL management Studio and right click on the database and choose: 您可以通过登录到SQL Management Studio并在数据库上单击鼠标右键,然后选择:

  • Task -> Generate scripts 任务->生成脚本

you should only need the default information. 您只需要默认信息。 However, if your like me, I excluded the users in the list. 但是,如果您喜欢我,则将列表中的用户排除在外。 This will generate a large SQL script. 这将生成一个大型SQL脚本。

Part 2: Next you will want to store this file in your solution/project. 第2部分:接下来,您将要将此文件存储在解决方案/项目中。 Make sure you right click it and choose always copy or or copy if newer. 确保右键单击它,然后选择“始终复制”或“复制”(如果较新)。 I think that's the options. 我认为这就是选择。 Basically it just copies your file when you debug or build it. 基本上,它只是在调试或构建文件时复制文件。 This is critical because you will need to access this file to execute the script. 这很关键,因为您将需要访问该文件以执行脚本。 Next you need to make a SQL function similar to mine to execute the script: 接下来,您需要使一个类似于我的SQL函数来执行脚本:

public bool SQLScript_ExecuteSQLScript(string ScriptLocation)
        {
            try
            {
                //5 min timeout
                SqlConnection SQLConn = new SqlConnection(cn + "; Connection Timeout = 300;");
                string script = File.ReadAllText(ScriptLocation);
                Server server = new Server(new ServerConnection(SQLConn));

                server.ConnectionContext.ExecuteNonQuery(script);

                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

In my code sample please note I changed my timeout to 5 minutes. 在我的代码示例中,请注意,我将超时更改为5分钟。 In the event you have a large script you may need to adjust the timeout to make sure your script fully executes. 如果您的脚本较大,则可能需要调整超时以确保脚本完全执行。

Congrats you have rebuilt your database. 恭喜,您已重建数据库。

Part 3: Load SQL Management Studio and make sure your database has been rebuilt successfully. 第3部分:加载SQL Management Studio,并确保您的数据库已成功重建。 You should see all your tables and Stored Procs but no data. 您应该看到所有表和存储的Procs,但没有数据。 If this is true, great you can continue. 如果是这样,那么您可以继续。 If not please go back and review your script. 如果没有,请返回并查看您的脚本。 If you have SQL comments in your script, you may need to remove them. 如果脚本中包含SQL注释,则可能需要将其删除。 I had to in order for my script to execute without errors. 为了使我的脚本能够正确执行,我不得不这样做。

Part 4: Now you need to import your data from your excel spreadsheet you created earlier. 第4部分:现在,您需要从您先前创建的excel电子表格中导入数据。 If your like me, you had multipal sheets. 如果您喜欢我,那您就有多张床单了。 If you have multipal sheets then you will want to make a list to loop through each item in your list to import the sheets. 如果您有多页工作表,则需要创建一个列表以循环浏览列表中的每个项目以导入工作表。 If not then you can ignore my code on the list. 如果没有,那么您可以忽略列表上的我的代码。 I also put mine in a background worker but you don't need to depending on the size of your data. 我也将我的工作安排在后台工作,但是您不必依赖于数据的大小。 Also note I created a separate class containing my list but you dont have to do that if you don't want too. 还要注意,我创建了一个包含我的列表的单独的类,但是如果不想的话也不必这样做。 My sheet names are Table_1, Table_2 and Table_3 your will be differently most likely. 我的工作表名称很可能是Table_1,Table_2和Table_3。

Sample Sheet List: 样品表清单:

public List<string> GetTestTableList()
        {
            try
            {
                List<string> testlist = new List<string>();
                testlist.Add("Table_1");
                testlist.Add("Table_2");
                testlist.Add("Table_3");

                return testlist;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

Part 5: Next we will import the data from excel into SQL. 第5部分:接下来,我们将把数据从excel导入到SQL中。 This is a function I made but you can modify this to meet your needs. 这是我做的功能,但是您可以修改它以满足您的需求。

Function: 功能:

private bool Import_Data_Into_SQL(string filepath, string SheetName, string Database, string Schema)
        {
            try
            {
                // sql table should match your sheet name in excel
                string sqltable = SheetName;

                // select all data from sheet by name  
                string exceldataquery = "select * from [" + SheetName + "$]";

                //create our connection strings - Excel 2007 - This may differ based on Excel spreadsheet used
                string excelconnectionstring = @"Provider=Microsoft.ACE.OLEDB.12.0; Data Source='" + filepath + " '; Extended Properties=Excel 8.0;";
                string sqlconnectionstring = Properties.Settings.Default.SQL_Connection;

                //series of commands to bulk copy data from the excel file into our sql table 
                OleDbConnection oledbconn = new OleDbConnection(excelconnectionstring);
                OleDbCommand oledbcmd = new OleDbCommand(exceldataquery, oledbconn);
                oledbconn.Open();
                OleDbDataReader dr = oledbcmd.ExecuteReader();
                SqlBulkCopy bulkcopy = new SqlBulkCopy(sqlconnectionstring);
                bulkcopy.DestinationTableName = Database + "." + Schema +"." + sqltable;

                while (dr.Read())
                {
                    bulkcopy.WriteToServer(dr);
                }

                dr.Close();
                oledbconn.Close();

                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

I hope this helps. 我希望这有帮助。 This was my workaround solution. 这是我的解决方法。 Originally I wanted/tried to import my data using the .bak file but as pointed out above you can only do that if the sql server is local. 最初,我希望/尝试使用.bak文件导入数据,但如上所述,只有在sql server为本地服务器时,您才可以这样做。 So I hope this work around helps those who where faced with a similar issue as me. 因此,我希望这种解决方法可以帮助那些遇到与我类似的问题的人。 I'm not marking this as the answer because the above post answers the question but I'm posting this in case someone else needs this workaround. 我没有将其标记为答案,因为上面的帖子回答了这个问题,但是如果有人需要此解决方法,我会在此发布。 Thanks 谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM