我已经搜索了一段时间这个问题,如果找不到解决方案,我将无法解决。
每周我们都会从客户那里获得新的数据库。我开发了一种工具来还原我们自己的数据库,以使所有数据库与客户端数据库保持一致。 该工具适用于某些数据库,但是在其他数据库上,由于日志文件,我会遇到一些错误。
我的还原数据库脚本如下
USE [master]
ALTER DATABASE[MyDataBase] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE DATABASE[MyDataBase]
FROM DISK = N'MyDataBase.bak'
WITH NOUNLOAD,
REPLACE, STATS = 5
ALTER DATABASE[MyDataBase] SET MULTI_USER
我知道如果使用MOVE命令可以解决问题,那是我无法事先知道文件,这意味着我无法真正编写任何自定义代码来还原数据库。
深入研究发现,我可以使用以下命令从数据库中打印所有日志文件
SELECT
DB_NAME([database_id]) [database_name]
, [file_id]
, [type_desc] [file_type]
, [name] [logical_name]
, [physical_name]
FROM sys.[master_files]
WHERE [database_id] IN (DB_ID('MyDataBase'))
ORDER BY [type], DB_NAME([database_id]);
但是这里显示的文件与我收到错误提示的文件完全不同。
要注意的另一重要事项是,如果我还原数据库,然后尝试通过tsql还原,则可以进行还原,但是我有一个Server Agent Job重命名文件以保持文件干净,并且在运行后无法再次还原数据库,并给出与手动还原之前相同的错误。
我不知道我要实现的目标是否可以实现,以及如何实现。如果有人可以给我一些灯光,那就太好了
答案 0 :(得分:2)
RESTORE FILELISTONLY会告诉您文件,然后您可以从中建立RESTORE ... WITH MOVE:
EG
--backup database a to disk='c:\temp\a.bak'
declare @fn nvarchar(255) = 'c:\temp\a.bak';
declare @sql nvarchar(max) = concat('restore filelistonly from disk=''',@fn,'''');
declare @targetFolder nvarchar(max) = 'c:\temp\customer_123';
declare @dbname sysname = 'a_123';
declare @t table
(
LogicalName nvarchar(128),--, --Logical name of the file.
PhysicalName nvarchar(260),-- Physical or operating-system name of the file.
Type char(1),-- The type of file, one of:
FileGroupName nvarchar(128) NULL, -- Name of the filegroup that contains the file.
Size numeric(20,0),-- Current size in bytes.
MaxSize numeric(20,0),-- Maximum allowed size in bytes.
FileID bigint,-- File identifier, unique within the database.
CreateLSN numeric(25,0),-- Log sequence number at which the file was created.
DropLSN numeric(25,0) NULL, -- The log sequence number at which the file was dropped. If the file has not been dropped, this value is NULL.
UniqueID uniqueidentifier,-- Globally unique identifier of the file.
ReadOnlyLSN numeric(25,0) NULL, -- Log sequence number at which the filegroup containing the file changed from read-write to read-only (the most recent change),--.
ReadWriteLSN numeric(25,0) NULL, -- Log sequence number at which the filegroup containing the file changed from read-only to read-write (the most recent change),--.
BackupSizeInBytes bigint, -- Size of the backup for this file in bytes.
SourceBlockSize int, -- Block size of the physical device containing the file in bytes (not the backup device),--.
FileGroupID int,-- ID of the filegroup.
LogGroupGUID uniqueidentifier NULL, -- NULL.
DifferentialBaseLSN numeric(25,0) NULL, -- For differential backups, changes with log sequence numbers greater than or equal to DifferentialBaseLSN are included in the differential
DifferentialBaseGUID uniqueidentifier NULL, -- For differential backups, the unique identifier of the differential base.
IsReadOnly bit,-- 1 = The file is read-only.
IsPresent bit,-- 1 = The file is present in the backup.
TDEThumbprint varbinary(32) NULL, -- Shows the thumbprint of the Database Encryption Key. The encryptor thumbprint is a SHA-1 hash of the certificate with which the key is encrypted. For information about database encryption, see Transparent Data Encryption (TDE),--.
SnapshotURL nvarchar(360)-- NULL The URL for the Azure snapshot of the database file contained in the FILE_SNAPSHOT backup. Returns NULL if no FILE_SNAPSHOT backup.
);
insert into @t
exec (@sql);
with q as
(
select concat('restore database ',@dbname,' from disk=''',@fn,''' with ') l
union all
select concat('
move ''',LogicalName,''' to ''', @targetFolder, '\', LogicalName, case [type] when 'D' then '.mdf' when 'L' then '.ldf' else null end, ''' , ')
from @t
union all
select 'RECOVERY, STATS = 10'
)
select @sql = STRING_AGG(l,'
')
from q;
print (@sql);
exec (@sql );