nikhil
nikhil

Reputation: 1748

Restoring a differential backup along with full backup

I am trying to restore both full backup and differential backup with Sql Queries. But doing so is throwing an exception when saying NoRestore or Restore with QuickBackup(txt_Quick.Text)

"The log or differential backup cannot be restored because no files are ready to rollforward.\r\nRESTORE DATABASE is terminating abnormally.\r\nChanged database context to 'master'.

Here is my code. Please see the else if condition in the WriteFile() method.

private void WriteFile()
        {
            try
            {
                // Creates Restore.sql file.
                string strTSQLFile = Environment.CurrentDirectory + "\\Restore.sql";
                FileInfo File = new FileInfo(strTSQLFile);
                StreamWriter Writer = File.CreateText();

                // Write open database  
                string strTemp;
                Writer.WriteLine("ALTER DATABASE [" + DB_NAME + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
                Writer.WriteLine("Go");
                if (Complete_Opt.Checked == true)           // Full restore
                {
                    strTemp = "USE MASTER RESTORE DATABASE [" + DB_NAME + "] FROM DISK = \'" + BackupFile_Txt.Text + "\' WITH RECOVERY";
                    Writer.WriteLine(strTemp);
                }
                else if (Differential_Opt.Checked == true)  // Quick restore
                {
                    strTemp = "USE MASTER RESTORE DATABASE [" + DB_NAME + "] FROM DISK = \'" + BackupFile_Txt.Text + "\' WITH RECOVERY";
                    Writer.WriteLine(strTemp);
                    Writer.WriteLine("GO");
                    //Writer.WriteLine("WAITFOR DELAY '00:00:10'");
                    //Writer.WriteLine("GO");
                    Writer.WriteLine("ALTER DATABASE [" + DB_NAME + "] SET MULTI_USER");
                    Writer.WriteLine("GO");
                    Writer.WriteLine("ALTER DATABASE [" + DB_NAME + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
                    Writer.WriteLine("Go");
                    strTemp = "USE MASTER RESTORE DATABASE [" + DB_NAME + "] FROM DISK = \'" + txt_Quick.Text + "\' WITH NORECOVERY";
                    Writer.WriteLine(strTemp);
                }

                Writer.WriteLine("GO");
                Writer.WriteLine("ALTER DATABASE [" + DB_NAME + "] SET MULTI_USER");
                Writer.WriteLine("GO");
                Writer.Close();
            }
            catch (Exception Exc)
            {
                throw Exc;
            }
        }

This is how I am executing the queries.

try
                                {
                                    string strTSQLFile = Environment.CurrentDirectory + "\\Restore.sql";
                                    if (!File.Exists(strTSQLFile))
                                    {
                                        throw new FileNotFoundException();
                                    }
                                    using (StreamReader srSQL = new StreamReader(strTSQLFile))
                                    {
                                        string sqlLine;
                                        StringBuilder sqlString = new StringBuilder();

                                        while (!srSQL.EndOfStream)
                                        {
                                            sqlLine = srSQL.ReadLine();

                                            if (string.IsNullOrEmpty(sqlLine) == false)
                                            {
                                                // We don't actually execute the "GO" lines but can use them to determine when to call the executenonquery function
                                                if (string.Compare(sqlLine, "GO", true) == 0)
                                                {
                                                    // Make sure we have something to execute
                                                    if (string.IsNullOrEmpty(sqlString.ToString()) == false)
                                                    {
                                                        ServerActionResult.ConnectionContext.ExecuteNonQuery(sqlString.ToString());
                                                        System.Diagnostics.Debug.WriteLine(sqlString);
                                                    }

                                                    sqlString.Clear();
                                                }
                                                // Add the next line to the stringbuilder object
                                                else
                                                {
                                                    sqlString.AppendLine(sqlLine);
                                                }
                                            }
                                        }
                                    }
                                }
                                catch (Exception exc)
                                {
                                    throw exc;
                                }
                                finally
                                {
                                    var strQuery = ("ALTER DATABASE [" + DB_NAME + "] SET MULTI_USER");
                                    ServerActionResult.ConnectionContext.ExecuteNonQuery(strQuery);
                                }

As I write to the debug window with System.Diagnostics.Debug.WriteLine(sqlString);, this is what I see,

ALTER DATABASE [PharmSpecDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE

USE MASTER RESTORE DATABASE [PharmSpecDB] FROM DISK = 'C:\PharmBackup\Backup\PharmSpecDB_14-Nov-2024-13-38-12-520_Full.Fbk' WITH RECOVERY

ALTER DATABASE [PharmSpecDB] SET MULTI_USER

ALTER DATABASE [PharmSpecDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE

Exception thrown: 'Microsoft.SqlServer.Management.Common.ExecutionFailureException' in Microsoft.SqlServer.ConnectionInfo.dll

This is how the backups are created,

 Backup bk = new Backup();
    
                        string szFilename = DB_NAME + "_" + DateTime.Now.ToString("dd-MMM-yyyy-HH-mm-ss-fff", CultureInfo.InvariantCulture);
    
                        //Setup the backup options
                        if (enumBackupMode == BACKUP_MODE_ENUM.BACKUP_FULL)
                        {
                            szFilename += "_Full.Fbk";
                            bk.BackupSetDescription = "PharmSpecDB Full Backup";
                            bk.BackupSetName = DB_NAME + " Backup";
                            bk.LogTruncation = BackupTruncateLogType.Truncate;
                            bk.Incremental = false;
                        }
                        else if (enumBackupMode == BACKUP_MODE_ENUM.BACKUP_QUICK)
                        {
                            szFilename += "_Quick.qbk";
                            bk.BackupSetDescription = "PharmSpecDB Quick Backup";
                            bk.BackupSetName = DB_NAME + " Backup";
                            bk.LogTruncation = BackupTruncateLogType.Truncate;
                            bk.Incremental = true;
                        }
 bdi = new BackupDeviceItem(szLocation + szFilename, DeviceType.File);
                    bk.Devices.Add(bdi);
                    bk.Action = BackupActionType.Database;
                    bk.Database = DB_NAME;
                    bk.RetainDays = 365;

                    //Perform the backup
                    bk.SqlBackup(ServerActionResult);

Upvotes: 0

Views: 33

Answers (0)

Related Questions