如何复制带分区的 SQL 数据库并将其恢复到测试数据库中

How to Copy a SQL Database With Partition and restore it in a Test Database

我有一个存储过程,它将备份 SQL 数据库并将其恢复到测试数据库中。它工作正常,但是当带有分区的数据库失败时,显示以下错误。

cannot be overwritten. It is being used by database 'OriginalDb'. Use WITH MOVE to identify a valid location for the file.

等等...它有很多事务日志文件所以每个分区都显示错误消息

下面是其他数据库的工作存储过程

***********************************************************
DECLARE   @SourceDatabaseName AS SYSNAME = 'orginalDb',

    @TargetDatabaseName AS SYSNAME = 'demo'
    declare @Disksize as bigint
    declare @Dbsize as bigint 
--========Checking the  C drive Size================
--==================================================
DBCC SHRINKDATABASE ('orginalDb', 10);
SELECT  @Disksize= available_bytes/1048576
FROM sys.master_files AS f CROSS APPLY 
  sys.dm_os_volume_stats(f.database_id, f.file_id)
group by volume_mount_point, total_bytes/1048576, 
  available_bytes/1048576 
--===============END=================================
--================DBSIZE=============================
SELECT @Dbsize = CONVERT(VARCHAR,SUM(size)*8/1024)
FROM        sys.databases   
JOIN        sys.master_files  
ON          sys.databases.database_id=sys.master_files.database_id   where sys.databases.name ='orginalDb'
GROUP BY    sys.databases.name  
ORDER BY    sys.databases.name  
--================= END =============================
--========================Condition to disk c drive is more than 10 GB size==========================================
IF @Disksize >@Dbsize 
begin 
-- ==================================================
-- Define path where backup will be saved
-- ==================================================
IF NOT EXISTS (SELECT 1 FROM sys.databases WHERE name = @SourceDatabaseName)
    RAISERROR ('Variable @SourceDatabaseName is not set correctly !', 20, 1) WITH LOG       
DECLARE @SourceBackupFilePath varchar(2000)
SELECT @SourceBackupFilePath = BMF.physical_device_name
FROM
    msdb.dbo.backupset B
    JOIN msdb.dbo.backupmediafamily BMF ON B.media_set_id = BMF.media_set_id
WHERE B.database_name = @SourceDatabaseName
ORDER BY B.backup_finish_date DESC
SET @SourceBackupFilePath = REPLACE(@SourceBackupFilePath, '.bak', '_clone.bak')
-- ==================================================
-- Backup source database
-- ==================================================
DECLARE @Sql NVARCHAR(MAX) 
SET @Sql = 'BACKUP DATABASE @SourceDatabaseName TO DISK = ''@SourceBackupFilePath'''
SET @Sql = REPLACE(@Sql, '@SourceDatabaseName', @SourceDatabaseName)
SET @Sql = REPLACE(@Sql, '@SourceBackupFilePath', @SourceBackupFilePath)
SELECT 'Performing backup...', @Sql as ExecutedSql
EXEC (@Sql)
-- ==================================================
-- Automatically compose database files (.mdf and .ldf) paths
-- ==================================================
DECLARE
          @LogicalDataFileName as NVARCHAR(MAX)
        , @LogicalLogFileName as NVARCHAR(MAX)
        , @TargetDataFilePath as NVARCHAR(MAX)
        , @TargetLogFilePath as NVARCHAR(MAX)
SELECT
    @LogicalDataFileName = name,
    @TargetDataFilePath = SUBSTRING(physical_name,1,LEN(physical_name)-CHARINDEX('\',REVERSE(physical_name))) + '\' + @TargetDatabaseName + '.mdf'
FROM sys.master_files
WHERE
    database_id = DB_ID(@SourceDatabaseName)        
    AND type = 0            -- datafile file
SELECT
    @LogicalLogFileName = name,
    @TargetLogFilePath = SUBSTRING(physical_name,1,LEN(physical_name)-CHARINDEX('\',REVERSE(physical_name))) + '\' + @TargetDatabaseName + '.ldf'
FROM sys.master_files
WHERE
    database_id = DB_ID(@SourceDatabaseName)        
    AND type = 1            -- log file     
-- ============================================
-- Restore target database
-- ============================================
IF EXISTS (SELECT 1 FROM sys.databases WHERE name = @TargetDatabaseName)
    RAISERROR ('A database with the same name already exists!', 20, 1) WITH LOG        
SET @Sql = 'RESTORE DATABASE @TargetDatabaseName
FROM DISK = ''@SourceBackupFilePath'' 
WITH MOVE ''@LogicalDataFileName'' TO ''@TargetDataFilePath'',
MOVE ''@LogicalLogFileName'' TO ''@TargetLogFilePath''' 
SET @Sql = REPLACE(@Sql, '@TargetDatabaseName', @TargetDatabaseName)
SET @Sql = REPLACE(@Sql, '@SourceBackupFilePath', @SourceBackupFilePath)
SET @Sql = REPLACE(@Sql, '@LogicalDataFileName', @LogicalDataFileName)
SET @Sql = REPLACE(@Sql, '@TargetDataFilePath', @TargetDataFilePath)
SET @Sql = REPLACE(@Sql, '@LogicalLogFileName', @LogicalLogFileName)
SET @Sql = REPLACE(@Sql, '@TargetLogFilePath', @TargetLogFilePath)
SELECT 'Restoring...', @Sql as ExecutedSql
EXEC (@Sql)
end
else
print 'Restoring failed';

************************************************************************

请复制此存储过程并检查分区数据库,(它不会工作)但与其他数据库一起工作。
我需要在哪里进行更改?是否可以将分区数据库恢复到另一个数据库? 提前致谢!

您的最终代码应如下所示:

RESTORE DATABASE TargetDatabaseName FROM DISK = '...' 
WITH MOVE 'LogicalDataFileName' TO 'D:\WINCAP\demo.mdf', 
     MOVE 'LogicalLogFileName' TO 'D:\WINCAP\demo.ldf', 
     MOVE 'Boces_ss2014_Part' TO 'D:\WINCAP\dem.ndf', 
     MOVE 'Boces_ss2015_Part' TO 'D:\WINCAP\demccc.ndf', 
     MOVE 'Boces_ss2016_Part' TO 'D:\WINCAP\demccdc.ndf', 
     MOVE 'Boces_ss2017_Part' TO 'D:\WINCAP\dems.ndf', 
     MOVE 'Boces_ss2018_Part' TO 'D:\WINCAP\de.ndf', 
     MOVE 'Boces_ssFinal_Part' TO 'D:\WINCAP\dems.ndf'

您的代码在某些地方不正确,但我不知道在哪里。

如果您粘贴的代码与您执行的代码完全相同,您可能在 move 之前错过了一个逗号:

''D:\WINCAP\dems.ndf'' MOVE 

找出你应该在哪里打印你的代码并在执行前检查它:

print @Sql

打印代码后,copy-paste 在 SSMS 查询 window 中解析它,如果有任何错误,SSMS 会证明它。

然后才做你的exec(@Sql)