У меня есть служба, написанная на C #, которая работает под учетной записью администратора домена.Эта учетная запись установлена как администратор SQL на всех серверах SQL в этом домене.Служба должна скопировать файл mdf / ldf (SQL Server 2003 или 2008) с одного сервера на другой и присоединить его к новому серверу.Вместо того чтобы отсоединять БД на исходном сервере, я изменяю статус БД только для чтения, а затем копирую файлы mdf / ldf.После того, как они скопированы, я сбрасываю статус БД на чтение-запись.
Это работает, если имя исходного сервера примерно такое же, как MYSQLSERVER2K8.Однако код не работает, если это имя экземпляра.Например: MYSQLSERVER2K8 \ VAULT.Я выполнил модульные тесты в NUnit для моего кода, и модульные тесты прошли в обоих случаях.Однако служба не может изменить состояние БД.Мы получаем следующую ошибку:
SQL: ALTER DATABASE My_Test_DataBase SET SINGLE_USER WITH ROLLBACK IMMEDIATE ---> System.Data.SqlClient.SqlException: База данных My_Test_DataBase не существует.Проверьте системные базы данных.Оператор ALTER DATABASE не выполнен.at System.Data.SqlClient.SqlConnection.
Вот мой код (обратите внимание, что я преобразовываю имя сервера в IP-адрес в строке подключения. Например: MYSQLSERVER2K8 \ VAULT преобразуется в 111.111.111.111 \ VAULT:
#region ChangeDatabaseStatus
/// <summary>
/// Change the database status to read-only/read-write
/// </summary>
/// <param name="serverName"></param>
/// <param name="databaseName"></param>
/// <param name="status"></param>
public virtual bool ChangeDatabaseStatus(string serverName, string databaseName, string status)
{
DateTime beginTimeStamp = DateTime.Now;
string sql = String.Empty;
bool databaseStatusChanged = false;
try
{
SqlConnection connection = GetSqlConnection(false);
string connectionString = connection.ConnectionString;
string serverIPAddress = Dns.GetHostAddresses(serverName.Contains(@"\") ? serverName.Substring(0, serverName.IndexOf(@"\")) : serverName)[0].ToString();
connectionString = connectionString.Replace("{0}", serverIPAddress = serverName.Contains(@"\") ? serverIPAddress + serverName.Substring(serverName.IndexOf(@"\"), serverName.Length - serverName.IndexOf(@"\")) : serverIPAddress);
connection.Close();
connection = new SqlConnection(connectionString);
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandTimeout = _commandTimeout;
command.CommandType = CommandType.Text;
command.CommandText = String.Format("ALTER DATABASE {0} SET SINGLE_USER WITH ROLLBACK IMMEDIATE", databaseName);
//Debugging & Exception handling
sql = HelperFunctions.BuildSQL(command);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandTimeout = _commandTimeout;
command.CommandType = CommandType.Text;
command.CommandText = status == "ReadOnly" ? String.Format("ALTER DATABASE {0} SET READ_ONLY", databaseName) : String.Format("ALTER DATABASE {0} SET READ_WRITE", databaseName);
//Debugging & Exception handling
sql = HelperFunctions.BuildSQL(command);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
databaseStatusChanged = true;
}
using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandTimeout = _commandTimeout;
command.CommandType = CommandType.Text;
command.CommandText = String.Format("ALTER DATABASE {0} SET MULTI_USER", databaseName);
//Debugging & Exception handling
sql = HelperFunctions.BuildSQL(command);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
}
}
catch (Exception e)
{
throw new DataProviderException(String.Format("{0} operation failed. SQL: {1}", MethodBase.GetCurrentMethod().Name, sql), e);
}
finally
{
LogPerformance(String.Format("Elapsed time for: {0}", MethodBase.GetCurrentMethod().Name), beginTimeStamp, DateTime.Now, null);
}
return databaseStatusChanged;
}
#endregion //ChangeDatabaseStatus