如果我需要将数据库从SQL Server 2012(32位)移动到SQL Server 2005(64位),该怎么办?

我知道我不能:


在SQL Server 2005上恢复数据库的备份
分离并附加

我知道我可以:


使用导入数据向导,我在一个数据库上尝试过它,但是它只能移动数据,即使那样也很麻烦,因为我需要做大量工作来创建临时表来维护标识列,重新创建所有FK,索引等。还有更简单的选择吗?

评论

老实说,更简单的选择是将目的地升级到2012年。

#1 楼

您可以按照以下任何一种方法进行操作:

注意:如果您使用的是任何新功能,例如新数据类型等,则必须进行测试,因为它会引发错误。

方法1:使用本机工具



编写数据库SCHEMA_ONLY,然后在目标服务器上重新创建一个空数据库。以下是屏幕截图:







使用BCP OUT和BULK INSERT插入数据。

下面是可以帮助您完成第2部分的脚本。

/************************************************************************************************************************************************
Author      :   KIN SHAH    *********************************************************************************************************************
Purpose     :   Move data from one server to another*********************************************************************************************
DATE        :   05-28-2013  *********************************************************************************************************************
Version     :   1.0.0   *************************************************************************************************************************
RDBMS       :   MS SQL Server 2008R2 and 2012   *************************************************************************************************
*************************************************************************************************************************************************/

-- save below output in a bat file by executing below in SSMS in TEXT mode
-- clean up: create a bat file with this command --> del D:\BCP_OUT\*.dat 

select '"C:\Program Files\Microsoft SQL Server0\Tools\Binn\bcp.exe" '-- path to BCP.exe
        +  QUOTENAME(DB_NAME())+ '.'                                    -- Current Database
        +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.'            
        +  QUOTENAME(name)  
        +  ' out D:\BCP_OUT\'                                           -- Path where BCP out files will be stored
        +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_' 
        +  REPLACE(name,' ','') 
        + '.dat -T -E -SSERVERNAME\INSTANCE -n'                         -- ServerName, -E will take care of Identity, -n is for Native Format
from sys.tables
where is_ms_shipped = 0 and name <> 'sysdiagrams'                       -- sysdiagrams is classified my MS as UserTable and we dont want it
and schema_name(schema_id) <> 'some_schema_exclude'                     -- Optional to exclude any schema 
order by schema_name(schema_id)                         



--- Execute this on the destination server.database from SSMS.
--- Make sure the change the @Destdbname and the bcp out path as per your environment.

declare @Destdbname sysname
set @Destdbname = 'destination_database_Name'               -- Destination Database Name where you want to Bulk Insert in
select 'BULK INSERT '                                       -- Remember Tables **must** be present on destination Database
        +  QUOTENAME(@Destdbname)+ '.'
        +  QUOTENAME(SCHEMA_NAME(SCHEMA_ID))+'.' 
        +  QUOTENAME(name) 
        + ' from ''D:\BCP_OUT\'                             -- Change here for bcp out path
        +  REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'
        +  REPLACE(name,' ','') 
        +'.dat'' 
        with (
        KEEPIDENTITY,
        DATAFILETYPE = ''native'',  
        TABLOCK
        )'  + char(10) 
        + 'print ''Bulk insert for '+REPLACE(SCHEMA_NAME(schema_id),' ','') + '_'+  REPLACE(name,' ','')+' is done... '''+ char(10)+'go' 
from sys.tables
where is_ms_shipped = 0 and name <> 'sysdiagrams'           -- sysdiagrams is classified my MS as UserTable and we dont want it
and schema_name(schema_id) <> 'some_schema_exclude'         -- Optional to exclude any schema 
order by schema_name(schema_id)


方法2:使用第三方工具

在目标服务器上创建一个空白数据库。使用Redgate的模式比较和数据比较来创建数据并将其加载到目标服务器中。正在使用第三方工具,那么我的建议是Redgate。

评论


+1,但请记住,有些事情在目的地是行不通的(而且我不确定第三方工具如何处理所有这些问题)。诸如SEQUENCEs之类的对象,诸如OFFSET / FETCH,LAG / LEAD之类的代码等

–亚伦·伯特兰(Aaron Bertrand)
2013年12月15日20:17

一旦通过脚本编写脚本并在较旧的数据库上运行这些脚本而创建了架构,用于传输数据的另一种方法是通过设置链接服务器将一个实例直接复制到另一个实例。编写完成所有工作的循环应该不难。要处理FK约束,您需要确保以适当的顺序复制表,或者可以临时删除FK并在复制后重新启用它们。同样,您将要在复制期间禁用目标中的所有触发器。

– David Spillett
2015年12月8日13:06

#2 楼

除了此处已建议的方法外,您还可以尝试创建BACPAC文件并将其导入到目标位置。
这类似于Microsoft建议将数据库从本地迁移到Azure云数据库的方式。

它的好处是它既可以导出模式又可以导出数据,并且不依赖于数据库版本,因此从理论上讲,您可以将数据库从任何版本导入到任何版本。 />缺点是,它在从源头生成BACPAC文件之前,会运行某种严格的验证过程,如果您对数据库外部的对象(用户数据库或系统数据库)进行了引用,或者您已经加密了对象。但是,如果您很幸运并且没有失败,那么它可以是一个非常简单的解决方案。

您需要的只是更新的SSMS版本(17或18)之一: https://docs.microsoft.com/zh-cn/sql/ssms/download-sql-server-management-studio-ssms

要开始创建BACPAC文件,请右键单击数据库并选择“导出数据层应用程序...”(请确保不要与“提取数据层应用程序...”混淆)。



将为您提供一个简单的向导,以指导您完成这些步骤。
完成后,您可以在目标服务器中使用“导入数据层应用程序...”,您可以通过右键单击“数据库”节点查看(同样,不要与“部署数据层应用程序...”混淆):



此,也将向您显示一个简单的向导来指导您完成这些步骤。

#3 楼

降低Sql Server的版本非常艰巨。
有一些减少的选择,例如:
首先,创建所有数据库对象脚本并在目标服务器上运行。
之后就可以使用了;


SSIS,
导入数据工具,
第三方工具,例如RedGate或其他。


但是对于RedGate数据比较工具


,您必须考虑到它仅比较具有主键的表。因此,如果您的表没有主键,则必须使用其他方式


评论


我认为这个答案不会比Kins答案更好

–詹姆斯·安德森(James Anderson)
2015年12月8日,11:27

#4 楼

在SQL Server上降级数据库是不可能的。但是,一种解决方法是编写所有数据库对象的脚本,然后将该脚本应用于目标数据库。 SSIS是帮助执行此操作的好方法。

评论


您是否认为这对Kin的回答有重要意义?

– dezso
17年5月10日13:56