Trích xuất một trường từ RESTORE CHÍNH HÃNG


12

Tôi đang cố gắng sử dụng ' RESTORE HeaderONLY ' để lấy ngày khi bản sao lưu tôi sắp khôi phục được thực hiện.

Lệnh:

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

hoạt động tốt trong Trình phân tích truy vấn và đưa ra một tập kết quả với khoảng 50 cột.

Vấn đề là thực sự truy cập từ mã này.

Tôi có thể lấy cái này vào một bảng tạm thời bằng cách khai báo từng cột trong số 50: ish, chèn vào đó execvà nhận giá trị tôi muốn từ đó.

Vấn đề là tôi thực sự muốn tránh phải khai báo toàn bộ tập kết quả dưới dạng bảng tạm thời vì nó có vẻ như là một giải pháp rất dễ vỡ nếu họ thêm các cột vào nó trong các phiên bản trong tương lai.

Có cách nào để chỉ lấy một cột ra khỏi tập kết quả này mà không cần khai báo tất cả các cột không?

Câu trả lời:


12

Điều này làm việc cho tôi.

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

Các quảng cáo hoc truy vấn phân phối Lựa chọn cần phải được kích hoạt. Hoặc nếu bạn không muốn làm điều đó, bạn có thể thiết lập một máy chủ được liên kết loopback và sử dụng nó để thay thế.

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

Thông minh, và cảm ơn vì đã chia sẻ, nhưng chỉ vì hồ sơ tôi nghĩ rằng điều này cũng dễ vỡ / phức tạp như danh sách các cột lớn cuối cùng. Xấu hổ không có một giải pháp thanh lịch.
Tim Abell

@TimAbell - Có, tôi không nghĩ rằng tôi thực sự sẽ sử dụng điều này trong thực tế ngoại trừ có thể để có được định nghĩa bảng ở vị trí đầu tiên.
Martin Smith

1
Tôi không thể làm cho một trong hai truy vấn hoạt động. Có ai khác nhận được thông báo lỗi "Không thể xác định siêu dữ liệu vì câu lệnh RESTORE CHÍNH HÃNG ... không hỗ trợ phát hiện siêu dữ liệu"? Tôi tin rằng sp_describe_first_result_sethệ thống sp là thủ phạm đằng sau. Tôi cũng đưa ra câu hỏi này như một vé riêng ở đây
Stackoverflowuser

@Stackoverflowuser - có vẻ như ban đầu tôi đã thử nghiệm điều này với một phiên bản 2008 (từ MARTINPC\MSSQL2008) nên có thể có gì đó đã thay đổi trong các phiên bản sau đó có nghĩa là điều này không còn hoạt động.
Martin Smith

1
@Stackoverflowuser, ví dụ trên hoạt động khi máy chủ @@ phiên bản <2012. Bắt đầu từ năm 2012, thay vì thực hiện truy vấn này, bạn có thể thấy trong Profiler này: exec [sys] .sp_describe_first_result_set N'SET FMTONLY OFF; EXEC ('' RESTORE CHÍNH HÃNG TỪ DISK = '' '' C: \ Chương trình tập tin \ Microsoft SQL Server \ MSSQL10.MSSQL2008 \ MSSQL \ Backup \ DB1.bak '' '' '') ', NULL, 1
sepupic

7

Đây là một phiên bản sp độc lập mà tôi đã viết để lấy ngày sao lưu từ một tập tin.

Nó đã được thử nghiệm cho SQL 2008R2, 2012 và 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
Theo stackoverflow.com/a/31318785/489865support.microsoft.com/en-us/kb/3058865 , KeyAlerskym / EncryptorThumbprint / EncryptorType mà bạn đã thêm cho "SQL SERVER 2014" thực sự chỉ xuất hiện trong SP1. Tôi tin rằng Phiên bản Xây dựng cho điều đó 12.0.4100.1, vì vậy mã phải xem xét tất cả các trường trong SERVERPROPERTY('ProductVersion')để phục vụ chính xác cho điều đó.
JonBrave

7

Vì bạn chỉ hỏi về việc truy cập dữ liệu từ 'mã' mà không chỉ định bất kỳ chi tiết nào về loại mã, nên tôi xin trình bày giải pháp PowerShell :

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

Điều này thậm chí còn tốt hơn, vì chúng ta có thể làm một cái gì đó như `ls | % {$ _. tên đầy đủ} | % {invoke-sqlcmd -Query "RESTORE CHÍNH HÃNG TỪ DISK = '$ _'"} | bảng định dạng `
Luiz Felipe

6

Cách thức cũ, để tham khảo:

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
Để làm việc này trong SQL2014, bạn cần có các trường bổ sung này ở cuối bảng :, Ngăn chặn tinyint, KeyAlacticm nvarchar (32), EncryptorThumbprint varbinary (20), EncryptorType nvarchar (32)
Mike

Ngoài ra còn có câu trả lời này , không sử dụng varchar cho mọi thứ và bao gồm các cột bổ sung cho SQL Server 2014.
Baodad

Lưu ý rằng các cột bổ sung này đã thực sự được thêm vào trong SQL 2014 SP1 . Tôi tin rằng Phiên bản Xây dựng cho điều đó là 12.0.4100.1.
JonBrave
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.