У меня есть экземпляр SQL 2005, который выполняет задание, использующее сценарий Powershell для переименования текущего файла резервной копии журнала TX, добавив к нему «-PrevDay» (впоследствии удалив резервную копию, уже названную «XXX-PrevDay.bak»). если он существует), а затем запустите полное резервное копирование БД и резервное копирование журнала TX, если БД не находится в простом режиме.
Задание агента SQL Server запускает сценарий Powershell через CMD на каждом этапе задания, а сценарий powershell запускает резервную копию sql с помощью командлета Invoke-SQLCmd. Это прекрасно работает, если резервное копирование не выполнено, потому что задание SQL по-прежнему отображается как «Успешное». Это связано с тем, что задание SQL, которое запускает сценарий Powershell через приглашение CMD, заботится только о том, запускается ли сценарий Powershell ... а не о том, действительно ли команды IN в сценарии выполняются или не выполняются.
Возможно ли, используя перехват ошибок в powershell (или любом другом методе), заставить скрипт powershell "не выполнить" действие приглашения cmd при запуске сценария ... так, чтобы задание SQL сообщало об ошибке?
Имеет ли это смысл? LOL
Я бы предположил, что если бы мне удалось использовать SQL 2008, который допускает тип шага задания SQL «Скрипт Powershell» (вместо того, чтобы быть типом шага, который должен быть «Операционная система»… который запускает сценарий PS) это не будет проблемой ... однако ... это не вариант.
В данный момент шаг задания запускает сценарий powershell через CMD с использованием параметров для DBName, Path и Servername и выглядит следующим образом:
powershell.exe "C:\SQLBackupScriptsTest\SQLServerBackup.ps1" -DBName 'Angel_Food' -Path 'E:\SQLBackup1' -Server 'DEVSQLSRV'
Фактический скрипт Powershell выглядит следующим образом:
Param($DBName,$Path,$Server)
## Add sql snapins...must have for Invoke-Sqlcmd with powershell 2.0 ##
add-pssnapin sqlserverprovidersnapin100
add-pssnapin sqlservercmdletsnapin100
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null
## Set parameter for finding DB recovery model ##
$Recovery = (Invoke-Sqlcmd -Query "SELECT recovery_model_desc FROM sys.databases WHERE name = '$DBName'" -Server $Server)
## Do full backup of DB ##
(Invoke-Sqlcmd -Query "BACKUP DATABASE $DBName TO DISK = N'$Path\$DBName\$DBName.bak' WITH NOFORMAT, INIT, NAME = N'$DBNameTEST', SKIP, NOREWIND, NOUNLOAD, STATS = 10, CHECKSUM" -Server $Server -ConnectionTimeout 0 -QueryTimeout 65535)
############################################################################################################
## Check recovery mode, if FULL, check for Log-PrevDay.bak. If exists then delete. If not exist, move on ##
## Then check for Current TX log backup. If exists, rename to Log-PreDay.bak. If not exist, move on ##
## Then perform TX Log backup ##
## If recovery mode NOT FULL, do nothing ##
############################################################################################################
IF
($Recovery.recovery_model_desc -eq 'FULL')
#THEN#
{
## Look to see if PrevDay TX log exists. If so, delete, if not, move on ##
IF
(Test-Path $Path\$DBName\$DBName-Log-PrevDay.bak)
#THEN#
{remove-item $Path\$DBName\$DBName-Log-PrevDay.bak -force}
ELSE
{}
## Look to see if current TX log exists, if so, rename to Prev Day TX Log, if not, move on ##
IF
(Test-Path $Path\$DBName\$DBName-Log.bak)
#THEN#
{rename-item $Path\$DBName\$DBName-Log.bak -newname $DBName-Log-PrevDay.bak -force}
ELSE
{}
Invoke-Sqlcmd -Query "BACKUP LOG $DBName TO DISK = N'$Path\$DBName\$DBName-Log.bak' WITH NOFORMAT, INIT, NAME = N'$DBName LogTEST (Init)', SKIP, NOREWIND, NOUNLOAD, STATS = 10, CHECKSUM" -Server $Server -ConnectionTimeout 0 -QueryTimeout 65535}
ELSE
{}