Как восстановить базу данных SQL Server с помощью кода С#
Я пытаюсь восстановить базу данных следующим образом:
SQL = @"RESTORE DATABASE MyDataBase TO DISK='d:\MyDATA.BAK'";
Cmd = new SqlCommand(SQL, Conn);
Cmd.ExecuteNonQuery();
Cmd.Dispose();
но я всегда получаю ошибку:
Msg 3102, уровень 16, состояние 1, строка 7
RESTORE не может обрабатывать базу данных "MyDataBase", поскольку она используется на этом сеансе. Рекомендуется использовать базовую базу данных при выполнении этой операции.
Msg 3013, уровень 16, состояние 1, строка 7
RESTORE DATABASE заканчивается аномально.
Ответы
Ответ 1
Я предпочитаю использовать 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
Ответ 2
Ваше соединение с БД наиболее вероятно с базой данных, которую вы пытаетесь восстановить. Таким образом, существует общая блокировка DB, которая предотвращает восстановление вашего db
Попробуйте это
SQL = @"USE master BACKUP DATABASE MyDataBase TO DISK='d:\MyDATA.BAK'";
Или измените данные соединения, чтобы использовать мастер-DB
Ответ 3
Вы должны подключиться к серверу базы данных через другую базу данных.
Таким образом, ваша строка подключения должна заставить вас сказать "Мастер" или другую базу данных на сервере, после чего вы можете выполнить задачу под рукой.
Ответ 4
Строка подключения должна иметь базу данных master
в качестве каталога по умолчанию для подключения.
Ответ 5
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();
}
Ответ 6
Я закончил с этим решением. Имя моей базы данных было Stats Это будет работать без установленной 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
}
}