我有一个 MS SQL Server 2008 Express 系统,其中包含一个我想“复制和重命名”(用于测试目的)的数据库,但我不知道实现此目的的简单方法。
我注意到在 R2 版本的 SQL Server 中有一个复制数据库向导,但遗憾的是我无法升级。
有问题的数据库围绕着一个演出。我试图将要复制到新数据库中的数据库的备份还原,但没有成功。
我有一个 MS SQL Server 2008 Express 系统,其中包含一个我想“复制和重命名”(用于测试目的)的数据库,但我不知道实现此目的的简单方法。
我注意到在 R2 版本的 SQL Server 中有一个复制数据库向导,但遗憾的是我无法升级。
有问题的数据库围绕着一个演出。我试图将要复制到新数据库中的数据库的备份还原,但没有成功。
安装 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
打开Microsoft SQL 管理工作室。
右键单击要克隆的数据库,单击Tasks
,单击Copy Database...
。按照向导操作,您就完成了。
您可以尝试分离数据库,在命令提示符下将文件复制到新名称,然后附加两个数据库。
在 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
事实证明,我曾错误地尝试从备份中恢复。
最初我创建了一个新数据库,然后尝试在此处恢复备份。我应该做的以及最终起作用的是打开恢复对话框并在目标字段中输入新数据库的名称。
所以,简而言之,从备份中恢复就可以了。
感谢所有反馈和建议的家伙
这是我使用的脚本。有点棘手,但它有效。在 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
使用 MS SQL Server 2012,您需要执行 3 个基本步骤:
首先,生成.sql
只包含源数据库结构的文件
.sql
本地保存文件二、将源数据库替换为.sql
文件中的目标数据库
最后,填充数据
Data Source=Mehdi\SQLEXPRESS;Initial Catalog=db_test;User ID=sa;Password=sqlrpwrd15
你完成了。
来自 SSMS:
1 - 将原始数据库备份到 .BAK 文件(your_source_db -> 任务 -> 备份)。
2 - 右键单击“数据库”和“恢复数据库”
3 - 设备 > ...(按钮)> 添加 > 选择 your_source_db.bak
4 - 在“常规”选项卡的“目标”部分中,将“数据库”中的 your_source_db 重命名为 new_name_db
5 - 在“文件”选项卡中,勾选“将所有文件重新定位到文件夹”,
6 - 在“选项”选项卡的“恢复选项”部分,勾选两个第一个选项(“覆盖...”、“保留...”)和“恢复状态”:“恢复时恢复”
如果数据库不是很大,您可以查看 SQL Server Management Studio Express 中的“脚本数据库”命令,这些命令位于资源管理器中数据库项本身的上下文菜单中。
您可以选择要编写的全部内容;当然,您需要对象和数据。然后,您将把整个脚本保存到一个文件中。然后您可以使用该文件重新创建数据库;只需确保USE
顶部的命令设置为正确的数据库即可。
在 SQL Server 2008 R2 中,将数据库作为文件备份到文件夹中。然后选择出现在“数据库”文件夹中的恢复选项。在向导中,输入您希望在目标数据库中使用的新名称。并选择从文件中恢复并使用您刚刚创建的文件。我只是做到了,而且速度非常快(我的数据库很小,但仍然如此)巴勃罗。
基于此评论的解决方案: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
另一种通过使用导入/导出向导来解决问题的方法,首先创建一个空数据库,然后选择源数据库作为您的服务器的源,然后在目标中选择与目标数据库相同的服务器(使用空数据库您首先创建),然后点击完成
它将创建所有表并将所有数据传输到新数据库中,
基于乔回答的脚本(分离、复制文件、附加两者)。
这不是必需的,但可能在执行时访问被拒绝错误。
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
@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
您可以只创建一个新数据库,然后转到任务,导入数据,然后将要复制的数据库中的所有数据导入刚刚创建的数据库。
<!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>
该程序以不同的名称将数据库复制到同一台服务器。我依靠这个网站上给出的例子进行了一些改进。
-- 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