16

我正在尝试编写自动备份和恢复 T-SQL 脚本。我已经完成了 BACKUP 部分,但我在 RESTORE 上苦苦挣扎。

当我在 SS Management Studio 上运行以下语句时;

EXEC('RESTORE FILELISTONLY FROM DISK = ''C:\backup.bak''')

我在网格中得到一个结果集,我也可以使用

INSERT INTO <temp_table> 
EXEC('RESTORE FILELISTONLY FROM DISK = ''C:\backup.bak''')

填充临时表。但是,当我尝试从该结果集中进行选择时,出现语法错误。例如

SELECT * FROM  
EXEC('RESTORE FILELISTONLY FROM DISK = ''C:\backup.bak''')

结果集元数据应存储在 SQL Server 字典中的某个位置。我找到了其他创可贴公式来让我的自动恢复工作,但如果可以得到结果集,我会创建更优雅的解决方案。另请注意,2008 年的结果集与 2005 年的不同。

提前致谢...

4

3 回答 3

46

死胡同SELECT INTO很好,因为您不必定义表格列,但它不支持EXEC.

解决方案INSERT INTO支持EXEC,但需要定义表。使用MSDN 提供的 SQL 2008 定义,我编写了以下脚本:

DECLARE @fileListTable TABLE (
    [LogicalName]           NVARCHAR(128),
    [PhysicalName]          NVARCHAR(260),
    [Type]                  CHAR(1),
    [FileGroupName]         NVARCHAR(128),
    [Size]                  NUMERIC(20,0),
    [MaxSize]               NUMERIC(20,0),
    [FileID]                BIGINT,
    [CreateLSN]             NUMERIC(25,0),
    [DropLSN]               NUMERIC(25,0),
    [UniqueID]              UNIQUEIDENTIFIER,
    [ReadOnlyLSN]           NUMERIC(25,0),
    [ReadWriteLSN]          NUMERIC(25,0),
    [BackupSizeInBytes]     BIGINT,
    [SourceBlockSize]       INT,
    [FileGroupID]           INT,
    [LogGroupGUID]          UNIQUEIDENTIFIER,
    [DifferentialBaseLSN]   NUMERIC(25,0),
    [DifferentialBaseGUID]  UNIQUEIDENTIFIER,
    [IsReadOnly]            BIT,
    [IsPresent]             BIT,
    [TDEThumbprint]         VARBINARY(32), -- remove this column if using SQL 2005
    [SnapshotURL]           NVARCHAR(360) -- remove this column if using less than SQL 2016 (13.x)
)
INSERT INTO @fileListTable EXEC('RESTORE FILELISTONLY FROM DISK = ''YourBackupFile.bak''')
SELECT * FROM @fileListTable
于 2010-10-25T20:55:34.380 回答
10

这是适用于 SQL 2005 和 SQL 2017 之间所有版本的代码:

CREATE TABLE #FileListHeaders (     
     LogicalName    nvarchar(128)
    ,PhysicalName   nvarchar(260)
    ,[Type] char(1)
    ,FileGroupName  nvarchar(128) NULL
    ,Size   numeric(20,0)
    ,MaxSize    numeric(20,0)
    ,FileID bigint
    ,CreateLSN  numeric(25,0)
    ,DropLSN    numeric(25,0) NULL
    ,UniqueID   uniqueidentifier
    ,ReadOnlyLSN    numeric(25,0) NULL
    ,ReadWriteLSN   numeric(25,0) NULL
    ,BackupSizeInBytes  bigint
    ,SourceBlockSize    int
    ,FileGroupID    int
    ,LogGroupGUID   uniqueidentifier NULL
    ,DifferentialBaseLSN    numeric(25,0) NULL
    ,DifferentialBaseGUID   uniqueidentifier NULL
    ,IsReadOnly bit
    ,IsPresent  bit
)
IF cast(cast(SERVERPROPERTY('ProductVersion') as char(4)) as float) > 9 -- Greater than SQL 2005 
BEGIN
    ALTER TABLE #FileListHeaders ADD TDEThumbprint  varbinary(32) NULL
END
IF cast(cast(SERVERPROPERTY('ProductVersion') as char(2)) as float) > 12 -- Greater than 2014
BEGIN
    ALTER TABLE #FileListHeaders ADD SnapshotURL    nvarchar(360) NULL
END
INSERT INTO #FileListHeaders
EXEC ('RESTORE FILELISTONLY FROM DISK = N''BackupFileName.bak''')

SELECT * FROM #FileListHeaders

DROP TABLE #FileListHeaders
于 2018-12-24T10:10:55.457 回答
9

您不能从 EXEC 中选择。您只能将 EXEC 的结果集插入到表(或表变量)中。

至于自动还原,全自动 SQL Server 还原中的答案已经为您提供了构建解决方案所需的一切。是否可以尝试自动还原具有未知文件列表的数据库,这是一个不同的主题。

于 2010-03-24T23:53:56.893 回答