แยกฟิลด์จาก RESTORE HEADERONLY


12

ฉันพยายามใช้ 'เรียกคืน HEADERONLY ' เพื่อรับวันที่ที่ฉันกำลังจะทำการสำรองข้อมูล

คำสั่ง:

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

ทำงานได้ดีใน Query Analyzer และให้ชุดผลลัพธ์กับคอลัมน์ 50 คอลัมน์

ปัญหาคือการเข้าถึงนี้จากรหัส

ฉันสามารถเอามันเข้าไปในตารางชั่วคราวได้โดยการประกาศทุก ๆ คอลัมน์ของคอลัมน์ 50: ish แทรกเข้าไปด้วยexecและรับค่าที่ฉันต้องการจากตรงนั้น

ปัญหาคือฉันต้องการหลีกเลี่ยงการประกาศ resultset ทั้งหมดเป็นตารางชั่วคราวเนื่องจากดูเหมือนว่าจะเป็นวิธีการแก้ไขที่เปราะบางหากพวกเขาเพิ่มคอลัมน์ลงในรุ่นอนาคต

มีวิธีใดที่จะเอาคอลัมน์เดียวออกจากชุดผลลัพธ์นี้โดยไม่ต้องประกาศคอลัมน์ทั้งหมดหรือไม่

คำตอบ:


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''''
'')')

ฉลาดและขอบคุณสำหรับการแบ่งปัน แต่สำหรับเร็กคอร์ดฉันคิดว่านี่เปราะ / ซับซ้อนเหมือนรายการใหญ่ของคอลัมน์ในท้ายที่สุด ความอัปยศไม่มีวิธีแก้ปัญหาที่สง่างาม
Tim Abell

@TimAbell - ใช่ฉันไม่คิดว่าจริง ๆ แล้วฉันจะใช้มันในทางปฏิบัติยกเว้นอาจจะได้รับความหมายของตารางในสถานที่แรก
Martin Smith

1
ฉันไม่สามารถใช้แบบสอบถามได้ มีใครได้รับข้อความแสดงข้อผิดพลาด "ไม่สามารถระบุข้อมูลเมตาได้เนื่องจากคำสั่ง RESTORE HEADERONLY ... ไม่รองรับการค้นพบข้อมูลเมตา" ฉันเชื่อว่าsp_describe_first_result_setระบบ sp เป็นตัวการที่อยู่เบื้องหลัง ฉันยังยกคำถามนี้เป็นตั๋วแยกต่างหากที่นี่
Stackoverflowuser

@Stackoverflowuser - ดูเหมือนว่าฉันเคยทดสอบสิ่งนี้กับอินสแตนซ์ 2008 (จากMARTINPC\MSSQL2008) ดังนั้นอาจมีบางสิ่งบางอย่างเปลี่ยนไปในเวอร์ชันที่ใหม่กว่าซึ่งหมายความว่ามันไม่ทำงานอีกต่อไป
Martin Smith

1
@Stackoverflowuser ตัวอย่างข้างต้นใช้งานได้เมื่อเซิร์ฟเวอร์ @@ เวอร์ชัน <2012 เริ่มต้นด้วย 2012 แทนที่จะเรียกใช้งานแบบสอบถามนี้คุณสามารถดูได้ใน Profiler this: exec [sys] .sp_describe_first_result_set N'SET FMTONLY OFF; EXEC ('' เรียกคืน HEADERONON จาก DISK = '' '' C: \ Program SQL Server \ MSSQL10.MSSQL2008 \ MSSQL \ Backup \ DB1.bak '\' SQL Server \ MSSQL10.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/489865และsupport.microsoft.com/en-us/kb/3058865 KeyAlgorithm / EncryptorThumbprint / EncryptorType ที่คุณเพิ่มไว้สำหรับ "SQL SERVER 2014" จะปรากฏใน SP1 เท่านั้น ฉันเชื่อว่า Build Version สำหรับสิ่งนั้นคือ12.0.4100.1ดังนั้นโค้ดควรดูฟิลด์ทั้งหมดในSERVERPROPERTY('ProductVersion')การตอบสนองอย่างถูกต้อง
JonBrave

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 | % {$ _. ชื่อเต็ม} | % {invoke-sqlcmd -Query "เรียกคืน HEADERONLY จาก DISK = '$ _'"} | รูปแบบตาราง `
ลูอิสเฟลิเป้

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 คุณจะต้องมีฟิลด์เพิ่มเติมเหล่านี้ที่ท้ายตาราง:, การบรรจุเล็ก ๆ , KeyAlgorithm nvarchar (32), EncryptorThumbprint varbinary (20), EncryptorType nvarchar (32)
Mike

นอกจากนี้ยังมีคำตอบนี้ซึ่งไม่ได้ใช้ varchar สำหรับทุกสิ่งและรวมคอลัมน์พิเศษสำหรับ SQL Server 2014
Baodad

โปรดทราบว่าคอลัมน์พิเศษเหล่านี้ถูกเพิ่มจริงใน SQL 2014 SP1 12.0.4100.1ผมเชื่อว่าการสร้างรุ่นที่เป็น
JonBrave
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.