Восстановление базы данных из резервной копии с опцией NoRecovery зависает в состоянии восстановления.C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Восстановление базы данных из резервной копии с опцией NoRecovery зависает в состоянии восстановления.

Сообщение Anonymous »

Я пытаюсь восстановить базу данных из полной резервной копии () и быстрое резервное копирование (

Код: Выделить всё

.qbk). Именно в такой последовательности
USE MASTER
RESTORE DATABASE [" + DB_NAME + "]
FROM DISK = \'" + BackupFile_Txt.Text + "\' WITH NORECOVERY";
база данных зависла в состоянии восстановления.
При обнаружении внутреннего исключения появляется сообщение

ALTER DATABASE не разрешен, пока база данных находится в состоянии восстановления

Операция ALTER DATABASE не выполнена

Когда я открываю SSMS, появляется надпись «Восстановление». базу данных.
Однако, когда я пытаюсь создать полную резервную копию (), восстанавливается нормально (в данном случае используется вариант «С восстановлением»).
Смотрите условие else if в методе WriteFile.

Код: Выделить всё

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 NORECOVERY";
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 RECOVERY";
Writer.WriteLine(strTemp);
}

Writer.WriteLine("GO");
Writer.WriteLine("ALTER DATABASE ["  + DB_NAME + "] SET MULTI_USER");
Writer.WriteLine("GO");

Writer.WriteLine("USE PharmSpecDB");
Writer.WriteLine("GO");

Writer.WriteLine("IF EXISTS (SELECT * FROM sys.triggers WHERE name = 'D_TRG_TestResults')");
Writer.WriteLine("BEGIN");
Writer.WriteLine("DROP TRIGGER D_TRG_TestResults");
Writer.WriteLine("END");
Writer.WriteLine("GO");

Writer.WriteLine("CREATE TRIGGER D_TRG_TestResults ON tblTestResults WITH ENCRYPTION INSTEAD OF DELETE AS BEGIN raiserror (50003,14,1)  END");
Writer.WriteLine("GO");

Writer.WriteLine("IF EXISTS (SELECT * FROM sys.triggers WHERE name = 'D_TRG_SampleIDParameter')");
Writer.WriteLine("BEGIN");
Writer.WriteLine("DROP TRIGGER D_TRG_SampleIDParameter");
Writer.WriteLine("END");
Writer.WriteLine("GO");

Writer.WriteLine("CREATE TRIGGER D_TRG_SampleIDParameter ON tblSampleIDParameter WITH ENCRYPTION INSTEAD OF DELETE AS BEGIN raiserror (50003,14,1)   END");
Writer.WriteLine("GO");

Writer.WriteLine("IF EXISTS (SELECT * FROM sys.triggers WHERE name = 'D_TRG_TestRun')");
Writer.WriteLine("BEGIN");
Writer.WriteLine("DROP TRIGGER D_TRG_TestRun");
Writer.WriteLine("END");
Writer.WriteLine("GO");

Writer.WriteLine("CREATE TRIGGER D_TRG_TestRun ON tblTestRun WITH ENCRYPTION INSTEAD OF DELETE AS BEGIN raiserror (50003,14,1) END");
Writer.WriteLine("GO");

Writer.WriteLine("IF EXISTS (SELECT * FROM sys.triggers WHERE name = 'D_TRG_ReviewApprove')");
Writer.WriteLine("BEGIN");
Writer.WriteLine("DROP TRIGGER D_TRG_ReviewApprove");
Writer.WriteLine("END");
Writer.WriteLine("GO");

Writer.WriteLine("CREATE TRIGGER D_TRG_ReviewApprove ON tblReviewApprove WITH ENCRYPTION INSTEAD OF DELETE AS BEGIN raiserror (50003,14,1) END");
Writer.WriteLine("GO");

Writer.WriteLine("IF EXISTS (SELECT * FROM sys.triggers WHERE name = 'D_TRG_ActiveParamValues')");
Writer.WriteLine("BEGIN");
Writer.WriteLine("DROP TRIGGER D_TRG_ActiveParamValues");
Writer.WriteLine("END");
Writer.WriteLine("GO");

Writer.WriteLine("CREATE TRIGGER D_TRG_ActiveParamValues ON tblActiveParamValues WITH ENCRYPTION INSTEAD OF DELETE AS BEGIN raiserror (50003,14,1) END");
Writer.WriteLine("GO");

Writer.WriteLine("IF EXISTS (SELECT * FROM sys.triggers WHERE name = 'D_TRG_ActivityLogger')");
Writer.WriteLine("BEGIN");
Writer.WriteLine("DROP TRIGGER D_TRG_ActivityLogger");
Writer.WriteLine("END");
Writer.WriteLine("GO");

Writer.WriteLine("CREATE TRIGGER D_TRG_ActivityLogger ON tblActivityLogger WITH ENCRYPTION INSTEAD OF DELETE AS BEGIN raiserror (50003,14,1) END");
Writer.WriteLine("GO");

Writer.WriteLine("EXEC sp_revokedbaccess 'PharmSpecUsr'");
Writer.WriteLine("EXEC sp_grantdbaccess  'PharmSpecUsr','PharmSpecUsr'");
Writer.WriteLine("EXEC sp_addrolemember 'db_owner','PharmSpecUsr'");
Writer.WriteLine("EXEC sp_addrolemember  'db_accessadmin','PharmSpecUsr'");
Writer.WriteLine("EXEC sp_addrolemember  'db_datareader' ,'PharmSpecUsr'");
Writer.WriteLine("EXEC sp_addrolemember 'db_datawriter ', 'PharmSpecUsr'");
Writer.WriteLine("EXEC sp_addrolemember 'db_ddladmin', 'PharmSpecUsr'");
Writer.WriteLine("EXEC sp_addrolemember 'db_securityadmin',  'PharmSpecUsr'");
Writer.WriteLine("EXEC sp_addrolemember 'db_backupoperator','PharmSpecUsr'");
Writer.WriteLine("GO");

Writer.Close();
}
catch (Exception Exc)
{
throw Exc;
}
}
Я выполняю этот SQL из кода C# следующим образом:

Код: Выделить всё

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;
}
Отладка:
При произнесении System.Diagnostics.Debug.WriteLine(sqlString); выводится:

Код: Выделить всё

ALTER DATABASE [PharmSpecDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE

USE MASTER RESTORE DATABASE [PharmSpecDB] FROM DISK = 'C:\PharmBackup\Backup\PharmSpecDB_13-Nov-2024-12-42-57-717_Full.Fbk' WITH NORECOVERY
WAITFOR DELAY '00:00:10'

РЕДАКТИРОВАТЬ:
С этим комментарием и тем, что он говорит в Интернете: «Чтобы восстановить базу данных и подключить ее к сети, чтобы пользователи могли подключиться, вы можете использовать оператор RESTORE DATABASE с опцией With RECOVERY». Я пробую что-то вроде этого,

Код: Выделить всё

strTemp = "USE MASTER RESTORE DATABASE [" + DB_NAME + "] FROM DISK = \'" + BackupFile_Txt.Text + "\' WITH NORECOVERY";
Writer.WriteLine(strTemp);
Writer.WriteLine("Go");
strTemp = "USE MASTER RESTORE DATABASE [" + DB_NAME + "] FROM DISK = \'" + txt_Quick.Text + "\' WITH RECOVERY";
Writer.WriteLine(strTemp);
Writer.WriteLine("Go");
Это вызывает жалобы:

"Журнал или дифференциальная резервная копия не могут быть восстановлены, поскольку нет файлов
готовы к повтору транзакций.\r\nВОССТАНОВЛЕНИЕ ДАННЫХ завершается
ненормально.\r\nКонтекст базы данных изменен на «главный».


Подробнее здесь: https://stackoverflow.com/questions/791 ... -in-recove
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»