【问题标题】:Clone an existing database to a new database将现有数据库克隆到新数据库
【发布时间】:2016-01-22 02:24:06
【问题描述】:

我正在努力寻找合适的解决方案。我有一个相当大的 SQL Server 2008 Express 数据库,其中包含 60 多个表(许多具有关键约束)和一大堆数据。

我需要将所有这些表、数据和约束从一个数据库准确地复制到另一个数据库。我基本上是在复制网站 A - 以在不同的域上生成精确的副本(网站 B),因此我们最终会得到两个完全相同的网站并行运行,每个网站都有自己相同的数据库。

数据库 A 已在网站 A 上启动并运行。数据库 B 已设置并拥有自己的用户。我只需要从 A 到 B 获取完整的表和数据。我可以修改我的 web.config 连接以使用数据库 B 的登录凭据,它应该可以工作。

我尝试通过 Management Studio Express 备份数据库 A 并恢复到数据库 B,但它告诉我:

System.Data.SqlClient.SqlError:备份集包含一个数据库的备份,而不是现有的“数据库-B”数据库。
(Microsoft.SqlServer.Smo)

我还尝试在 Management Studio Express 中右键单击数据库 A 并转到 Tasks > Generate scripts。但是,当我这样做并在数据库 B 上运行 SQL 脚本时,我会在导入内容时遇到与外键等有关的大量错误。似乎它在做正确的事情,但无法处理不同的键/关系。

那么,有没有人知道一种简单、可靠的方法,可以让我的数据 100% 准确和完整地从数据库 A 传输到数据库 B?

我想我在大约 5 年前使用 SQL Server 数据库发布向导来执行类似的操作,但该产品现在似乎已经失效 - 我尝试安装它,它希望我将我的 SQL Server 版本回归到 2005,所以我不去那里!

【问题讨论】:

    标签: database sql-server-2008 schema transfer management-studio-express


    【解决方案1】:

    不要为此使用 UI。如果您不熟悉 BACKUP/RESTORE 的各个方面,那么 UI 只会将您引向错误的道路,从而获得许多选项。最简单的备份命令是:

    BACKUP DATABASE dbname TO DISK = 'C:\some folder\dbname.bak' WITH INIT;
    

    现在要将其还原为不同的数据库,您需要知道文件名,因为它会尝试将相同的文件放在相同的位置。因此,如果您运行以下命令:

    EXEC dbname.dbo.sp_helpfile;
    

    您应该会看到包含数据和日志文件的名称和路径的输出。构建还原时,您需要使用这些,但将路径替换为新数据库的名称,例如:

    RESTORE DATABASE newname FROM DISK = 'C\some folder\dbname.bak'
      WITH MOVE 'dbname' TO 'C:\path_from_sp_helpfile_output\newname_data.mdf',
      MOVE 'dbname_log' TO 'C:\path_from_sp_helpfile_output\newname_log.ldf';
    

    您必须将dbnamenewname 替换为您的实际数据库名称,并将some folderC:\path_from_sp_helpfile_output\ 替换为您的实际路径。除非我知道这些是什么,否则我无法更具体地回答。


    ** 编辑 **

    这是一个完整的复制品,对我来说完全没问题:

    CREATE DATABASE [DB-A];
    GO
    
    EXEC [DB-A].dbo.sp_helpfile;
    

    部分结果:

    name     fileid filename
    -------- ------ ---------------------------------
    DB-A     1      C:\Program Files\...\DB-A.mdf
    DB-A_log 2      C:\Program Files\...\DB-A_log.ldf
    

    现在我运行备份:

    BACKUP DATABASE [DB-A] TO DISK = 'C:\dev\DB-A.bak' WITH INIT;
    

    当然,如果克隆目标(在本例中为 DB-B)已经存在,您需要删除它:

    USE [master];
    GO
    IF DB_ID('DB-B') IS NOT NULL
    BEGIN
      ALTER DATABASE [DB-B] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
      DROP DATABASE [DB-B];
    END
    GO
    

    现在此还原将成功运行:

    RESTORE DATABASE [DB-B] FROM DISK = 'C:\dev\DB-A.bak'
      WITH MOVE 'DB-A'     TO 'C:\Program Files\...\DB-B.mdf',
           MOVE 'DB-A_log' TO 'C:\Program Files\...\DB-B_log.ldf';
    

    如果您收到有关 BAK 文件内容的错误,那么我建议您确认您确实正在生成一个新文件,并且您在 RESTORE 命令中指向了正确的文件。请尝试上述方法并告诉我它是否有效,并尝试找出您正在做的不同过程的任何部分。

    【讨论】:

    • 谢谢!试试这个。只是检查一下,它应该是RESTORE DATABASE newname FROM DISK = 'C\some folder\dbname.bak' WITH MOVE 'dbname_data' TO 'C:\path_from_sp_helpfile_output\newname_data.mdf', MOVE 'dbname_log' TO 'C:\path_from_sp_helpfile_output\newname_log.ldf';,即 WITH MOVE 'dbname_data' 而不是 WITH MOVE 'dbname'?
    • 就像我说的,这取决于 sp_helpfile 的输出。您不应该输入我写的内容 - 如果 sp_helpfile 的输出显示为dbname,则输入dbname,如果输出显示为dbname_data,则输入dbname_data。我已经看到这两种格式都在使用,但我不知道你的输出是什么样的。
    • 不,那样比较危险,不推荐。如果分离和附加之间出现问题,您现在拥有数据库的完全零副本。 BACKUP/RESTORE 方法是从备份中创建数据库的新副本,同时保留数据库的原始副本。
    • 那么,您在数据库中吗?请查看另一个更新。您需要将数据库设置为单用户模式(并确保您自己不在其中,因为这是第 22 条规则,对吧?)。
    • @Dan 感谢您的接受。但是您也应该养成对有用的答案进行投票的习惯(无论它们最终是否成为最终解决方案)。我在您的个人资料中注意到,您提交的选票少于问题。向上投票有助于鼓励用户帮助您解决问题,尤其是在有多个答案且有多个答案有帮助的情况下(因为您只能接受一个)。我鼓励您重新审视过去的问题并投票。
    【解决方案2】:

    我意识到这是一个老问题,但我也遇到了同样的问题,我发现 UI 比创建脚本更容易和更快。

    我认为 Dan 的问题在于他先创建了新数据库,然后尝试将另一个数据库恢复到其中。我也试过这个,得到了同样的错误。诀窍是不要先创建数据库并在“恢复数据库”过程中命名数据库。

    以下文章对指导您完成此过程有些帮助: http://msdn.microsoft.com/en-us/library/ms186390(v=sql.105).aspx

    【讨论】:

    • 感谢您更新此内容。老实说,我在 Management Studio UI 中缺少的一个简单技巧是,当您选择要还原的 .bak 文件时,在选项选项卡上,有一个复选框,上面写着“覆盖目标数据库”。选中此项可以防止出现无法恢复数据库的错误,因为它已经存在或具有不同的名称等。我现在一直使用它 - 这是缺少的链接!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 2011-07-29
    • 1970-01-01
    • 2011-03-25
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    相关资源
    最近更新 更多