Odzyskiwanie bazy z pliku *.bak (Sql Server)

0

Dzień dobry.

Mam problem z programowym odzyskaniem bazy z pliku *.bak.

Wyskakuje mi komunikat: RESTORE cannot process database '***' because it is in use by this session. It is recommended that the master database be used when performing this operation

Znalazłem w sieci wiele raportów wystąpień tego błędu i zastosowałem się do wszelkich technik, ale na nic to się zdało. Załączam kod odzyskiwania:

public void Restore(object sender, EventArgs e)
{
	OpenFileDialog ofd = new OpenFileDialog();
	ofd.Filter = "pliki z rozszerzeniem bak (*.bak)|*.bak";
	ofd.InitialDirectory = @"C:\momBackup";

	bool result = false;

	try
	{
		if (ofd.ShowDialog() == DialogResult.OK)
			if (MessageBox.Show("Czy na pewno chcesz przywrócić bazę do stanu z: " + ofd.SafeFileName.Substring(0, ofd.SafeFileName.Length - 4) + "?", "Pytanie", MessageBoxButtons.YesNo) == DialogResult.Yes)
			{
				//MainForm.sqlConn.ConnectToMaster();
				if (MainForm.sqlConn.IsTableEmpty("logins"))
				{
					MessageBox.Show("Nie przywrócono bazy. Najpierw dodaj użytkowników");
					return;
				}

				string[,] res = MainForm.sqlConn.Query("Restore filelistonly from disk='" + ofd.FileName + "'");
				if (null == res ||
					//null == MainForm.sqlConn.ExecuteOnce("ALTER DATABASE nazwaBazy SET MULTI_USER"))
					null == MainForm.sqlConn.ExecuteOnce("ALTER DATABASE nazwaBazy SET SINGLE_USER WITH ROLLBACK IMMEDIATE"))
				{
					MessageBox.Show("Nie przywrócono bazy.");
					return;
				}
				MainForm.sqlConn.useDB("master");
				MainForm.sqlConn.ChangeOwnerToFirstUserLogin();
				if (null == MainForm.sqlConn.ExecuteOnce("RESTORE DATABASE nazwaBazy FROM DISK = '" + ofd.FileName + "' WITH MOVE '" + res[0, 0] + "' TO '" + res[0, 1] + "', MOVE '" + res[1, 0] + "' TO '" + res[1, 1] + "'") ||
					null == MainForm.sqlConn.ExecuteOnce("ALTER DATABASE nazwaBazy SET MULTI_USER"))
				{
					MessageBox.Show("Nie przywrócono bazy.");
					MainForm.sqlConn.ChangeOwnerToSystem();
					return;
				}
				result = true;
			}
	}

	catch (Exception ex)
	{
		MessageBox.Show(ex.ToString());
		MainForm.sqlConn.ChangeOwnerToSystem();
		return;
	}
	
	MainForm.sqlConn.ChangeOwnerToSystem();
	if (result)
		MessageBox.Show("Pomyślnie przywrócono bazę do staniu, z " + ofd.SafeFileName);

	else
		MessageBox.Show("Nie przywrócono bazy.");
}

Kod jest po wielu modyfikacjach i jego aktualny wygląd nie jest wersją sztywnie poprawną. Niektóre instrukcje są niepotrzebne.
Aktualnie program zwraca wyjątek w linii: RESTORE DATABASE ... FROM DISK. Jeżeli ktoś ma jakiś pomysł, to proszę o odpowiedź.

Pozdrawiam
Michał!

Screen

1

Ja mam to zrobione w ten sposób i nie mam problemów, ponieważ bezbłędnie przywraca codziennie bazę danych

using (SqlConnection con = new SqlConnection(ConnectionString))
{
     con.Open();

     using (SqlCommand cmd = con.CreateCommand())
     {
          string sql = $"Alter Database {dbname} SET SINGLE_USER WITH ROLLBACK IMMEDIATE;";
          sql += $"Restore Database {dbname} FROM DISK ='" + path + fileName + "' WITH REPLACE;";
          cmd.CommandText = sql;
          cmd.CommandTimeout = 240;
          cmd.ExecuteNonQuery();
      }
}

Wydaje mi się, że twój problem leży po stronie ConnectionString, którego nie wrzciłeś tutaj

if (string.IsNullOrEmpty(password))
    ConnectionString = $@"Server={host};Database=master;Trusted_Connection=True;";
else
    ConnectionString = $@"Data Source={host};Initial Catalog=master;Persist Security Info=False;User ID=sa;Password={password}";
0

Dzięki za odpowiedź. Przyczyną błędu było, zaszyte wewnątrz pozostałego kodu, ustawianie używania bazy programu. Nie mogłem wgrać do niej pliku .bat, gdyż była używana.

Pozdrawiam i dziękuję.
Michał

1 użytkowników online, w tym zalogowanych: 0, gości: 1