325

我有一个 MS SQL Server 2008 Express 系统,其中包含一个我想“复制和重命名”(用于测试目的)的数据库,但我不知道实现此目的的简单方法。

我注意到在 R2 版本的 SQL Server 中有一个复制数据库向导,但遗憾的是我无法升级。

有问题的数据库围绕着一个演出。我试图将要复制到新数据库中的数据库的备份还原,但没有成功。

4

16 回答 16

442
  1. 安装 Microsoft SQL Management Studio,您可以从 Microsoft 网站免费下载:

    2008 版

    Microsoft SQL Management Studio 2008 是具有高级服务的 SQL Server 2008 Express的一部分

    2012 版

    点击下载按钮并检查ENU\x64\SQLManagementStudio_x64_ENU.exe

    2014 版

    单击下载按钮并检查 MgmtStudio64BIT\SQLManagementStudio_x64_ENU.exe

  2. 打开Microsoft SQL 管理工作室

  3. 将原始数据库备份到 .BAK 文件(db -> 任务 -> 备份)。
  4. 使用新名称(克隆)创建空数据库。请注意下面的注释,因为这是可选的。
  5. 单击以克隆数据库并打开还原对话框(见图) 恢复对话框
  6. 选择设备并添加步骤 3 中的备份文件。 添加备份文件
  7. 将目标更改为测试数据库 更改目的地
  8. 更改数据库文件的位置,它必须与原始位置不同。您可以直接在文本框中输入,只需添加后缀。(注意:顺序很重要。选择复选框,然后更改文件名。) 换地点
  9. 检查 WITH REPLACE 和 WITH KEEP_REPLICATION 用替换
于 2014-10-08T20:14:56.150 回答
120

右键单击要克隆的数据库,单击Tasks,单击Copy Database...。按照向导操作,您就完成了。

于 2010-09-30T18:37:29.027 回答
103

您可以尝试分离数据库,在命令提示符下将文件复制到新名称,然后附加两个数据库。

在 SQL 中:

USE master;
GO 
EXEC sp_detach_db
    @dbname = N'OriginalDB';
GO

在命令提示符下(为了这个示例,我简化了文件路径):

copy c:\OriginalDB.mdf c:\NewDB.mdf
copy c:\OriginalDB.ldf c:\NewDB.ldf

再次在 SQL 中:

USE master;
GO
CREATE DATABASE OriginalDB
    ON (FILENAME = 'C:\OriginalDB.mdf'),
       (FILENAME = 'C:\OriginalDB.ldf')
    FOR ATTACH;
GO
CREATE DATABASE NewDB
    ON (FILENAME = 'C:\NewDB.mdf'),
       (FILENAME = 'C:\NewDB.ldf')
    FOR ATTACH;
GO
于 2010-09-30T13:27:08.313 回答
34

事实证明,我曾错误地尝试从备份中恢复。

最初我创建了一个新数据库,然后尝试在此处恢复备份。我应该做的以及最终起作用的是打开恢复对话框并在目标字段中输入新数据库的名称。

所以,简而言之,从备份中恢复就可以了。

感谢所有反馈和建议的家伙

于 2010-10-01T12:55:39.623 回答
23

这是我使用的脚本。有点棘手,但它有效。在 SQL Server 2012 上测试。

DECLARE @backupPath nvarchar(400);
DECLARE @sourceDb nvarchar(50);
DECLARE @sourceDb_log nvarchar(50);
DECLARE @destDb nvarchar(50);
DECLARE @destMdf nvarchar(100);
DECLARE @destLdf nvarchar(100);
DECLARE @sqlServerDbFolder nvarchar(100);

SET @sourceDb = 'db1'
SET @sourceDb_log = @sourceDb + '_log'
SET @backupPath = 'E:\DB SQL\MSSQL11.MSSQLSERVER\MSSQL\Backup\' + @sourceDb + '.bak'    --ATTENTION: file must already exist and SQL Server must have access to it
SET @sqlServerDbFolder = 'E:\DB SQL\MSSQL11.MSSQLSERVER\MSSQL\DATA\'
SET @destDb = 'db2'
SET @destMdf = @sqlServerDbFolder + @destDb + '.mdf'
SET @destLdf = @sqlServerDbFolder + @destDb + '_log' + '.ldf'

BACKUP DATABASE @sourceDb TO DISK = @backupPath

RESTORE DATABASE @destDb FROM DISK = @backupPath
WITH REPLACE,
   MOVE @sourceDb     TO @destMdf,
   MOVE @sourceDb_log TO @destLdf
于 2014-03-14T15:34:55.820 回答
13

这里提到的所有解决方案都不适合我——我使用的是 SQL Server Management Studio 2014。

相反,我不得不取消选中“选项”屏幕中的“恢复前进行尾日志备份”复选框:在我的版本中,默认情况下它被选中并阻止完成恢复操作。取消选中后,还原操作继续进行,没有问题。

在此处输入图像描述

于 2017-05-23T08:42:22.820 回答
9

使用 MS SQL Server 2012,您需要执行 3 个基本步骤:

  1. 首先,生成.sql只包含源数据库结构的文件

    • 右键单击源数据库然后任务然后生成脚本
    • 按照向导并在.sql本地保存文件
  2. 二、将源数据库替换为.sql文件中的目标数据库

    • 右键单击目标文件,选择新建查询Ctrl-H或(编辑-查找和替换-快速替换
  3. 最后,填充数据

    • 右键单击目标数据库,然后选择任务导入数据
    • 数据源下拉设置为“ .net framework data provider for SQL server ” + 设置 DATA 下的连接字符串文本字段,例如:Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
    • 对目的地做同样的事情
    • 选中您要转移的表或“源:...”旁边的复选框以检查所有表

你完成了。

于 2015-01-09T11:04:46.827 回答
8

来自 SSMS:

1 - 将原始数据库备份到 .BAK 文件(your_source_db -> 任务 -> 备份)。

2 - 右键单击​​“数据库”和“恢复数据库”

3 - 设备 > ...(按钮)> 添加 > 选择 your_source_db.bak

4 - 在“常规”选项卡的“目标”部分中,将“数据库”中的 your_source_db 重命名为 new_name_db

5 - 在“文件”选项卡中,勾选“将所有文件重新定位到文件夹”,

  • 在“恢复为”列中重命​​名两个法线以与 new_name_db (.mdf, _log.ldf) 保持一致

6 - 在“选项”选项卡的“恢复选项”部分,勾选两个第一个选项(“覆盖...”、“保留...”)和“恢复状态”:“恢复时恢复”

  • 还要确保在“尾日志备份”部分选项未选中,以避免将源数据库保持在“恢复状态”!
于 2021-05-12T14:31:26.810 回答
6

如果数据库不是很大,您可以查看 SQL Server Management Studio Express 中的“脚本数据库”命令,这些命令位于资源管理器中数据库项本身的上下文菜单中。

您可以选择要编写的全部内容;当然,您需要对象和数据。然后,您将把整个脚本保存到一个文件中。然后您可以使用该文件重新创建数据库;只需确保USE顶部的命令设置为正确的数据库即可。

于 2010-09-30T09:39:48.247 回答
6

在 SQL Server 2008 R2 中,将数据库作为文件备份到文件夹中。然后选择出现在“数据库”文件夹中的恢复选项。在向导中,输入您希望在目标数据库中使用的新名称。并选择从文件中恢复并使用您刚刚创建的文件。我只是做到了,而且速度非常快(我的数据库很小,但仍然如此)巴勃罗。

于 2012-11-14T16:43:07.327 回答
5

基于此评论的解决方案:https ://stackoverflow.com/a/22409447/2399045 。只需设置设置:数据库名称、临时文件夹、数据库文件文件夹。运行后,您将获得名称为“sourceDBName_yyyy-mm-dd”格式的数据库副本。

-- Settings --
-- New DB name will have name = sourceDB_yyyy-mm-dd
declare @sourceDbName nvarchar(50) = 'MyDbName';
declare @tmpFolder nvarchar(50) = 'C:\Temp\'
declare @sqlServerDbFolder nvarchar(100) = 'C:\Databases\'

--  Execution --
declare @sourceDbFile nvarchar(50);
declare @sourceDbFileLog nvarchar(50);
declare @destinationDbName nvarchar(50) = @sourceDbName + '_' + (select convert(varchar(10),getdate(), 121))
declare @backupPath nvarchar(400) = @tmpFolder + @destinationDbName + '.bak'
declare @destMdf nvarchar(100) = @sqlServerDbFolder + @destinationDbName + '.mdf'
declare @destLdf nvarchar(100) = @sqlServerDbFolder + @destinationDbName + '_log' + '.ldf'

SET @sourceDbFile = (SELECT top 1 files.name 
                    FROM sys.databases dbs 
                    INNER JOIN sys.master_files files 
                        ON dbs.database_id = files.database_id 
                    WHERE dbs.name = @sourceDbName
                        AND files.[type] = 0)

SET @sourceDbFileLog = (SELECT top 1 files.name 
                    FROM sys.databases dbs 
                    INNER JOIN sys.master_files files 
                        ON dbs.database_id = files.database_id 
                    WHERE dbs.name = @sourceDbName
                        AND files.[type] = 1)

BACKUP DATABASE @sourceDbName TO DISK = @backupPath

RESTORE DATABASE @destinationDbName FROM DISK = @backupPath
WITH REPLACE,
   MOVE @sourceDbFile     TO @destMdf,
   MOVE @sourceDbFileLog  TO @destLdf
于 2018-02-15T11:58:06.657 回答
4

另一种通过使用导入/导出向导来解决问题的方法,首先创建一个空数据库,然后选择源数据库作为您的服务器的源,然后在目标中选择与目标数据库相同的服务器(使用空数据库您首先创建),然后点击完成

它将创建所有表并将所有数据传输到新数据库中,

于 2016-10-10T16:12:42.740 回答
4

基于乔回答的脚本(分离、复制文件、附加两者)。

  1. 以管理员帐户运行管理工作室。

这不是必需的,但可能在执行时访问被拒绝错误。

  1. 配置 sql server 以执行 xp_cmdshel
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
  1. 运行脚本,但在之前输入您的数据库名称@dbName@copyDBName变量。
USE master;
GO 

DECLARE @dbName NVARCHAR(255) = 'Products'
DECLARE @copyDBName NVARCHAR(255) = 'Products_branch'

-- get DB files
CREATE TABLE ##DBFileNames([FileName] NVARCHAR(255))
EXEC('
    INSERT INTO ##DBFileNames([FileName])
    SELECT [filename] FROM ' + @dbName + '.sys.sysfiles')

-- drop connections
EXEC('ALTER DATABASE ' + @dbName + ' SET OFFLINE WITH ROLLBACK IMMEDIATE')

EXEC('ALTER DATABASE ' + @dbName + ' SET SINGLE_USER')

-- detach
EXEC('EXEC sp_detach_db @dbname = ''' + @dbName + '''')

-- copy files
DECLARE @filename NVARCHAR(255), @path NVARCHAR(255), @ext NVARCHAR(255), @copyFileName NVARCHAR(255), @command NVARCHAR(MAX) = ''
DECLARE 
    @oldAttachCommand NVARCHAR(MAX) = 
        'CREATE DATABASE ' + @dbName + ' ON ', 
    @newAttachCommand NVARCHAR(MAX) = 
        'CREATE DATABASE ' + @copyDBName + ' ON '

DECLARE curs CURSOR FOR 
SELECT [filename] FROM ##DBFileNames
OPEN curs  
FETCH NEXT FROM curs INTO @filename
WHILE @@FETCH_STATUS = 0  
BEGIN
    SET @path = REVERSE(RIGHT(REVERSE(@filename),(LEN(@filename)-CHARINDEX('\', REVERSE(@filename),1))+1))
    SET @ext = RIGHT(@filename,4)
    SET @copyFileName = @path + @copyDBName + @ext

    SET @command = 'EXEC master..xp_cmdshell ''COPY "' + @filename + '" "' + @copyFileName + '"'''
    PRINT @command
    EXEC(@command);

    SET @oldAttachCommand = @oldAttachCommand + '(FILENAME = "' + @filename + '"),'
    SET @newAttachCommand = @newAttachCommand + '(FILENAME = "' + @copyFileName + '"),'

    FETCH NEXT FROM curs INTO @filename
END
CLOSE curs 
DEALLOCATE curs

-- attach
SET @oldAttachCommand = LEFT(@oldAttachCommand, LEN(@oldAttachCommand) - 1) + ' FOR ATTACH'
SET @newAttachCommand = LEFT(@newAttachCommand, LEN(@newAttachCommand) - 1) + ' FOR ATTACH'

-- attach old db
PRINT @oldAttachCommand
EXEC(@oldAttachCommand)

-- attach copy db
PRINT @newAttachCommand
EXEC(@newAttachCommand)

DROP TABLE ##DBFileNames
于 2018-02-15T10:45:03.457 回答
3

您可以只创建一个新数据库,然后转到任务,导入数据,然后将要复制的数据库中的所有数据导入刚刚创建的数据库。

于 2018-07-04T19:08:06.833 回答
0

<!doctype html>

<head>
    <title>Copy Database</title>
</head>

<body>
    
    <?php
    
    $servername = "localhost:xxxx";
    $user1 = "user1";
    $pw1 = "pw1";
    $db1 = "db1";
    
    $conn1 = new mysqli($servername,$user1,$pw1,$db1);
    
    if($conn1->connect_error) {
        die("Conn1 failed: " . $conn1->connect_error);
    }
    
    $user2 = "user2";
    $pw2 = "pw2";
    $db2 = "db2";
    
    $conn2 = new mysqli($servername,$user2,$pw2,$db2);
    
    if($conn2->connect_error) {
        die("Conn2 failed: " . $conn2->connect_error);
    }
    
    $sqlDB1 = "SELECT * FROM table1";
    $resultDB1 = $conn1->query($sqlDB1);
    
    if($resultDB1->num_rows > 0) {
        while($row = $resultDB1->fetch_assoc()) {
            $sqlDB2 = "INSERT INTO table2 (col1, col2) VALUES ('" . $row["tableRow1"] . "','" . $row["tableRow2"] . "')";
            $resultDB2 = $conn2->query($sqlDB2);
        }
    }else{
        echo "0 results";
    }
    
    $conn1->close();
    $conn2->close();
    
    ?>
    
</body>
于 2021-10-11T09:22:30.510 回答
0

该程序以不同的名称将数据库复制到同一台服务器。我依靠这个网站上给出的例子进行了一些改进。

-- Copies a database to the same server
-- Copying the database is based on backing up the original database and restoring with a different name

DECLARE @sourceDb nvarchar(50);    
DECLARE @destDb nvarchar(50);
DECLARE @backupTempDir nvarchar(200)

SET @sourceDb =  N'Northwind'         -- The name of the source database
SET @destDb =    N'Northwind_copy'    -- The name of the target database
SET @backupTempDir = N'c:\temp'       -- The name of the temporary directory in which the temporary backup file will be saved
-- --------- ---

DECLARE @sourceDb_ROWS nvarchar(50);  
DECLARE @sourceDb_LOG nvarchar(50);
DECLARE @backupPath nvarchar(400); 
DECLARE @destMdf nvarchar(100);
DECLARE @destLdf nvarchar(100);
DECLARE @sqlServerDbFolder nvarchar(100);

Declare @Ret as int = -1
Declare @RetDescription nvarchar(200) = ''

-- Temporary backup file name
SET @backupPath = @backupTempDir+ '\TempDb_' + @sourceDb + '.bak'    

-- Finds the physical location of the files on the disk
set @sqlServerDbFolder = (SELECT top(1) physical_name as dir
                           FROM sys.master_files where DB_NAME(database_id) = @sourceDb  );

-- Clears the file name and leaves the directory name
set @sqlServerDbFolder = REVERSE(SUBSTRING(REVERSE(@sqlServerDbFolder), CHARINDEX('\', REVERSE(@sqlServerDbFolder)) + 1, LEN(@sqlServerDbFolder))) + '\'

-- Finds the logical name for the .mdf file
set @sourceDb_ROWS = (SELECT f.name LogicalName FROM sys.master_files f INNER JOIN sys.databases d ON d.database_id = f.database_id
                      where d.name = @sourceDb  and   f.type_desc = 'ROWS' )

-- Finds the logical name for the .ldf file
set @sourceDb_LOG = (SELECT f.name LogicalName FROM sys.master_files f INNER JOIN sys.databases d ON d.database_id = f.database_id
                      where d.name = @sourceDb  and   f.type_desc = 'LOG' )

-- Composes the names of the physical files for the new database  
SET @destMdf = @sqlServerDbFolder + @destDb + N'.mdf'
SET @destLdf = @sqlServerDbFolder + @destDb + N'_log' + N'.ldf'

-- If the source name is the same as the target name does not perform the operation
if @sourceDb <> @destDb      
    begin 

    -- Checks if the target database already exists
    IF Not EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = @destDb)
    begin 
        -- Checks if the source database exists
        IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = @sourceDb) and (@sqlServerDbFolder is not null)
        begin 

            -- Opens the permission to run xp_cmdshell
            EXEC master.dbo.sp_configure 'show advanced options', 1
            RECONFIGURE WITH OVERRIDE
            EXEC master.dbo.sp_configure 'xp_cmdshell', 1
            RECONFIGURE WITH OVERRIDE
         
            -- If the temporary backup directory does not exist it creates it
            declare @md as nvarchar(100) = N'if not exist ' + @backupTempDir + N' md ' +@backupTempDir  
            exec xp_cmdshell  @md,  no_output

            -- Creates a backup to the source database to the temporary file
            BACKUP DATABASE @sourceDb TO DISK = @backupPath 

            -- Restores the database with a new name
            RESTORE DATABASE @destDb FROM DISK = @backupPath
            WITH REPLACE, 
            MOVE @sourceDb_ROWS TO @destMdf, 
            MOVE @sourceDb_LOG TO  @destLdf

            -- Deletes the temporary backup file
            declare @del as varchar(100) = 'if exist ' + @backupPath +' del ' +@backupPath 
            exec xp_cmdshell  @del ,  no_output

            -- Close the permission to run xp_cmdshell
            EXEC master.dbo.sp_configure 'xp_cmdshell', 0
            RECONFIGURE WITH OVERRIDE
            EXEC master.dbo.sp_configure 'show advanced options', 0
            RECONFIGURE WITH OVERRIDE
         
            set @ret = 1
            set @RetDescription = 'The ' +@sourceDb + ' database was successfully copied to ' + @destDb 
        
        end
        else
        begin
          set @RetDescription = 'The source database '''+ @sourceDb + ''' is not exists.'
          set @ret = -3
        end

    end
    else
    begin
      set @RetDescription = 'The target database '''+ @destDb + ''' already exists.'
      set @ret = -4
    end
end
else
begin
  set @RetDescription = 'The target database ''' +@destDb + ''' and the source database '''+ @sourceDb + ''' have the same name.'
  set @ret = -5
end

select @ret as Ret, @RetDescription as RetDescription
于 2022-01-21T14:23:58.983 回答