我有一个MS SQL Server 2008 Express系统,其中包含一个数据库,我想“复制和重命名”(用于测试目的),但我不知道一个简单的方法来实现这一点。
我注意到在R2版本的SQL Server中有一个复制数据库向导,但遗憾的是我无法升级。
我们讨论的数据库大约是1g。 我试图恢复我想复制到一个新数据库的数据库的备份,但没有运气。
我有一个MS SQL Server 2008 Express系统,其中包含一个数据库,我想“复制和重命名”(用于测试目的),但我不知道一个简单的方法来实现这一点。
我注意到在R2版本的SQL Server中有一个复制数据库向导,但遗憾的是我无法升级。
我们讨论的数据库大约是1g。 我试图恢复我想复制到一个新数据库的数据库的备份,但没有运气。
当前回答
这里提到的解决方案都不适合我-我使用的是SQL Server Management Studio 2014。
相反,我不得不取消“选项”屏幕中的“在恢复前进行尾日志备份”复选框:在我的版本中,默认情况下它是选中的,并阻止恢复操作完成。 取消检查后,还原操作继续进行,没有出现问题。
其他回答
右键单击要克隆的数据库,单击Tasks,单击Copy database ....遵循向导,您就完成了。
这是我使用的脚本。有点棘手,但很有效。在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
脚本基于乔回答(分离,复制文件,附加两者)。
以Administrator帐户运行management Studio。
这是不必要的,但可能在执行时访问被拒绝错误。
为执行xp_cmdshel配置sql server
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
运行脚本,但在@dbName和@copyDBName变量之前输入你的db名称。
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
该程序以不同的名称将数据库复制到同一服务器。我依赖于这个网站上给出的例子,并进行了一些改进。
-- 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
<!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>