RESTORE HEADERONLYからフィールドを抽出する


12

RESTORE HEADERONLY」を使用して、復元しようとしているバックアップが作成された日付を取得しようとしています。

コマンド:

RESTORE HEADERONLY FROM DISK = '<path to .bak file>'

クエリアナライザーで正常に動作し、50列などの結果セットを提供します。

問題は、実際にコードからこれにアクセスすることです。

これを一時テーブルに入れるには、50:ish列の1つ1つを宣言し、それに挿入してexec、そこから必要な値を取得します。

問題は、将来のバージョンで列を追加する場合、非常に脆弱なソリューションのように思われるので、結果セット全体を一時テーブルとして宣言する必要がないようにしたいということです。

すべての列を宣言せずに、この結果セットから単一の列を取得する方法はありますか?

回答:


12

これでうまくいきます。

SELECT BackupStartDate 
FROM OPENROWSET('SQLNCLI',
                'Server=MARTINPC\MSSQL2008;Trusted_Connection=yes;',
'SET NOCOUNT ON;SET FMTONLY OFF;EXEC(''
RESTORE HEADERONLY 
FROM DISK = ''''C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQL2008\MSSQL\Backup\DB1.bak''''
'')'
) 

アドホック分散クエリのオプションを有効にする必要があります。または、それを実行したくない場合は、ループバックリンクサーバーを設定して、代わりにそれを使用できます。

EXEC sp_addlinkedserver @server = 'LOCALSERVER',  @srvproduct = '',
                        @provider = 'SQLOLEDB', @datasrc = @@servername

SELECT BackupStartDate 
FROM OPENQUERY(LOCALSERVER, 
               'SET FMTONLY OFF;
               EXEC(''
               RESTORE HEADERONLY 
               FROM DISK = ''''C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQL2008\MSSQL\Backup\DB1.bak''''
'')')

賢い、そして共有してくれてありがとう、しかし記録のためだけに、これは結局の列のビッグOLEリストと同じくらい脆く/複雑だと思います。残念ながら、エレガントな解決策はありません。
Tim Abell、2014年

@TimAbell-はい、テーブルの定義を最初に取得する場合を除いて、実際にこれを実際に使用することはないと思います。
マーティン・スミス

1
どちらのクエリも機能させることができませんでした。他の誰かがエラーメッセージ「ステートメントRESTORE HEADERONLY ...がメタデータの検出をサポートしていないため、メタデータを特定できませんでした」を受け取りますか?sp_describe_first_result_setシステムspが原因であると思います。私はこの質問をここで
Stackoverflowuser 2017年

@Stackoverflowuser-私はもともとこれを2008のインスタンス(からMARTINPC\MSSQL2008)に対してテストしたように見えるので、後のバージョンで何かが変更されたため、これは機能しなくなりました。
マーティンスミス

1
@Stackoverflowuser、上記の例は、サーバー@@ version <2012の場合に機能します。2012以降、このクエリを実行する代わりに、プロファイラで次のクエリを確認できます。exec [sys] .sp_describe_first_result_set N'SET FMTONLY OFF; EXEC( '' RESTORE HEADERONLY FROM DISK = '' '' C:\ Program Files \ Microsoft SQL Server \ MSSQL10.MSSQL2008 \ MSSQL \ Backup \ DB1.bak '' '' '') '、NULL、1
sepupic

7

これは、ファイルからバックアップ日付を取得するために私が書いた、バージョンに依存しないspです。

SQL 2008R2、2012、2014でテストされています。

IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'spGetBackupDateFromFile')
    EXEC ('CREATE PROC dbo.spGetBackupDateFromFile AS SELECT ''stub version, to be replaced''')
GO
/*----------------------------------------------------------------------
                    spGetBackupDateFromFile
------------------------------------------------------------------------
Versie      : 1.0
Autheur     : Theo Ekelmans 
Datum       : 2016-03-31
Change      : Initial release 
------------------------------------------------------------------------*/
alter procedure dbo.spGetBackupDateFromFile(@BackupFile as varchar(1000), @DT as datetime output) as 

declare @BackupDT datetime
declare @sql varchar(8000)
declare @ProductVersion NVARCHAR(128)
declare @ProductVersionNumber TINYINT

SET @ProductVersion = CONVERT(NVARCHAR(128),SERVERPROPERTY('ProductVersion'))
SET @ProductVersionNumber = SUBSTRING(@ProductVersion, 1, (CHARINDEX('.', @ProductVersion) - 1))

if object_id('dbo.tblBackupHeader') is not null drop table dbo.tblBackupHeader

set @sql = ''

-- THIS IS GENERIC FOR SQL SERVER 2008R2, 2012 and 2014
if @ProductVersionNumber in(10, 11, 12)
set @sql = @sql +'
create table dbo.tblBackupHeader
( 
    BackupName varchar(256),
    BackupDescription varchar(256),
    BackupType varchar(256),        
    ExpirationDate varchar(256),
    Compressed varchar(256),
    Position varchar(256),
    DeviceType varchar(256),        
    UserName varchar(256),
    ServerName varchar(256),
    DatabaseName varchar(256),
    DatabaseVersion varchar(256),        
    DatabaseCreationDate varchar(256),
    BackupSize varchar(256),
    FirstLSN varchar(256),
    LastLSN varchar(256),        
    CheckpointLSN varchar(256),
    DatabaseBackupLSN varchar(256),
    BackupStartDate varchar(256),
    BackupFinishDate varchar(256),        
    SortOrder varchar(256),
    CodePage varchar(256),
    UnicodeLocaleId varchar(256),
    UnicodeComparisonStyle varchar(256),        
    CompatibilityLevel varchar(256),
    SoftwareVendorId varchar(256),
    SoftwareVersionMajor varchar(256),        
    SoftwareVersionMinor varchar(256),
    SoftwareVersionBuild varchar(256),
    MachineName varchar(256),
    Flags varchar(256),        
    BindingID varchar(256),
    RecoveryForkID varchar(256),
    Collation varchar(256),
    FamilyGUID varchar(256),        
    HasBulkLoggedData varchar(256),
    IsSnapshot varchar(256),
    IsReadOnly varchar(256),
    IsSingleUser varchar(256),        
    HasBackupChecksums varchar(256),
    IsDamaged varchar(256),
    BeginsLogChain varchar(256),
    HasIncompleteMetaData varchar(256),        
    IsForceOffline varchar(256),
    IsCopyOnly varchar(256),
    FirstRecoveryForkID varchar(256),
    ForkPointLSN varchar(256),        
    RecoveryModel varchar(256),
    DifferentialBaseLSN varchar(256),
    DifferentialBaseGUID varchar(256),        
    BackupTypeDescription varchar(256),
    BackupSetGUID varchar(256),
    CompressedBackupSize varchar(256),'

-- THIS IS SPECIFIC TO SQL SERVER 2012
if @ProductVersionNumber in(11)
set @sql = @sql +'
    Containment varchar(256),'


-- THIS IS SPECIFIC TO SQL SERVER 2014
if @ProductVersionNumber in(12)
set @sql = @sql +'
    Containment tinyint, 
    KeyAlgorithm nvarchar(32), 
    EncryptorThumbprint varbinary(20), 
    EncryptorType nvarchar(32),'


--All versions (This field added to retain order by)
set @sql = @sql +'
    Seq int NOT NULL identity(1,1)
); 
'
exec (@sql)


set @sql = 'restore headeronly from disk = '''+ @BackupFile +'''' 

insert into dbo.tblBackupHeader 
exec(@sql)

select @DT = BackupStartDate from dbo.tblBackupHeader 

if object_id('dbo.tblBackupHeader') is not null drop table dbo.tblBackupHeader

1
あたりとしてstackoverflow.com/a/31318785/489865support.microsoft.com/en-us/kb/3058865、KeyAlgorithm / EncryptorThumbprint / EncryptorTypeあなたが実際にのみSP1に登場の"SQL Server 2014"を追加しました。私はそれのビルドバージョンはだと思う12.0.4100.1ので、コードはのすべてのフィールドを調べて、それをSERVERPROPERTY('ProductVersion')正しく満たす必要があります。
JonBrave 2016

7

どのようなコードの詳細も指定せずに、「コード」からのデータへのアクセスについてのみ尋ねたので、PowerShellソリューションをここに示します。

Invoke-SQLcmd -Query "RESTORE HEADERONLY FROM DISK = 'R:\SQLFiles\MSSQL.MSSQLSERVER.Backup\Backup.bak'" | Select-Object MachineName,DatabaseName,HasBackupChecksums,BackupStartDate,BackupFinishDate

1
`ls |のようなことができるので、これはさらに良いです。%{$ _。fullname} | %{invoke-sqlcmd -Query "RESTORE HEADERONLY FROM DISK = '$ _'"} | format-table `
Luiz Felipe

6

参考のために昔ながらの方法:

declare @backupFile varchar(max) = 'C:\backupfile.bak';
declare @dbName varchar(256);

-- THIS IS SPECIFIC TO SQL SERVER 2012
--
declare @headers table 
( 
    BackupName varchar(256),
    BackupDescription varchar(256),
    BackupType varchar(256),        
    ExpirationDate varchar(256),
    Compressed varchar(256),
    Position varchar(256),
    DeviceType varchar(256),        
    UserName varchar(256),
    ServerName varchar(256),
    DatabaseName varchar(256),
    DatabaseVersion varchar(256),        
    DatabaseCreationDate varchar(256),
    BackupSize varchar(256),
    FirstLSN varchar(256),
    LastLSN varchar(256),        
    CheckpointLSN varchar(256),
    DatabaseBackupLSN varchar(256),
    BackupStartDate varchar(256),
    BackupFinishDate varchar(256),        
    SortOrder varchar(256),
    CodePage varchar(256),
    UnicodeLocaleId varchar(256),
    UnicodeComparisonStyle varchar(256),        
    CompatibilityLevel varchar(256),
    SoftwareVendorId varchar(256),
    SoftwareVersionMajor varchar(256),        
    SoftwareVersionMinor varchar(256),
    SoftwareVersionBuild varchar(256),
    MachineName varchar(256),
    Flags varchar(256),        
    BindingID varchar(256),
    RecoveryForkID varchar(256),
    Collation varchar(256),
    FamilyGUID varchar(256),        
    HasBulkLoggedData varchar(256),
    IsSnapshot varchar(256),
    IsReadOnly varchar(256),
    IsSingleUser varchar(256),        
    HasBackupChecksums varchar(256),
    IsDamaged varchar(256),
    BeginsLogChain varchar(256),
    HasIncompleteMetaData varchar(256),        
    IsForceOffline varchar(256),
    IsCopyOnly varchar(256),
    FirstRecoveryForkID varchar(256),
    ForkPointLSN varchar(256),        
    RecoveryModel varchar(256),
    DifferentialBaseLSN varchar(256),
    DifferentialBaseGUID varchar(256),        
    BackupTypeDescription varchar(256),
    BackupSetGUID varchar(256),
    CompressedBackupSize varchar(256),        
    Containment varchar(256),
    --
    -- This field added to retain order by
    --
    Seq int NOT NULL identity(1,1)
); 

insert into @headers exec('restore headeronly from disk = '''+ @backupFile +'''');
select @dbName = DatabaseName from @headers;
select @dbName;

1
SQL2014で動作するようにこれを取得するには、表の最後にこれらの追加のフィールドを持っている必要があります、封じ込めTINYINT、KeyAlgorithm NVARCHAR(32)、EncryptorThumbprint VARBINARY(20)、EncryptorType NVARCHAR(32)
マイク・

そこにもあるこの答えすべてのためにvarchar型を使用していないと、SQL Serverの2014年のための余分な列が含まれて
Baodad

これらの追加の列は実際にはSQL 2014 SP1で追加されたことに注意してください。そのためのビルドバージョンはだと思います12.0.4100.1
JonBrave 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.