Вилучення поля з ПОЛУЧАЙТЕ НАВЧАЛЬНО


12

Я намагаюся використовувати " RESTORE HEADERONLY ", щоб отримати дату, коли була зроблена резервна копія, яку я збираюся відновити.

Команда:

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

прекрасно працює в аналізаторі запитів і дає набір результатів з приблизно 50 стовпців.

Проблема полягає в фактичному доступі до цього з коду.

Я можу отримати це в тимчасовій таблиці, оголосивши кожен з 50: ish стовпців, вставивши в нього 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''''
'')')

Розумний, і дякую за спільний доступ, але тільки за запис, я думаю, що це так само крихко / складно, як і великий список колонок у підсумку. Ганьба, там немає елегантного рішення.
Тім Абелл

@TimAbell - Так, я не думаю, що я насправді використовував би це на практиці, за винятком, можливо, для визначення визначення таблиці в першу чергу.
Мартін Сміт

1
Я не міг змусити жодного запиту працювати. Хтось ще отримує повідомлення про помилку "Метадані не вдалося визначити, оскільки оператор RESTORE HEADERONLY ... не підтримує виявлення метаданих"? Я вважаю, sp_describe_first_result_setвинуватцем є система sp. Я також підняв це питання як окремий квиток тут
Stackoverflowuser

@Stackoverflowuser - схоже, я спочатку тестував це на екземплярі 2008 року (з MARTINPC\MSSQL2008), тому, можливо, щось змінилося в пізніших версіях, що означає, що це більше не працює.
Мартін Сміт

1
@Stackoverflowuser, наведений вище приклад працює, коли сервер @@ версії <2012. Починаючи з 2012 року, замість виконання цього запиту, ви можете побачити в Profiler цей: exec [sys] .sp_describe_first_result_set N'SET FMTONLY OFF; EXEC ('' RESTORE HEADERONY OF DISK = '' 'C: \ Program Files \ Microsoft SQL Server \ MSSQL10.MSSQL2008 \ MSSQL \ Backup \ DB1.bak' '' '' ')', NULL, 1
sepupic

7

Це незалежна версія, яку я написав, щоб отримати дату резервного копіювання з файлу.

Тестовано для 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 , ви можете розмістити фотографії до «SQL SERVER 2014» KeyAlgorithm / EncryptorThumbprint / EncryptorType фактично тільки з'явився в SP1. Я вважаю, що версія версії для цього є 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 "ВІДКРИТИ СЛУХАЛЬНО З ДИСКА = '$ _'"} | формат-таблиця `
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, вам потрібно буде мати ці додаткові поля в кінці таблиці:, Contain tinyint, KeyAlgorithm nvarchar (32), EncryptorThumbprint varbinary (20), EncryptorType nvarchar (32)
Mike

Існує також ця відповідь , яка не використовує varchar для всього, і включає додаткові стовпці для SQL Server 2014.
Baodad

Зауважте, що ці додаткові стовпці були фактично додані в SQL 2014 SP1 . Я вважаю, що версія версії для цього є 12.0.4100.1.
JonBrave
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.