复制SQL Server 2008数据库并重命名

ama*_*eur 11 sql database sql-server-2008 sql-server-2012

我有一个SQL Server 2008数据库,我想复制并在服务器上创建一个新的数据库(使用不同的名称).我不关心维护数据,可以创建没有数据的新数据库.我要做的是以下内容:

  • 创建旧数据库的新数据库维护结构
  • 设置新数据库的名称
  • 将所有varchar和char数据类型更改为nvarchar和nchar
  • 将所有文本数据类型更改为nvarchar(MAX)

顺便说一句,我还有两个问题不属于我的任务,但我想考虑以下问题:

  • 如何将sql server数据库升级到sql server 2012
  • 我需要在数据库上进行任何准备工作,以确保我可以轻松升级它吗?

Aar*_*and 30

这确实是多个问题的组合.


问题1和2

  • 创建旧数据库的新数据库维护结构
  • 设置新数据库的名称

最简单的备份命令是:

BACKUP DATABASE dbname TO DISK = 'C:\some folder\dbname.bak' WITH INIT;
-- or WITH INIT, COMPRESSION if you are on Enterprise or Developer
Run Code Online (Sandbox Code Playgroud)

现在要将其恢复为另一个数据库,您需要知道文件名,因为它会尝试将相同的文件放在同一个地方.因此,如果您运行以下内容:

EXEC dbname.dbo.sp_helpfile;
Run Code Online (Sandbox Code Playgroud)

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

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';
Run Code Online (Sandbox Code Playgroud)

你必须更换dbname,并newname与实际的数据库名称,也C:\some folderC:\path_from_sp_helpfile_output\你的实际路径.除非我知道那些是什么,否则我无法在答案中得到更具体的解释.


这是一个完整的repro:

CREATE DATABASE [DB-A];
GO

EXEC [DB-A].dbo.sp_helpfile;
Run Code Online (Sandbox Code Playgroud)

部分结果:

name     fileid filename
-------- ------ ---------------------------------
DB-A     1      C:\Program Files\...\DB-A.mdf
DB-A_log 2      C:\Program Files\...\DB-A_log.ldf
Run Code Online (Sandbox Code Playgroud)

现在我运行备份:

BACKUP DATABASE [DB-A] TO DISK = 'C:\dev\DB-A.bak' WITH INIT;
Run Code Online (Sandbox Code Playgroud)

当然,如果克隆目标(在这种情况下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
Run Code Online (Sandbox Code Playgroud)

现在,此还原将成功运行,为您提供DB-A的副本,重命名为DB-B:

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';
Run Code Online (Sandbox Code Playgroud)

问题3和4

  • 将所有varchar和char数据类型更改为nvarchar和nchar
  • 将所有文本数据类型更改为nvarchar(MAX)

重构是一个主要的痛苦,特别是如果这些列中的一些参与约束.您可以通过这种方式构建一个非常基本的脚本,但是您需要更多的工业强度来处理所有这些变量.这假设所有列都可以为空并且不参与约束.

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += '
  ALTER TABLE ' + 
  QUOTENAME(OBJECT_SCHEMA_NAME(c.[object_id])) 
  + '.' + QUOTENAME(OBJECT_NAME(c.[object_id]))
  + ' ALTER COLUMN ' + QUOTENAME(c.name) + ' '
  + CASE t.name WHEN N'text' 
     THEN N'nvarchar(max)' 
     ELSE N'n' + t.name + '(' + RTRIM(c.max_length) + ')'
  END + ';'
FROM sys.columns AS c
INNER JOIN sys.types AS t
ON c.user_type_id = t.user_type_id
WHERE c.system_type_id IN (35, 167, 175)
AND OBJECTPROPERTY(c.[object_id], 'IsMsShipped') = 0;

PRINT @sql;
-- EXEC sp_executesql @sql;
Run Code Online (Sandbox Code Playgroud)

您可以使用PRINT输出来验证脚本的前8K,当您认为它看起来不错时,取消注释EXEC.

完成后,您将需要重建所有索引.

也就是说,像Tony建议的那样编写数据库(或使用Red Gate的SQL Compare之类的工具- 或其中一个替代方案 - 针对空数据库)可能要容易得多,特别是如果其中一些列参与约束 -可能需要删除并重新创建才能更改类型.


问题5和6

  • 如何将sql server数据库升级到sql server 2012
  • 我需要在数据库上进行任何准备工作,以确保我可以轻松升级它吗?

您无法仅在2008实例上升级单个数据库.您要么就地升级,要么设置一个新实例(如Tony描述的那样),然后迁移您的数据库(最好使用备份/恢复 - 很多人会告诉您分离/附加,但这样安全性要差得多).你应该做的准备工作包括:

升级后,您需要:

  • 将兼容级别设置为110
  • 更新所有统计信息