我有一个用C#编写的服务,该服务在域管理员帐户下运行。此帐户在该域中的所有SQL Server上设置为SQL admin。该服务需要将mdf / ldf(SQL Server 2003或2008)从一个服务器复制到另一个服务器并将其附加到新服务器。我没有在源服务器上分离DB,而是将DB状态更改为只读,然后复制mdf / ldf文件。复制完毕后,我将DB状态重置为读写。
如果源服务器名称类似于MYSQLSERVER2K8,则此方法有效。但是,如果代码是实例名称,则代码不起作用。例如:MYSQLSERVER2K8 \ VAULT。我已经在我的代码中运行NUnit中的单元测试,并且单元测试都通过了两种情况。但是,该服务无法更改数据库状态。我们得到的错误如下:
SQL:ALTER DATABASE My_Test_DataBase SET SINGLE_USER WITH ROLLBACK IMMEDIATE ---> System.Data.SqlClient.SqlException:数据库'My_Test_DataBase'不存在。检查sysdatabases。 ALTER DATABASE语句失败。在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
答案 0 :(得分:0)
检查您是否配置了别名。
在Native Client下加载Sql Server配置管理器,然后加载别名。
正如Tony Hopkinson所说,测试你可以使用sqlcmd或来自同一台机器的东西进行连接:
sqlcmd -S MYSQLSERVER2K8\VAULT -q "ALTER DATABASE dbname SET SINGLE_USER WITH ROLLBACK IMMEDIATE"