20

I try to restore the database like this:

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

but I always get error:

Msg 3102, Level 16, State 1, Line 7
RESTORE cannot process database 'MyDataBase ' because it is in use by this session. It is recommended that the master database be used when performing this operation.
Msg 3013, Level 16, State 1, Line 7
RESTORE DATABASE is terminating abnormally.

6 Answers 6

18

I prefer to use SMO to restore a backup:

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();

You'll need references to Microsoft.SqlServer.Smo, Microsoft.SqlServer.SmoExtended, and Microsoft.SqlServer.Management.Sdk.Sfc

Sign up to request clarification or add additional context in comments.

3 Comments

On my machine the necessary DLLs to access these libraries were in C:\Program Files (x86)\Microsoft SQL Server\110\SDK\Assemblies (because I have SQL Server Management Studio installed as part of SQL Server Express 2008 R2), and I needed to Browse to this folder and add: Microsoft.SqlServer.ConnectionInfo.dll, Microsoft.SqlServer.Management.Sdk.Sfc.dll, Microsoft.SqlServer.Smo.dll, Microsoft.SqlServer.SmoExtended.dll.
Why the dbPath and logPath lines? They don't seem necessary. You can also make this slightly more concise by using restore.Devices.AddDevice( and passing the arguments you used in new BackupDeviceItem
@ChrisMoschini I believe he meant to do something like: RelocateFile relocateDataFile = new RelocateFile(restore.ReadFileList(smoServer).Rows[0][0].ToString(), dbPath ); restore.RelocateFiles.Add(relocateDataFile);
15

Your DB connection is most likely to the database you're trying to restore. So there is a DB shared lock which prevents the restore of your db

Try this

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

Or change the connection details to use master DB

2 Comments

sorry !!! i need to restore i try this: RESTORE DATABASE MyDataBase FROM DISK='d:\MyDataBase.BAK' and got this error
i try this: USE MASTER RESTORE MyDataBase TO DISK='d:\MyDATA.BAK but still get this error: Msg 3159, Level 16, State 1, Line 7 The tail of the log for the database "MyDataBase " has not been backed up. Use BACKUP LOG WITH NORECOVERY to backup the log if it contains work you do not want to lose. Use the WITH REPLACE or WITH STOPAT clause of the RESTORE statement to just overwrite the contents of the log. Msg 3013, Level 16, State 1, Line 7 RESTORE DATABASE is terminating abnormally.
7

  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();
        }

Comments

2

Your connection string should have a master database as default catalog to connect to.

Comments

1

You must connect to the database server via a different database.

So your connection string should take you to say "Master" or another database on the server, then you can complete the task at hand.

Comments

0

I've ended with this solution. Name of my database was Stats This will work without installed MSSQL management studio

    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
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.