【问题标题】:How to restore SQL Server database through C# code如何通过 C# 代码恢复 SQL Server 数据库
【发布时间】:2011-05-12 06:18:24
【问题描述】:

我尝试这样恢复数据库:

SQL = @"RESTORE DATABASE MyDataBase TO DISK='d:\MyDATA.BAK'";
                Cmd = new SqlCommand(SQL, Conn);
                Cmd.ExecuteNonQuery();
                Cmd.Dispose();

但我总是出错:

消息 3102,第 16 级,状态 1,第 7 行
RESTORE 无法处理数据库“MyDataBase”,因为它正在使用中 通过本次会议。建议使用master数据库 执行此操作时。
消息 3013,第 16 层,状态 1,第 7 行
RESTORE DATABASE 异常终止。

【问题讨论】:

    标签: c# sql-server-2008


    【解决方案1】:

    我已经结束了这个解决方案。我的数据库名称是 Stats 这将在没有安装 MSSQL 管理工作室的情况下工作

        public void BackUpDB(string fname)
        {
            using (SqlConnection cn = new SqlConnection(_cstr))
            {
                cn.Open();
                string cmd = "BACKUP DATABASE [Stats] TO DISK='" + fname + "'";
                using (var command = new SqlCommand(cmd, cn))
                {
                    command.ExecuteNonQuery();
                }
            }
        }
    
        public void RestoreDB(string fname)
        {
            using (SqlConnection cn = new SqlConnection(_cstr))
            {
                cn.Open();
                #region step 1 SET SINGLE_USER WITH ROLLBACK
                string sql = "IF DB_ID('Stats') IS NOT NULL ALTER DATABASE [Stats] SET SINGLE_USER WITH ROLLBACK IMMEDIATE";
                using (var command = new SqlCommand(sql, cn))
                {
                    command.ExecuteNonQuery();
                }
                #endregion
                #region step 2 InstanceDefaultDataPath
    
                sql = "SELECT ServerProperty(N'InstanceDefaultDataPath') AS default_file";
                string default_file = "NONE";
                using (var command = new SqlCommand(sql, cn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                       if (reader.Read())
                        {
                            default_file = reader.GetString(reader.GetOrdinal("default_file"));
                        }
                    }
                }
                sql = "SELECT ServerProperty(N'InstanceDefaultLogPath') AS default_log";
                string default_log = "NONE";
                using (var command = new SqlCommand(sql, cn))
                {
                    using (var reader = command.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            default_log = reader.GetString(reader.GetOrdinal("default_log"));
                        }
                    }
                }
                #endregion
                #region step 3 Restore
                sql = "USE MASTER RESTORE DATABASE [Stats] FROM DISK='" + fname + "' WITH  FILE = 1, MOVE N'Stats' TO '" + default_file + "Stats.mdf', MOVE N'Stats_Log' TO '"+ default_log+ "Stats_Log.ldf', NOUNLOAD,  REPLACE,  STATS = 1;";
                using (var command = new SqlCommand(sql, cn))
                {
                    command.ExecuteNonQuery();
                }
                #endregion
                #region step 4 SET MULTI_USER
                sql = "ALTER DATABASE [Stats] SET MULTI_USER";
                using (var command = new SqlCommand(sql, cn))
                {
                    command.ExecuteNonQuery();
                }
                #endregion
            }
        }
    

    【讨论】:

      【解决方案2】:

        public void Restore(string Filepath)
              {
                  try
                  {
                      if(con.State == ConnectionState.Closed)
                      {
                          con.Open();
                      }
                      SqlCommand cmd1 = new SqlCommand("ALTER DATABASE [" + Database + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE ", con);
                      cmd1.ExecuteNonQuery();
                      SqlCommand cmd2 = new SqlCommand("USE MASTER RESTORE DATABASE [" + Database + "] FROM DISK='" + Filepath + "' WITH REPLACE", con);
                      cmd2.ExecuteNonQuery();
                      SqlCommand cmd3 = new SqlCommand("ALTER DATABASE [" + Database + "] SET MULTI_USER", con);
                      cmd3.ExecuteNonQuery();
                      con.Close();
                  }
                  catch (Exception ex)
                  {
                      MessageBox.Show(ex.Message);
                  }
                  con.Close();
              }
      

      【讨论】:

        【解决方案3】:

        您的数据库连接最有可能连接到您尝试恢复的数据库。所以有一个数据库共享锁可以防止你的数据库恢复

        试试这个

        SQL = @"USE master BACKUP DATABASE MyDataBase TO DISK='d:\MyDATA.BAK'";
        

        或更改连接详细信息以使用主数据库

        【讨论】:

        • 对不起!!!我需要恢复我试试这个:RESTORE DATABASE MyDataBase FROM DISK='d:\MyDataBase.BAK' 并得到这个错误
        • 我试试这个:USE MASTER RESTORE MyDataBase TO DISK='d:\MyDATA.BAK 但仍然得到这个错误:Msg 3159, Level 16, State 1, Line 7数据库“MyDataBase”尚未备份。如果日志包含您不想丢失的工作,请使用 BACKUP LOG WITH NORECOVERY 备份日志。使用 RESTORE 语句的 WITH REPLACE 或 WITH STOPAT 子句仅覆盖日志的内容。消息 3013,级别 16,状态 1,第 7 行 RESTORE DATABASE 异常终止。
        【解决方案4】:

        我更喜欢使用 SMO 来恢复备份:

        Microsoft.SqlServer.Management.Smo.Server smoServer = 
             new Server(new ServerConnection(server));
        
        Database db = smoServer.Databases['MyDataBase'];
        string dbPath = Path.Combine(db.PrimaryFilePath, 'MyDataBase.mdf');
        string logPath = Path.Combine(db.PrimaryFilePath, 'MyDataBase_Log.ldf');
        Restore restore = new Restore();
        BackupDeviceItem deviceItem = 
            new BackupDeviceItem('d:\MyDATA.BAK', DeviceType.File);
        restore.Devices.Add(deviceItem);
        restore.Database = backupDatabaseTo;
        restore.FileNumber = restoreFileNumber;
        restore.Action = RestoreActionType.Database;
        restore.ReplaceDatabase = true;
        restore.SqlRestore(smoServer);
        
        db = smoServer.Databases['MyDataBase'];
        db.SetOnline();
        smoServer.Refresh();
        db.Refresh();
        

        您需要对 Microsoft.SqlServer.Smo、Microsoft.SqlServer.SmoExtended 和 Microsoft.SqlServer.Management.Sdk.Sfc 的引用

        【讨论】:

        • 在我的机器上,访问这些库所需的 DLL 位于 C:\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies 中(因为我安装了 SQL Server Management Studio 作为SQL Server Express 2008 R2),我需要浏览到此文件夹并添加:Microsoft.SqlServer.ConnectionInfo.dll、Microsoft.SqlServer.Management.Sdk.Sfc.dll、Microsoft.SqlServer.Smo.dll、Microsoft.SqlServer。 SmoExtended.dll。
        • 为什么是 dbPath 和 logPath 行?他们似乎没有必要。您还可以通过使用 restore.Devices.AddDevice( 并传递您在 new BackupDeviceItem 中使用的参数来使其更加简洁
        • @ChrisMoschini 我相信他的意思是: RelocateFile relocateDataFile = new RelocateFile(restore.ReadFileList(smoServer).Rows[0][0].ToString(), dbPath ); restore.RelocateFiles.Add(relocateDataFile);
        【解决方案5】:

        您的连接字符串应该有一个master 数据库作为要连接的默认目录。

        【讨论】:

          【解决方案6】:

          您必须通过不同的数据库连接到数据库服务器。

          所以你的连接字符串应该带你说“Master”或服务器上的另一个数据库,然后你就可以完成手头的任务了。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-23
            相关资源
            最近更新 更多