在较低版本上恢复SQL Server数据库备份

222

如何将一个高版本的 SQL Server 数据库备份文件恢复到低版本的 SQL Server 中?

我使用 SQL Server 2008 R2 (10.50.1600) 创建了一个备份文件,现在我想将它恢复到我生产服务器上的 SQL Server 2008 (10.00.1600) 中。

当我尝试将备份还原到 SQL Server 2008 上时,它会出现错误,即 还原失败,因为:

该数据库是在运行版本为10.50.1600的服务器上备份的。 该版本与此服务器不兼容,此服务器正在运行版本 10.00.1600。

如何在此服务器上恢复备份文件?


2
你做不到这个 - 这是不可能的。SQL Server 不允许将一个数据库从高版本降级到低版本。 - marc_s
47
微软对SQL Server(因为他们创建了它)非常了解,但是在两个版本之间移动数据却是不可能的。我简单地不明白为什么导出时不能提供某种兼容模式。这有多难? - dvdmn
2
@PanagiotisKanavos 我不同意,MySQL可以将数据库导出为SQL命令,并在任何版本的MySQL上进行恢复(降级或升级)。是的,您也可以将SQL数据库导出为脚本,但如果您有一些相互依赖的存储函数/过程,则恢复它并不容易。基本上这并不是一个有用的解决方案。 - dvdmn
5
@dvdmn,导出数据库脚本与备份是完全不同的。我知道有些产品没有提供备份/恢复功能,或者更糟糕的是混淆了这两个概念。这通常是由于历史原因造成的:过去缺乏备份功能,一些产品将导出/脚本称为备份。现在他们已经提供了备份功能,他们必须继续解决术语冲突,通过谈论物理和逻辑备份,然后在谈论脚本时混淆它们。 - Panagiotis Kanavos
1
我同意,但这并不改变 SQL Server 备份系统在某些情况下并不完美甚至不好的事实。考虑到许可费用,我希望能有更好的解决方案。PS:可能有点不相关,但连接管理器也很糟糕 :) - dvdmn
显示剩余3条评论
14个回答

151
您可以使用名为“导出数据层应用程序”的功能,它会生成一个包含数据库架构和数据的.bacpac文件。
在目标服务器上,您可以使用“导入数据层应用程序”选项,该选项将从预先创建的.bacpac文件中创建并填充新数据库。
如果您只想传输数据库架构,则可以使用“提取数据层应用程序”来创建文件,并使用“部署数据层应用程序”来部署已创建的数据库架构。
我已经在SQL 2014到SQL 2012以及SQL 2014到SQL 2008R2的不同版本上尝试了这个过程,并且运作良好。

11
这个回答值得更多的关注。它实际上对大多数情况都是有效的。但如果你有一些孤立的SQL用户,导出操作将失败。你总是可以手动添加/删除这些组件来超越SQL版本的限制。 - Doctor Blue
5
我刚刚尝试在我的MSSQLEX2012(V11)上创建一个在MSSQLEX2014(V12)上创建的数据库。我遇到了一个错误,提示“Microsoft.Data.Tools.Schema.Sql.Sql120DatabaseSchemaProvider无效”,但没有任何方法可以更改它。 - Craig
5
使用 .bakpac 从 SQL Server 2014 导入到 2012 是可行的,但需要正确版本的 SSMS。例如,我使用 SSMS 2016 CTP3,它完美地运作了。但是在使用 SSMS 2012 时,它对我来说不起作用。我没有测试过 SSMS 2014。 - Greg Gum
3
有人知道是否可以在T-SQL中编写脚本来执行这个过程吗?更新(自己搜索后回答):你可以通过sqlpackage.exe命令行自动化此过程。搜索更多信息。 - Alex from Jitbit
2
这是唯一对我有效的方案,用于将相当大/复杂的SQL2017降级为SQL2016。性能也非常好。 - Keith Blows
显示剩余4条评论

81
不,无法降级数据库。10.50.1600是SQL Server 2008 R2版本。您绝对无法将此数据库还原或附加到您正在尝试恢复的SQL Server 2008实例(10.00.1600是SQL Server 2008)上。您的唯一选择是:
  • 将此实例升级到SQL Server 2008 R2版本或者
  • 在SQL Server 2008 R2实例上还原您拥有的备份,导出所有数据并将其导入SQL Server 2008数据库。

11
@Gaurav 不要将数据脚本化,而是将整个数据库(表、存储过程、触发器、约束等)脚本化但不包含数据,创建新的数据库后,右键单击源数据库,进入“工具”,然后选择“导出数据”来将表中的内容转移至你的数据库中。 - Jim McLeod
31
我非常怀疑“没有可能的方法”这样的简单回答 - 这只是意味着你还没有找到方法而已。你想要做这件事情可能有很多原因,所以这并不是一个有帮助的回答。 - Jay Imerman
6
我不同意,@Jay,有时“你不能”是完美的答案,虽然更好的做法是在可能的情况下提供解决办法。 - Russell Fox
1
@张,如果你有问题,请将它们提出来作为问题,而不是评论。 - Remus Rusanu
2
veljasije的回答有一个简单的解决方法。不明白为什么一个“不可能”的答案被标记为答案,当有一个简单的解决方案可以在不升级的情况下实现它。 - serge
显示剩余2条评论

42
无法将在较高版本中创建的数据库(或附加)恢复到较低版本。唯一的方法是为所有对象创建脚本,并使用脚本生成数据库。

enter image description here

选择“模式和数据”- 如果您想将两者都纳入备份脚本文件中
选择仅模式 - 如果只需要模式。

enter image description here

是的,现在您已经完成了创建带有数据库模式和数据的脚本。


1
这是2020年,那就是现在最好的答案! - d.popov
3
只有当数据库大小在几个千兆字节以下时,才能使用SSMS读取文件。否则,文件将太大无法读取。 - Josh J

38

不一定有效

有效

  • 脚本生成 - 任务 -> 生成脚本。确保在 设置脚本选项 -> 高级 页面上设置所需的目标 SQL Server 版本。您还可以选择是否复制架构、数据或两者。请注意,在生成的脚本中,如果从非 Express 迁移到 Express 或反之,则可能需要更改 MDF/LDF 文件的 DATA 文件夹。

  • Microsoft SQL Server 数据库发布服务 - 随 SQL Server 2005 及以上版本提供,我认为。从这里下载最新版本。前提条件:sqlncli.msi/sqlncli_x64.msi/sqlncli_ia64.msiSQLServer2005_XMO.msi/SQLServer2005_XMO_x64.msi/SQLServer2005_XMO_ia64.msi(从这里下载)。


8
对于大规模数据库而言,脚本生成的结果不可靠,如果可能的话应该避免使用。 - Chris
底部的两个链接都是404。 - Sнаđошƒаӽ
1
根据 https://learn.microsoft.com/en-us/sql/relational-databases/databases/use-the-copy-database-wizard?view=sql-server-ver15 ,复制数据库选项将无法工作,因为“数据库无法移动或复制到较早版本的 SQL Server”。 - sparrow

31

以下是我对完成此操作的不同选项的个人意见:

第三方工具: 完成任务最简单的方法可能是在低版本上创建一个空数据库,然后使用第三方工具读取备份并将新创建的数据库与备份进行同步。

Red gate 是最受欢迎的工具之一,但还有许多其他工具,如 ApexSQL DiffApexSQL Data DiffAdept SQLIdera 等等。这些都是高级工具,但您可以在试用模式下完成任务 ;)

生成脚本: 正如其他人已经提到的,您可以使用 SSMS 脚本结构和数据,但您需要考虑执行顺序。默认情况下,对象脚本的顺序不正确,您必须处理依赖关系。如果数据库很大并且具有许多对象,则可能会出现问题。

导入和导出向导: 这不是理想的解决方案,因为它只会还原数据表而不是所有对象,但在需要快速解决问题时可以考虑使用它。


1
Red Gate Sql Clone不支持在不同版本的SQL Server之间进行克隆,报告的错误与我手动尝试时得到的完全相同。 - DarkDeny
现在你可以使用Visual Studio Community了。进入工具 => SQL Server => 模式比较。在目标服务器上创建一个新的空数据库,然后使用模式比较工具更新其中的模式。然后使用数据比较工具,在比较后复制所有数据。这个工具非常出色。我刚刚使用它将一个数据库从最新的SQL服务器复制到了一个2016服务器上。完全没有问题。只花了十分钟。 - undefined

19

另一种方法是使用“复制数据库”功能:

右键单击源数据库,选择“任务” > “复制数据库”。

您可以将数据库复制到较低版本的 SQL Server 实例。这在我从 SQL Server 2008 R2 (SP1) - 10.50.2789.0 到 Microsoft SQL Server 2008 (SP2) - 10.0.3798.0 的转移中运作良好。


4
请注意,如果目标是SQL Server Express,则此方法不可行。“目标服务器不能是SQL Server 2005或更高版本的Express实例。” http://social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/a40a5867-a46a-478f-bf0d-52cc423b712b/ - Ohad Schneider
3
以此方式无法将数据库从 SQL Server 2012 复制到 SQL Server 2008。 - Twinkles
1
复制数据库就是一种分离/附加操作。 - Panagiotis Kanavos
1
谢谢这个提示!那帮了我很多。我把数据从SQL 2008 R2复制到了SQL 2008。 - dns_nx
1
我在SSMS 18.4中没有看到这个选项。可能因人而异。 - Ben

8

进入 任务->生成脚本...

"脚本的数据类型" 中选择 "架构和数据",并尝试在较低版本中运行此脚本。


6
这是一个非常好的解决方案,但在处理大型数据库时效果很差。 - veljasije

8

您可以尝试以下方法:

  1. 在 SQL Server 2008 中创建数据库。
  2. 使用“导入数据”功能从 SQL Server R2(或更高版本)导入数据。
  3. 使用“RedGate SQLCompare”同步脚本。

5

虽然不太好看,但这就是我做的方式,前提是你已经安装了 SQL 2008 R2。

1)在 SQL Server 2008 R2 中右键单击数据库,“任务”→“生成脚本”,选择向导中的整个数据库和对象。在“设置脚本选项”步骤中,您应该会看到一个“高级”按钮,请选择它并确保选择“为服务器版本编写脚本”= SQL Server 2008”,而不是R2版本。这是一个至关重要的步骤,因为仅“导入数据”无法带来所有主键、限制和任何其他对象(如存储过程)。

2)在新安装或数据库实例 SQL Express 或 SQL Server 2008 上运行生成的 SQL 脚本,使用查询窗口或打开保存的 .sql 脚本并执行,您应该会看到新的数据库。

3)现在,在新的数据库上右键单击,选择“任务”→“导入数据”,将源选择为 R2 数据库,目标选择为新数据库。选择“从一个或多个表或视图复制数据”,选择顶部复选框以选择所有表,然后下一步,运行包,您应该可以在旧版本上找到所有内容。这也适用于退回到 2005 版本。希望对某人有所帮助。


嗨@motogeek,我有同样的问题,但是我在生产服务器上使用R2,本地使用2008,在这种情况下,我不能使用导入和导出数据。那么什么是最理想的解决方案呢? - Abbas

2

你可以使用BCP导入和导出小型表格。

BCP OUT命令:

BCP "SELECT *  FROM [Dinesh].[dbo].[Invoices]" QUERYOUT C:\av\Invoices1.txt -S MC0XENTC -T -c -r c:\error.csv

BCP IN 命令:- 创建 Invoicescopy1 表的结构。

BCP [Dinesh].[dbo].[Invoicescopy1] IN C:\av\Invoices.txt -S MC0XENTC -T -c

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接