我试图将数据库的副本复制到同一服务器上的新数据库.服务器是我在Windows XP下运行SQL 2008 Express的本地计算机.使用SMO.Transfer类这样做应该很容易,它几乎可以正常工作!
我的代码如下(稍微简化):
Server server = new Server("server"); Database sourceDatabase = server.Databases["source database"]; Database newDatbase = new Database(server, "new name"); newDatbase.Create(); Transfer transfer = new Transfer(sourceDatabase); transfer.CopyAllObjects = true; transfer.Options.WithDependencies = true; transfer.DestinationDatabase = newDatbase.Name; transfer.CopySchema = true; transfer.CopyData = true; StringCollection transferScript = transfer.ScriptTransfer(); using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); using (SqlCommand switchDatabase = new SqlCommand("USE " + newDatbase.Name, conn)) { switchDatabase.ExecuteNonQuery(); } foreach (string scriptLine in transferScript) { using (SqlCommand scriptCmd = new SqlCommand(scriptLine, conn, transaction)) { int res = scriptCmd.ExecuteNonQuery(); } } }
我在这里做的是首先创建一个新数据库,然后使用Transfer
该类生成一个复制脚本,最后在新数据库中运行该脚本.
这适用于复制结构,但该CopyData
选项不起作用!
该CopyData
选项是否有任何未记录的限制?文档仅说该选项指定是否复制数据.
我尝试使用该TransferData()
方法复制数据库而不使用脚本,但后来我得到一个异常,说"连接到服务器失败",内部异常显示"建立连接时出现网络相关或特定于实例的错误" SQL Server.找不到服务器或无法访问服务器.验证实例名称是否正确以及SQL Server是否配置为允许远程连接.(提供程序:命名管道提供程序,错误:40 - 无法打开与SQL Server的连接)"
我也尝试在服务器上启用命名管道,但这没有帮助.
编辑:我找到了一个解决方案,通过进行备份,然后将其还原到新数据库.虽然这很笨拙,而且比它应该慢,所以我仍然在寻找更好的解决方案.
好吧,在联系Microsft支持后,我让它正常工作,但它很慢,或多或少没用.执行备份然后还原要快得多,只要新副本应与原始副本位于同一服务器上,我将使用它.
工作代码如下:
ServerConnection conn = new ServerConnection("rune\\sql2008"); Server server = new Server(conn); Database newdb = new Database(server, "new database"); newdb.Create(); Transfer transfer = new Transfer(server.Databases["source database"]); transfer.CopyAllObjects = true; transfer.CopyAllUsers = true; transfer.Options.WithDependencies = true; transfer.DestinationDatabase = newdb.Name; transfer.DestinationServer = server.Name; transfer.DestinationLoginSecure = true; transfer.CopySchema = true; transfer.CopyData = true; transfer.Options.ContinueScriptingOnError = true; transfer.TransferData();
诀窍是设置DestinationDatabase属性.即使目标与源相同,也必须设置此项.此外,我必须作为命名实例连接到服务器,而不是使用其他连接选项.