Files
sql-scripts/maintenance_devdb.sql
Thierry Schork 94be4e48e8 sync
2025-08-15 10:17:18 +02:00

9880 lines
491 KiB
Transact-SQL

/*
Deploy the db maintenance objects and setup jobs
1. Deploy the Ola Hallengren objects
2. Drop any maintenance plan owned by Paul or Mehdi
3. Create default jobs for db integrity, index and statistics maintenance (no backups)
12.08.2025, TSC
*/
BEGIN TRANSACTION;
SET XACT_ABORT ON;
SET NOCOUNT ON;
--#region SQL Server Maintenance Solution
/*
SQL Server Maintenance Solution - SQL Server 2008, SQL Server 2008 R2, SQL Server 2012, SQL Server 2014, SQL Server 2016, SQL Server 2017, SQL Server 2019, and SQL Server 2022
Backup: https://ola.hallengren.com/sql-server-backup.html
Integrity Check: https://ola.hallengren.com/sql-server-integrity-check.html
Index and Statistics Maintenance: https://ola.hallengren.com/sql-server-index-and-statistics-maintenance.html
License: https://ola.hallengren.com/license.html
GitHub: https://github.com/olahallengren/sql-server-maintenance-solution
Version: 2025-07-22 16:49:16
You can contact me by e-mail at ola@hallengren.com.
Ola Hallengren
https://ola.hallengren.com
*/
USE [master]; -- Specify the database in which the objects will be created.
SET NOCOUNT ON;
DECLARE @CreateJobs NVARCHAR(MAX) = 'N'; -- Specify whether jobs should be created.
DECLARE @BackupDirectory NVARCHAR(MAX) = NULL; -- Specify the backup root directory. If no directory is specified, the default backup directory is used.
DECLARE @BackupURL NVARCHAR(MAX) = NULL; -- Specify the backup root URL.
DECLARE @CleanupTime INT = NULL; -- Time in hours, after which backup files are deleted. If no time is specified, then no backup files are deleted.
DECLARE @OutputFileDirectory NVARCHAR(MAX) = NULL; -- Specify the output file directory. If no directory is specified, then the SQL Server error log directory is used.
DECLARE @LogToTable NVARCHAR(MAX) = 'Y'; -- Log commands to a table.
DECLARE @ErrorMessage NVARCHAR(MAX);
IF IS_SRVROLEMEMBER('sysadmin') = 0 AND NOT (EXISTS (SELECT * FROM [sys].[databases] WHERE [name] = 'rdsadmin') AND SUSER_SNAME(0x01) = 'rdsa')
BEGIN
SET @ErrorMessage = 'You need to be a member of the SysAdmin server role to install the SQL Server Maintenance Solution.';
RAISERROR(@ErrorMessage,16,1) WITH NOWAIT;
END;
IF NOT (SELECT [compatibility_level] FROM [sys].[databases] WHERE [name] = DB_NAME()) >= 90
BEGIN
SET @ErrorMessage = 'The database ' + QUOTENAME(DB_NAME()) + ' has to be in compatibility level 90 or higher.';
RAISERROR(@ErrorMessage,16,1) WITH NOWAIT;
END;
IF @BackupDirectory IS NOT NULL AND @BackupURL IS NOT NULL
BEGIN
SET @ErrorMessage = 'Only one of the variables @BackupDirectory and @BackupURL can be set.';
RAISERROR(@ErrorMessage,16,1) WITH NOWAIT;
END;
IF @BackupURL IS NOT NULL AND @CleanupTime IS NOT NULL
BEGIN
SET @ErrorMessage = 'The variable @CleanupTime is not supported with backup to URL.';
RAISERROR(@ErrorMessage,16,1) WITH NOWAIT;
END;
IF OBJECT_ID('tempdb..#Config') IS NOT NULL DROP TABLE #Config;
CREATE TABLE #Config ([Name] NVARCHAR(MAX),
[Value] NVARCHAR(MAX));
INSERT INTO #Config ([Name], [Value]) VALUES('CreateJobs', @CreateJobs);
INSERT INTO #Config ([Name], [Value]) VALUES('BackupDirectory', @BackupDirectory);
INSERT INTO #Config ([Name], [Value]) VALUES('BackupURL', @BackupURL);
INSERT INTO #Config ([Name], [Value]) VALUES('CleanupTime', @CleanupTime);
INSERT INTO #Config ([Name], [Value]) VALUES('OutputFileDirectory', @OutputFileDirectory);
INSERT INTO #Config ([Name], [Value]) VALUES('LogToTable', @LogToTable);
INSERT INTO #Config ([Name], [Value]) VALUES('DatabaseName', DB_NAME());
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
IF NOT EXISTS (SELECT * FROM [sys].[objects] WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[CommandLog]') AND TYPE IN (N'U'))
BEGIN
CREATE TABLE [dbo].[CommandLog](
[ID] [int] IDENTITY(1,1) NOT NULL,
[DatabaseName] [sysname] NULL,
[SchemaName] [sysname] NULL,
[ObjectName] [sysname] NULL,
[ObjectType] [char](2) NULL,
[IndexName] [sysname] NULL,
[IndexType] [tinyint] NULL,
[StatisticsName] [sysname] NULL,
[PartitionNumber] [int] NULL,
[ExtendedInfo] [xml] NULL,
[Command] [nvarchar](MAX) NOT NULL,
[CommandType] [nvarchar](60) NOT NULL,
[StartTime] [datetime2](7) NOT NULL,
[EndTime] [datetime2](7) NULL,
[ErrorNumber] [int] NULL,
[ErrorMessage] [nvarchar](MAX) NULL,
CONSTRAINT [PK_CommandLog] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
);
END;
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
IF NOT EXISTS (SELECT * FROM [sys].[objects] WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[CommandExecute]') AND TYPE IN (N'P', N'PC'))
BEGIN
EXECUTE [dbo].sp_executesql @statement = N'CREATE PROCEDURE [dbo].[CommandExecute] AS';
END;
GO
ALTER PROCEDURE [dbo].[CommandExecute]
@DatabaseContext NVARCHAR(MAX),
@Command NVARCHAR(MAX),
@CommandType NVARCHAR(MAX),
@Mode INT,
@Comment NVARCHAR(MAX) = NULL,
@DatabaseName NVARCHAR(MAX) = NULL,
@SchemaName NVARCHAR(MAX) = NULL,
@ObjectName NVARCHAR(MAX) = NULL,
@ObjectType NVARCHAR(MAX) = NULL,
@IndexName NVARCHAR(MAX) = NULL,
@IndexType INT = NULL,
@StatisticsName NVARCHAR(MAX) = NULL,
@PartitionNumber INT = NULL,
@ExtendedInfo XML = NULL,
@LockMessageSeverity INT = 16,
@ExecuteAsUser NVARCHAR(MAX) = NULL,
@LogToTable NVARCHAR(MAX),
@Execute NVARCHAR(MAX)
AS
BEGIN
----------------------------------------------------------------------------------------------------
--// Source: https://ola.hallengren.com //--
--// License: https://ola.hallengren.com/license.html //--
--// GitHub: https://github.com/olahallengren/sql-server-maintenance-solution //--
--// Version: 2025-07-22 16:49:16 //--
----------------------------------------------------------------------------------------------------
SET NOCOUNT ON;
DECLARE @StartMessage NVARCHAR(MAX);
DECLARE @EndMessage NVARCHAR(MAX);
DECLARE @ErrorMessage NVARCHAR(MAX);
DECLARE @ErrorMessageOriginal NVARCHAR(MAX);
DECLARE @Severity INT;
DECLARE @Errors TABLE ([Id] INT IDENTITY PRIMARY KEY,
[Message] NVARCHAR(MAX) NOT NULL,
[severity] INT NOT NULL,
[State] INT);
DECLARE @CurrentMessage NVARCHAR(MAX);
DECLARE @CurrentSeverity INT;
DECLARE @CurrentState INT;
DECLARE @sp_executesql NVARCHAR(MAX) = QUOTENAME(@DatabaseContext) + '.sys.sp_executesql';
DECLARE @StartTime DATETIME2;
DECLARE @EndTime DATETIME2;
DECLARE @ID INT;
DECLARE @Error INT = 0;
DECLARE @ReturnCode INT = 0;
DECLARE @EmptyLine NVARCHAR(MAX) = CHAR(9);
DECLARE @RevertCommand NVARCHAR(MAX);
----------------------------------------------------------------------------------------------------
--// Check core requirements //--
----------------------------------------------------------------------------------------------------
IF NOT (SELECT [compatibility_level] FROM [sys].[databases] WHERE [name] = DB_NAME()) >= 90
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The database ' + QUOTENAME(DB_NAME()) + ' has to be in compatibility level 90 or higher.', 16, 1;
END;
IF NOT (SELECT [uses_ansi_nulls] FROM [sys].[sql_modules] WHERE [object_id] = @@PROCID) = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'ANSI_NULLS has to be set to ON for the stored procedure.', 16, 1;
END;
IF NOT (SELECT [uses_quoted_identifier] FROM [sys].[sql_modules] WHERE [object_id] = @@PROCID) = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'QUOTED_IDENTIFIER has to be set to ON for the stored procedure.', 16, 1;
END;
IF @LogToTable = 'Y' AND NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'U' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'CommandLog')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The table CommandLog is missing. Download https://ola.hallengren.com/scripts/CommandLog.sql.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Check input parameters //--
----------------------------------------------------------------------------------------------------
IF @DatabaseContext IS NULL OR NOT EXISTS (SELECT * FROM [sys].[databases] WHERE [name] = @DatabaseContext)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseContext is not supported.', 16, 1;
END;
IF @Command IS NULL OR @Command = ''
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Command is not supported.', 16, 1;
END;
IF @CommandType IS NULL OR @CommandType = '' OR LEN(@CommandType) > 60
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CommandType is not supported.', 16, 1;
END;
IF @Mode NOT IN(1,2) OR @Mode IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Mode is not supported.', 16, 1;
END;
IF @LockMessageSeverity NOT IN(10,16) OR @LockMessageSeverity IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LockMessageSeverity is not supported.', 16, 1;
END;
IF LEN(@ExecuteAsUser) > 128
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ExecuteAsUser is not supported.', 16, 1;
END;
IF @LogToTable NOT IN('Y','N') OR @LogToTable IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LogToTable is not supported.', 16, 1;
END;
IF @Execute NOT IN('Y','N') OR @Execute IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Execute is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Raise errors //--
----------------------------------------------------------------------------------------------------
DECLARE ErrorCursor CURSOR FAST_FORWARD FOR SELECT [Message], [severity], [State] FROM @Errors ORDER BY [ID] ASC;
OPEN ErrorCursor;
FETCH ErrorCursor INTO @CurrentMessage, @CurrentSeverity, @CurrentState;
WHILE @@FETCH_STATUS = 0
BEGIN
RAISERROR('%s', @CurrentSeverity, @CurrentState, @CurrentMessage) WITH NOWAIT;
RAISERROR(@EmptyLine, 10, 1) WITH NOWAIT;
FETCH NEXT FROM ErrorCursor INTO @CurrentMessage, @CurrentSeverity, @CurrentState;
END;
CLOSE ErrorCursor;
DEALLOCATE ErrorCursor;
IF EXISTS (SELECT * FROM @Errors WHERE [severity] >= 16)
BEGIN
SET @ReturnCode = 50000;
GOTO ReturnCode;
END;
----------------------------------------------------------------------------------------------------
--// Execute as user //--
----------------------------------------------------------------------------------------------------
IF @ExecuteAsUser IS NOT NULL
BEGIN
SET @Command = 'EXECUTE AS USER = ''' + REPLACE(@ExecuteAsUser,'''','''''') + '''; ' + @Command + '; REVERT;';
SET @RevertCommand = 'REVERT';
END;
----------------------------------------------------------------------------------------------------
--// Log initial information //--
----------------------------------------------------------------------------------------------------
SET @StartTime = SYSDATETIME();
SET @StartMessage = 'Date and time: ' + CONVERT(NVARCHAR,@StartTime,120);
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Database context: ' + QUOTENAME(@DatabaseContext);
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Command: ' + @Command;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
IF @Comment IS NOT NULL
BEGIN
SET @StartMessage = 'Comment: ' + @Comment;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
END;
IF @LogToTable = 'Y'
BEGIN
INSERT INTO [dbo].CommandLog (DatabaseName, SchemaName, ObjectName, ObjectType, IndexName, IndexType, StatisticsName, PartitionNumber, ExtendedInfo, CommandType, [command], [starttime])
VALUES (@DatabaseName, @SchemaName, @ObjectName, @ObjectType, @IndexName, @IndexType, @StatisticsName, @PartitionNumber, @ExtendedInfo, @CommandType, @Command, @StartTime);
END;
SET @ID = SCOPE_IDENTITY();
----------------------------------------------------------------------------------------------------
--// Execute command //--
----------------------------------------------------------------------------------------------------
IF @Mode = 1 AND @Execute = 'Y'
BEGIN
EXECUTE @sp_executesql @stmt = @Command;
SET @Error = @@ERROR;
SET @ReturnCode = @Error;
END;
IF @Mode = 2 AND @Execute = 'Y'
BEGIN
BEGIN TRY
EXECUTE @sp_executesql @stmt = @Command;
END TRY
BEGIN CATCH
SET @Error = ERROR_NUMBER();
SET @ErrorMessageOriginal = ERROR_MESSAGE();
SET @ErrorMessage = 'Msg ' + CAST(ERROR_NUMBER() AS NVARCHAR) + ', ' + ISNULL(ERROR_MESSAGE(),'');
SET @Severity = CASE WHEN ERROR_NUMBER() IN(1205,1222) THEN @LockMessageSeverity ELSE 16 END;
RAISERROR('%s',@Severity,1,@ErrorMessage) WITH NOWAIT;
IF NOT (ERROR_NUMBER() IN(1205,1222) AND @LockMessageSeverity = 10)
BEGIN
SET @ReturnCode = ERROR_NUMBER();
END;
IF @ExecuteAsUser IS NOT NULL
BEGIN
EXECUTE @sp_executesql @RevertCommand;
END;
END CATCH;
END;
----------------------------------------------------------------------------------------------------
--// Log completing information //--
----------------------------------------------------------------------------------------------------
SET @EndTime = SYSDATETIME();
SET @EndMessage = 'Outcome: ' + CASE WHEN @Execute = 'N' THEN 'Not Executed' WHEN @Error = 0 THEN 'Succeeded' ELSE 'Failed' END;
RAISERROR('%s',10,1,@EndMessage) WITH NOWAIT;
SET @EndMessage = 'Duration: ' + CASE WHEN (DATEDIFF(SECOND,@StartTime,@EndTime) / (24 * 3600)) > 0 THEN CAST((DATEDIFF(SECOND,@StartTime,@EndTime) / (24 * 3600)) AS NVARCHAR) + '.' ELSE '' END + CONVERT(NVARCHAR,DATEADD(SECOND,DATEDIFF(SECOND,@StartTime,@EndTime),'1900-01-01'),108);
RAISERROR('%s',10,1,@EndMessage) WITH NOWAIT;
SET @EndMessage = 'Date and time: ' + CONVERT(NVARCHAR,@EndTime,120);
RAISERROR('%s',10,1,@EndMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF @LogToTable = 'Y'
BEGIN
UPDATE [dbo].CommandLog
SET [endtime] = @EndTime,
ErrorNumber = CASE WHEN @Execute = 'N' THEN NULL ELSE @Error END,
ErrorMessage = @ErrorMessageOriginal
WHERE [Id] = @ID;
END;
ReturnCode:;
IF @ReturnCode <> 0
BEGIN
RETURN @ReturnCode;
END;
----------------------------------------------------------------------------------------------------
END;
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
IF NOT EXISTS (SELECT * FROM [sys].[objects] WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[DatabaseBackup]') AND TYPE IN (N'P', N'PC'))
BEGIN
EXECUTE [dbo].sp_executesql @statement = N'CREATE PROCEDURE [dbo].[DatabaseBackup] AS';
END;
GO
ALTER PROCEDURE [dbo].[DatabaseBackup]
@Databases NVARCHAR(MAX) = NULL,
@Directory NVARCHAR(MAX) = NULL,
@BackupType NVARCHAR(MAX),
@Verify NVARCHAR(MAX) = 'N',
@CleanupTime INT = NULL,
@CleanupMode NVARCHAR(MAX) = 'AFTER_BACKUP',
@Compress NVARCHAR(MAX) = NULL,
@CompressionAlgorithm NVARCHAR(MAX) = NULL,
@CompressionLevel NVARCHAR(MAX) = NULL,
@CopyOnly NVARCHAR(MAX) = 'N',
@ChangeBackupType NVARCHAR(MAX) = 'N',
@BackupSoftware NVARCHAR(MAX) = NULL,
@Checksum NVARCHAR(MAX) = NULL,
@BlockSize INT = NULL,
@BufferCount INT = NULL,
@MaxTransferSize INT = NULL,
@NumberOfFiles INT = NULL,
@MinBackupSizeForMultipleFiles INT = NULL,
@MaxFileSize INT = NULL,
@CompressionLevelNumeric INT = NULL,
@Description NVARCHAR(MAX) = NULL,
@BackupSetName NVARCHAR(MAX) = NULL,
@Threads INT = NULL,
@Throttle INT = NULL,
@Encrypt NVARCHAR(MAX) = 'N',
@EncryptionAlgorithm NVARCHAR(MAX) = NULL,
@ServerCertificate NVARCHAR(MAX) = NULL,
@ServerAsymmetricKey NVARCHAR(MAX) = NULL,
@EncryptionKey NVARCHAR(MAX) = NULL,
@ReadWriteFileGroups NVARCHAR(MAX) = 'N',
@OverrideBackupPreference NVARCHAR(MAX) = 'N',
@NoRecovery NVARCHAR(MAX) = 'N',
@URL NVARCHAR(MAX) = NULL,
@Credential NVARCHAR(MAX) = NULL,
@MirrorDirectory NVARCHAR(MAX) = NULL,
@MirrorCleanupTime INT = NULL,
@MirrorCleanupMode NVARCHAR(MAX) = 'AFTER_BACKUP',
@MirrorURL NVARCHAR(MAX) = NULL,
@AvailabilityGroups NVARCHAR(MAX) = NULL,
@Updateability NVARCHAR(MAX) = 'ALL',
@AdaptiveCompression NVARCHAR(MAX) = NULL,
@ModificationLevel INT = NULL,
@MinDatabaseSizeForDifferentialBackup INT = NULL,
@LogSizeSinceLastLogBackup INT = NULL,
@TimeSinceLastLogBackup INT = NULL,
@DataDomainBoostHost NVARCHAR(MAX) = NULL,
@DataDomainBoostUser NVARCHAR(MAX) = NULL,
@DataDomainBoostDevicePath NVARCHAR(MAX) = NULL,
@DataDomainBoostLockboxPath NVARCHAR(MAX) = NULL,
@DirectoryStructure NVARCHAR(MAX) = '{ServerName}${InstanceName}{DirectorySeparator}{DatabaseName}{DirectorySeparator}{BackupType}_{Partial}_{CopyOnly}',
@AvailabilityGroupDirectoryStructure NVARCHAR(MAX) = '{ClusterName}${AvailabilityGroupName}{DirectorySeparator}{DatabaseName}{DirectorySeparator}{BackupType}_{Partial}_{CopyOnly}',
@DirectoryStructureCase NVARCHAR(MAX) = NULL,
@FileName NVARCHAR(MAX) = '{ServerName}${InstanceName}_{DatabaseName}_{BackupType}_{Partial}_{CopyOnly}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
@AvailabilityGroupFileName NVARCHAR(MAX) = '{ClusterName}${AvailabilityGroupName}_{DatabaseName}_{BackupType}_{Partial}_{CopyOnly}_{Year}{Month}{Day}_{Hour}{Minute}{Second}_{FileNumber}.{FileExtension}',
@FileNameCase NVARCHAR(MAX) = NULL,
@TokenTimezone NVARCHAR(MAX) = 'LOCAL',
@FileExtensionFull NVARCHAR(MAX) = NULL,
@FileExtensionDiff NVARCHAR(MAX) = NULL,
@FileExtensionLog NVARCHAR(MAX) = NULL,
@Init NVARCHAR(MAX) = 'N',
@Format NVARCHAR(MAX) = 'N',
@ObjectLevelRecoveryMap NVARCHAR(MAX) = 'N',
@ExcludeLogShippedFromLogBackup NVARCHAR(MAX) = 'Y',
@DirectoryCheck NVARCHAR(MAX) = 'Y',
@BackupOptions NVARCHAR(MAX) = NULL,
@Stats INT = NULL,
@ExpireDate DATETIME = NULL,
@RetainDays INT = NULL,
@StringDelimiter NVARCHAR(MAX) = ',',
@DatabaseOrder NVARCHAR(MAX) = NULL,
@DatabasesInParallel NVARCHAR(MAX) = 'N',
@LogToTable NVARCHAR(MAX) = 'N',
@Execute NVARCHAR(MAX) = 'Y'
AS
BEGIN
----------------------------------------------------------------------------------------------------
--// Source: https://ola.hallengren.com //--
--// License: https://ola.hallengren.com/license.html //--
--// GitHub: https://github.com/olahallengren/sql-server-maintenance-solution //--
--// Version: 2025-07-22 16:49:16 //--
----------------------------------------------------------------------------------------------------
SET NOCOUNT ON;
DECLARE @StartMessage NVARCHAR(MAX);
DECLARE @EndMessage NVARCHAR(MAX);
DECLARE @DatabaseMessage NVARCHAR(MAX);
DECLARE @ErrorMessage NVARCHAR(MAX);
DECLARE @StartTime DATETIME2 = SYSDATETIME();
DECLARE @SchemaName NVARCHAR(MAX) = OBJECT_SCHEMA_NAME(@@PROCID);
DECLARE @ObjectName NVARCHAR(MAX) = OBJECT_NAME(@@PROCID);
DECLARE @VersionTimestamp NVARCHAR(MAX) = SUBSTRING(OBJECT_DEFINITION(@@PROCID),CHARINDEX('--// Version: ',OBJECT_DEFINITION(@@PROCID)) + LEN('--// Version: ') + 1, 19);
DECLARE @Parameters NVARCHAR(MAX);
DECLARE @HostPlatform NVARCHAR(MAX);
DECLARE @DirectorySeparator NVARCHAR(MAX);
DECLARE @Updated BIT;
DECLARE @Cluster NVARCHAR(MAX);
DECLARE @DefaultDirectory NVARCHAR(4000);
DECLARE @QueueID INT;
DECLARE @QueueStartTime DATETIME2;
DECLARE @CurrentRootDirectoryID INT;
DECLARE @CurrentRootDirectoryPath NVARCHAR(4000);
DECLARE @CurrentDBID INT;
DECLARE @CurrentDatabaseName NVARCHAR(MAX);
DECLARE @CurrentDatabase_sp_executesql NVARCHAR(MAX);
DECLARE @CurrentUserAccess NVARCHAR(MAX);
DECLARE @CurrentIsReadOnly BIT;
DECLARE @CurrentDatabaseState NVARCHAR(MAX);
DECLARE @CurrentInStandby BIT;
DECLARE @CurrentRecoveryModel NVARCHAR(MAX);
DECLARE @CurrentDatabaseSize BIGINT;
DECLARE @CurrentIsEncrypted BIT;
DECLARE @CurrentBackupType NVARCHAR(MAX);
DECLARE @CurrentMaxTransferSize INT;
DECLARE @CurrentNumberOfFiles INT;
DECLARE @CurrentFileExtension NVARCHAR(MAX);
DECLARE @CurrentFileNumber INT;
DECLARE @CurrentDifferentialBaseLSN NUMERIC(25,0);
DECLARE @CurrentDifferentialBaseIsSnapshot BIT;
DECLARE @CurrentLogLSN NUMERIC(25,0);
DECLARE @CurrentLatestBackup DATETIME2;
DECLARE @CurrentDatabaseNameFS NVARCHAR(MAX);
DECLARE @CurrentDirectoryStructure NVARCHAR(MAX);
DECLARE @CurrentDatabaseFileName NVARCHAR(MAX);
DECLARE @CurrentMaxFilePathLength NVARCHAR(MAX);
DECLARE @CurrentFileName NVARCHAR(MAX);
DECLARE @CurrentDirectoryID INT;
DECLARE @CurrentDirectoryPath NVARCHAR(4000);
DECLARE @CurrentFilePath NVARCHAR(MAX);
DECLARE @CurrentDate DATETIME2;
DECLARE @CurrentDateUTC DATETIME2;
DECLARE @CurrentCleanupDate DATETIME2;
DECLARE @CurrentReplicaID UNIQUEIDENTIFIER;
DECLARE @CurrentAvailabilityGroupID UNIQUEIDENTIFIER;
DECLARE @CurrentAvailabilityGroup NVARCHAR(MAX);
DECLARE @CurrentAvailabilityGroupRole NVARCHAR(MAX);
DECLARE @CurrentAvailabilityGroupDatabaseReplicaSynchronizationState NVARCHAR(MAX);
DECLARE @CurrentAvailabilityGroupDatabaseReplicaSynchronizationHealth NVARCHAR(MAX);
DECLARE @CurrentAvailabilityGroupBackupPreference NVARCHAR(MAX);
DECLARE @CurrentIsPreferredBackupReplica BIT;
DECLARE @CurrentDatabaseMirroringRole NVARCHAR(MAX);
DECLARE @CurrentLogShippingRole NVARCHAR(MAX);
DECLARE @CurrentBackupOperationSupportedOnSecondaryReplicas BIT;
DECLARE @CurrentBackupSetID INT;
DECLARE @CurrentIsMirror BIT;
DECLARE @CurrentLastLogBackup DATETIME2;
DECLARE @CurrentLogSizeSinceLastLogBackup FLOAT;
DECLARE @CurrentAllocatedExtentPageCount BIGINT;
DECLARE @CurrentModifiedExtentPageCount BIGINT;
DECLARE @CurrentDatabaseContext NVARCHAR(MAX);
DECLARE @CurrentCommand NVARCHAR(MAX);
DECLARE @CurrentCommandOutput INT;
DECLARE @CurrentCommandType NVARCHAR(MAX);
DECLARE @Errors TABLE ([Id] INT IDENTITY PRIMARY KEY,
[Message] NVARCHAR(MAX) NOT NULL,
[severity] INT NOT NULL,
[State] INT);
DECLARE @CurrentMessage NVARCHAR(MAX);
DECLARE @CurrentSeverity INT;
DECLARE @CurrentState INT;
DECLARE @Directories TABLE ([Id] INT PRIMARY KEY,
DirectoryPath NVARCHAR(MAX),
[mirror] BIT,
Completed BIT);
DECLARE @URLs TABLE ([Id] INT PRIMARY KEY,
DirectoryPath NVARCHAR(MAX),
[mirror] BIT);
DECLARE @DirectoryInfo TABLE (FileExists BIT,
FileIsADirectory BIT,
ParentDirectoryExists BIT);
DECLARE @tmpDatabases TABLE ([Id] INT IDENTITY,
DatabaseName NVARCHAR(MAX),
DatabaseNameFS NVARCHAR(MAX),
DatabaseType NVARCHAR(MAX),
AvailabilityGroup BIT,
StartPosition INT,
DatabaseSize BIGINT,
LogSizeSinceLastLogBackup FLOAT,
[Order] INT,
Selected BIT,
Completed BIT,
PRIMARY KEY(Selected, Completed, [Order], [Id]));
DECLARE @tmpAvailabilityGroups TABLE ([Id] INT IDENTITY PRIMARY KEY,
AvailabilityGroupName NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @tmpDatabasesAvailabilityGroups TABLE (DatabaseName NVARCHAR(MAX),
AvailabilityGroupName NVARCHAR(MAX));
DECLARE @SelectedDatabases TABLE (DatabaseName NVARCHAR(MAX),
DatabaseType NVARCHAR(MAX),
AvailabilityGroup NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @SelectedAvailabilityGroups TABLE (AvailabilityGroupName NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @CurrentBackupOutput BIT;
DECLARE @CurrentBackupSet TABLE ([Id] INT IDENTITY PRIMARY KEY,
[mirror] BIT,
VerifyCompleted BIT,
VerifyOutput INT);
DECLARE @CurrentDirectories TABLE ([Id] INT PRIMARY KEY,
DirectoryPath NVARCHAR(MAX),
[mirror] BIT,
DirectoryNumber INT,
CleanupDate DATETIME2,
CleanupMode NVARCHAR(MAX),
CreateCompleted BIT,
CleanupCompleted BIT,
CreateOutput INT,
CleanupOutput INT);
DECLARE @CurrentURLs TABLE ([Id] INT PRIMARY KEY,
DirectoryPath NVARCHAR(MAX),
[mirror] BIT,
DirectoryNumber INT);
DECLARE @CurrentFiles TABLE ([Type] NVARCHAR(MAX),
FilePath NVARCHAR(MAX),
[mirror] BIT);
DECLARE @CurrentCleanupDates TABLE (CleanupDate DATETIME2,
[mirror] BIT);
DECLARE @Error INT = 0;
DECLARE @ReturnCode INT = 0;
DECLARE @EmptyLine NVARCHAR(MAX) = CHAR(9);
DECLARE @Version NUMERIC(18,10) = CAST(LEFT(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)),CHARINDEX('.',CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX))) - 1) + '.' + REPLACE(RIGHT(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)), LEN(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX))) - CHARINDEX('.',CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)))),'.','') AS NUMERIC(18,10));
IF @Version >= 14
BEGIN
SELECT @HostPlatform = [host_platform]
FROM [sys].[dm_os_host_info];
END;
ELSE
BEGIN
SET @HostPlatform = 'Windows';
END;
DECLARE @AmazonRDS BIT = CASE WHEN EXISTS (SELECT * FROM [sys].[databases] WHERE [name] = 'rdsadmin') AND SUSER_SNAME(0x01) = 'rdsa' THEN 1 ELSE 0 END;
----------------------------------------------------------------------------------------------------
--// Log initial information //--
----------------------------------------------------------------------------------------------------
SET @Parameters = '@Databases = ' + ISNULL('''' + REPLACE(@Databases,'''','''''') + '''','NULL');
SET @Parameters += ', @Directory = ' + ISNULL('''' + REPLACE(@Directory,'''','''''') + '''','NULL');
SET @Parameters += ', @BackupType = ' + ISNULL('''' + REPLACE(@BackupType,'''','''''') + '''','NULL');
SET @Parameters += ', @Verify = ' + ISNULL('''' + REPLACE(@Verify,'''','''''') + '''','NULL');
SET @Parameters += ', @CleanupTime = ' + ISNULL(CAST(@CleanupTime AS NVARCHAR),'NULL');
SET @Parameters += ', @CleanupMode = ' + ISNULL('''' + REPLACE(@CleanupMode,'''','''''') + '''','NULL');
SET @Parameters += ', @Compress = ' + ISNULL('''' + REPLACE(@Compress,'''','''''') + '''','NULL');
SET @Parameters += ', @CompressionAlgorithm = ' + ISNULL('''' + REPLACE(@CompressionAlgorithm,'''','''''') + '''','NULL');
SET @Parameters += ', @CompressionLevel = ' + ISNULL('''' + REPLACE(@CompressionLevel,'''','''''') + '''','NULL');
SET @Parameters += ', @CopyOnly = ' + ISNULL('''' + REPLACE(@CopyOnly,'''','''''') + '''','NULL');
SET @Parameters += ', @ChangeBackupType = ' + ISNULL('''' + REPLACE(@ChangeBackupType,'''','''''') + '''','NULL');
SET @Parameters += ', @BackupSoftware = ' + ISNULL('''' + REPLACE(@BackupSoftware,'''','''''') + '''','NULL');
SET @Parameters += ', @Checksum = ' + ISNULL('''' + REPLACE(@Checksum,'''','''''') + '''','NULL');
SET @Parameters += ', @BlockSize = ' + ISNULL(CAST(@BlockSize AS NVARCHAR),'NULL');
SET @Parameters += ', @BufferCount = ' + ISNULL(CAST(@BufferCount AS NVARCHAR),'NULL');
SET @Parameters += ', @MaxTransferSize = ' + ISNULL(CAST(@MaxTransferSize AS NVARCHAR),'NULL');
SET @Parameters += ', @NumberOfFiles = ' + ISNULL(CAST(@NumberOfFiles AS NVARCHAR),'NULL');
SET @Parameters += ', @MinBackupSizeForMultipleFiles = ' + ISNULL(CAST(@MinBackupSizeForMultipleFiles AS NVARCHAR),'NULL');
SET @Parameters += ', @MaxFileSize = ' + ISNULL(CAST(@MaxFileSize AS NVARCHAR),'NULL');
SET @Parameters += ', @CompressionLevelNumeric = ' + ISNULL(CAST(@CompressionLevelNumeric AS NVARCHAR),'NULL');
SET @Parameters += ', @Description = ' + ISNULL('''' + REPLACE(@Description,'''','''''') + '''','NULL');
SET @Parameters += ', @BackupSetName = ' + ISNULL('''' + REPLACE(@BackupSetName,'''','''''') + '''','NULL');
SET @Parameters += ', @Threads = ' + ISNULL(CAST(@Threads AS NVARCHAR),'NULL');
SET @Parameters += ', @Throttle = ' + ISNULL(CAST(@Throttle AS NVARCHAR),'NULL');
SET @Parameters += ', @Encrypt = ' + ISNULL('''' + REPLACE(@Encrypt,'''','''''') + '''','NULL');
SET @Parameters += ', @EncryptionAlgorithm = ' + ISNULL('''' + REPLACE(@EncryptionAlgorithm,'''','''''') + '''','NULL');
SET @Parameters += ', @ServerCertificate = ' + ISNULL('''' + REPLACE(@ServerCertificate,'''','''''') + '''','NULL');
SET @Parameters += ', @ServerAsymmetricKey = ' + ISNULL('''' + REPLACE(@ServerAsymmetricKey,'''','''''') + '''','NULL');
SET @Parameters += ', @EncryptionKey = ' + ISNULL('''' + REPLACE(@EncryptionKey,'''','''''') + '''','NULL');
SET @Parameters += ', @ReadWriteFileGroups = ' + ISNULL('''' + REPLACE(@ReadWriteFileGroups,'''','''''') + '''','NULL');
SET @Parameters += ', @OverrideBackupPreference = ' + ISNULL('''' + REPLACE(@OverrideBackupPreference,'''','''''') + '''','NULL');
SET @Parameters += ', @NoRecovery = ' + ISNULL('''' + REPLACE(@NoRecovery,'''','''''') + '''','NULL');
SET @Parameters += ', @URL = ' + ISNULL('''' + REPLACE(@URL,'''','''''') + '''','NULL');
SET @Parameters += ', @Credential = ' + ISNULL('''' + REPLACE(@Credential,'''','''''') + '''','NULL');
SET @Parameters += ', @MirrorDirectory = ' + ISNULL('''' + REPLACE(@MirrorDirectory,'''','''''') + '''','NULL');
SET @Parameters += ', @MirrorCleanupTime = ' + ISNULL(CAST(@MirrorCleanupTime AS NVARCHAR),'NULL');
SET @Parameters += ', @MirrorCleanupMode = ' + ISNULL('''' + REPLACE(@MirrorCleanupMode,'''','''''') + '''','NULL');
SET @Parameters += ', @MirrorURL = ' + ISNULL('''' + REPLACE(@MirrorURL,'''','''''') + '''','NULL');
SET @Parameters += ', @AvailabilityGroups = ' + ISNULL('''' + REPLACE(@AvailabilityGroups,'''','''''') + '''','NULL');
SET @Parameters += ', @Updateability = ' + ISNULL('''' + REPLACE(@Updateability,'''','''''') + '''','NULL');
SET @Parameters += ', @AdaptiveCompression = ' + ISNULL('''' + REPLACE(@AdaptiveCompression,'''','''''') + '''','NULL');
SET @Parameters += ', @ModificationLevel = ' + ISNULL(CAST(@ModificationLevel AS NVARCHAR),'NULL');
SET @Parameters += ', @MinDatabaseSizeForDifferentialBackup = ' + ISNULL('''' + REPLACE(@MinDatabaseSizeForDifferentialBackup,'''','''''') + '''','NULL');
SET @Parameters += ', @LogSizeSinceLastLogBackup = ' + ISNULL(CAST(@LogSizeSinceLastLogBackup AS NVARCHAR),'NULL');
SET @Parameters += ', @TimeSinceLastLogBackup = ' + ISNULL(CAST(@TimeSinceLastLogBackup AS NVARCHAR),'NULL');
SET @Parameters += ', @DataDomainBoostHost = ' + ISNULL('''' + REPLACE(@DataDomainBoostHost,'''','''''') + '''','NULL');
SET @Parameters += ', @DataDomainBoostUser = ' + ISNULL('''' + REPLACE(@DataDomainBoostUser,'''','''''') + '''','NULL');
SET @Parameters += ', @DataDomainBoostDevicePath = ' + ISNULL('''' + REPLACE(@DataDomainBoostDevicePath,'''','''''') + '''','NULL');
SET @Parameters += ', @DataDomainBoostLockboxPath = ' + ISNULL('''' + REPLACE(@DataDomainBoostLockboxPath,'''','''''') + '''','NULL');
SET @Parameters += ', @DirectoryStructure = ' + ISNULL('''' + REPLACE(@DirectoryStructure,'''','''''') + '''','NULL');
SET @Parameters += ', @AvailabilityGroupDirectoryStructure = ' + ISNULL('''' + REPLACE(@AvailabilityGroupDirectoryStructure,'''','''''') + '''','NULL');
SET @Parameters += ', @DirectoryStructureCase = ' + ISNULL('''' + REPLACE(@DirectoryStructureCase,'''','''''') + '''','NULL');
SET @Parameters += ', @FileName = ' + ISNULL('''' + REPLACE(@FileName,'''','''''') + '''','NULL');
SET @Parameters += ', @AvailabilityGroupFileName = ' + ISNULL('''' + REPLACE(@AvailabilityGroupFileName,'''','''''') + '''','NULL');
SET @Parameters += ', @FileNameCase = ' + ISNULL('''' + REPLACE(@FileNameCase,'''','''''') + '''','NULL');
SET @Parameters += ', @TokenTimezone = ' + ISNULL('''' + REPLACE(@TokenTimezone,'''','''''') + '''','NULL');
SET @Parameters += ', @FileExtensionFull = ' + ISNULL('''' + REPLACE(@FileExtensionFull,'''','''''') + '''','NULL');
SET @Parameters += ', @FileExtensionDiff = ' + ISNULL('''' + REPLACE(@FileExtensionDiff,'''','''''') + '''','NULL');
SET @Parameters += ', @FileExtensionLog = ' + ISNULL('''' + REPLACE(@FileExtensionLog,'''','''''') + '''','NULL');
SET @Parameters += ', @Init = ' + ISNULL('''' + REPLACE(@Init,'''','''''') + '''','NULL');
SET @Parameters += ', @Format = ' + ISNULL('''' + REPLACE(@Format,'''','''''') + '''','NULL');
SET @Parameters += ', @ObjectLevelRecoveryMap = ' + ISNULL('''' + REPLACE(@ObjectLevelRecoveryMap,'''','''''') + '''','NULL');
SET @Parameters += ', @ExcludeLogShippedFromLogBackup = ' + ISNULL('''' + REPLACE(@ExcludeLogShippedFromLogBackup,'''','''''') + '''','NULL');
SET @Parameters += ', @DirectoryCheck = ' + ISNULL('''' + REPLACE(@DirectoryCheck,'''','''''') + '''','NULL');
SET @Parameters += ', @BackupOptions = ' + ISNULL('''' + REPLACE(@BackupOptions,'''','''''') + '''','NULL');
SET @Parameters += ', @Stats = ' + ISNULL(CAST(@Stats AS NVARCHAR),'NULL');
SET @Parameters += ', @ExpireDate = ' + ISNULL('''' + CONVERT(NVARCHAR, @ExpireDate, 21) + '''','NULL');
SET @Parameters += ', @RetainDays = ' + ISNULL(CAST(@RetainDays AS NVARCHAR),'NULL');
SET @Parameters += ', @StringDelimiter = ' + ISNULL('''' + REPLACE(@StringDelimiter,'''','''''') + '''','NULL');
SET @Parameters += ', @DatabaseOrder = ' + ISNULL('''' + REPLACE(@DatabaseOrder,'''','''''') + '''','NULL');
SET @Parameters += ', @DatabasesInParallel = ' + ISNULL('''' + REPLACE(@DatabasesInParallel,'''','''''') + '''','NULL');
SET @Parameters += ', @LogToTable = ' + ISNULL('''' + REPLACE(@LogToTable,'''','''''') + '''','NULL');
SET @Parameters += ', @Execute = ' + ISNULL('''' + REPLACE(@Execute,'''','''''') + '''','NULL');
SET @StartMessage = 'Date and time: ' + CONVERT(NVARCHAR,@StartTime,120);
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Server: ' + CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(MAX));
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Version: ' + CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX));
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Edition: ' + CAST(SERVERPROPERTY('Edition') AS NVARCHAR(MAX));
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Platform: ' + @HostPlatform;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Procedure: ' + QUOTENAME(DB_NAME()) + '.' + QUOTENAME(@SchemaName) + '.' + QUOTENAME(@ObjectName);
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Parameters: ' + @Parameters;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Version: ' + @VersionTimestamp;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Source: https://ola.hallengren.com';
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
----------------------------------------------------------------------------------------------------
--// Check core requirements //--
----------------------------------------------------------------------------------------------------
IF NOT (SELECT [compatibility_level] FROM [sys].[databases] WHERE [name] = DB_NAME()) >= 90
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The database ' + QUOTENAME(DB_NAME()) + ' has to be in compatibility level 90 or higher.', 16, 1;
END;
IF NOT (SELECT [uses_ansi_nulls] FROM [sys].[sql_modules] WHERE [object_id] = @@PROCID) = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'ANSI_NULLS has to be set to ON for the stored procedure.', 16, 1;
END;
IF NOT (SELECT [uses_quoted_identifier] FROM [sys].[sql_modules] WHERE [object_id] = @@PROCID) = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'QUOTED_IDENTIFIER has to be set to ON for the stored procedure.', 16, 1;
END;
IF NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'P' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'CommandExecute')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The stored procedure CommandExecute is missing. Download https://ola.hallengren.com/scripts/CommandExecute.sql.', 16, 1;
END;
IF EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'P' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'CommandExecute' AND OBJECT_DEFINITION([objects].[object_id]) NOT LIKE '%@DatabaseContext%')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The stored procedure CommandExecute needs to be updated. Download https://ola.hallengren.com/scripts/CommandExecute.sql.', 16, 1;
END;
IF @LogToTable = 'Y' AND NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'U' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'CommandLog')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The table CommandLog is missing. Download https://ola.hallengren.com/scripts/CommandLog.sql.', 16, 1;
END;
IF @DatabasesInParallel = 'Y' AND NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'U' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'Queue')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The table Queue is missing. Download https://ola.hallengren.com/scripts/Queue.sql.', 16, 1;
END;
IF @DatabasesInParallel = 'Y' AND NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'U' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'QueueDatabase')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The table QueueDatabase is missing. Download https://ola.hallengren.com/scripts/QueueDatabase.sql.', 16, 1;
END;
IF @@TRANCOUNT <> 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The transaction count is not 0.', 16, 1;
END;
IF @AmazonRDS = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The stored procedure DatabaseBackup is not supported on Amazon RDS.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Select databases //--
----------------------------------------------------------------------------------------------------
SET @Databases = REPLACE(@Databases, CHAR(10), '');
SET @Databases = REPLACE(@Databases, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @Databases) > 0 SET @Databases = REPLACE(@Databases, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @Databases) > 0 SET @Databases = REPLACE(@Databases, ' ' + @StringDelimiter, @StringDelimiter);
SET @Databases = LTRIM(RTRIM(@Databases));
WITH Databases1 (StartPosition, EndPosition, DatabaseItem) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, 1), 0), LEN(@Databases) + 1) AS EndPosition,
SUBSTRING(@Databases, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, 1), 0), LEN(@Databases) + 1) - 1) AS DatabaseItem
WHERE @Databases IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, EndPosition + 1), 0), LEN(@Databases) + 1) AS EndPosition,
SUBSTRING(@Databases, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, EndPosition + 1), 0), LEN(@Databases) + 1) - EndPosition - 1) AS DatabaseItem
FROM Databases1
WHERE EndPosition < LEN(@Databases) + 1
),
Databases2 (DatabaseItem, StartPosition, Selected) AS
(
SELECT CASE WHEN DatabaseItem LIKE '-%' THEN RIGHT(DatabaseItem,LEN(DatabaseItem) - 1) ELSE DatabaseItem END AS DatabaseItem,
StartPosition,
CASE WHEN DatabaseItem LIKE '-%' THEN 0 ELSE 1 END AS Selected
FROM Databases1
),
Databases3 (DatabaseItem, DatabaseType, AvailabilityGroup, StartPosition, Selected) AS
(
SELECT CASE WHEN DatabaseItem IN('ALL_DATABASES','SYSTEM_DATABASES','USER_DATABASES','AVAILABILITY_GROUP_DATABASES') THEN '%' ELSE DatabaseItem END AS DatabaseItem,
CASE WHEN DatabaseItem = 'SYSTEM_DATABASES' THEN 'S' WHEN DatabaseItem = 'USER_DATABASES' THEN 'U' ELSE NULL END AS DatabaseType,
CASE WHEN DatabaseItem = 'AVAILABILITY_GROUP_DATABASES' THEN 1 ELSE NULL END AvailabilityGroup,
StartPosition,
Selected
FROM Databases2
),
Databases4 (DatabaseName, DatabaseType, AvailabilityGroup, StartPosition, Selected) AS
(
SELECT CASE WHEN LEFT(DatabaseItem,1) = '[' AND RIGHT(DatabaseItem,1) = ']' THEN PARSENAME(DatabaseItem,1) ELSE DatabaseItem END AS DatabaseItem,
DatabaseType,
AvailabilityGroup,
StartPosition,
Selected
FROM Databases3
)
INSERT INTO @SelectedDatabases (DatabaseName, DatabaseType, AvailabilityGroup, StartPosition, Selected)
SELECT DatabaseName,
DatabaseType,
AvailabilityGroup,
StartPosition,
Selected
FROM Databases4
OPTION (MAXRECURSION 0);
IF @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
INSERT INTO @tmpAvailabilityGroups (AvailabilityGroupName, Selected)
SELECT [name] AS AvailabilityGroupName,
0 AS Selected
FROM [sys].[availability_groups];
INSERT INTO @tmpDatabasesAvailabilityGroups (DatabaseName, AvailabilityGroupName)
SELECT [databases].[name],
[availability_groups].[name]
FROM [sys].[databases] [databases]
INNER JOIN [sys].[availability_replicas] [availability_replicas] ON [databases].[replica_id] = [availability_replicas].[replica_id]
INNER JOIN [sys].[availability_groups] [availability_groups] ON [availability_replicas].[group_id] = [availability_groups].[group_id];
END;
INSERT INTO @tmpDatabases (DatabaseName, DatabaseNameFS, DatabaseType, AvailabilityGroup, [Order], Selected, Completed)
SELECT [name] AS DatabaseName,
RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE([name],'\',''),'/',''),':',''),'*',''),'?',''),'"',''),'<',''),'>',''),'|','')) AS DatabaseNameFS,
CASE WHEN [name] IN('master','msdb','model') OR [is_distributor] = 1 THEN 'S' ELSE 'U' END AS DatabaseType,
NULL AS AvailabilityGroup,
0 AS [Order],
0 AS Selected,
0 AS Completed
FROM [sys].[databases]
WHERE [name] <> 'tempdb'
AND [source_database_id] IS NULL
ORDER BY [name] ASC;
UPDATE tmpDatabases
SET AvailabilityGroup = CASE WHEN EXISTS (SELECT * FROM @tmpDatabasesAvailabilityGroups WHERE DatabaseName = tmpDatabases.DatabaseName) THEN 1 ELSE 0 END
FROM @tmpDatabases tmpDatabases;
UPDATE tmpDatabases
SET tmpDatabases.Selected = SelectedDatabases.Selected
FROM @tmpDatabases tmpDatabases
INNER JOIN @SelectedDatabases SelectedDatabases
ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]')
AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL)
AND (tmpDatabases.AvailabilityGroup = SelectedDatabases.AvailabilityGroup OR SelectedDatabases.AvailabilityGroup IS NULL)
WHERE SelectedDatabases.Selected = 1;
UPDATE tmpDatabases
SET tmpDatabases.Selected = SelectedDatabases.Selected
FROM @tmpDatabases tmpDatabases
INNER JOIN @SelectedDatabases SelectedDatabases
ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]')
AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL)
AND (tmpDatabases.AvailabilityGroup = SelectedDatabases.AvailabilityGroup OR SelectedDatabases.AvailabilityGroup IS NULL)
WHERE SelectedDatabases.Selected = 0;
UPDATE tmpDatabases
SET tmpDatabases.StartPosition = SelectedDatabases2.StartPosition
FROM @tmpDatabases tmpDatabases
INNER JOIN (SELECT tmpDatabases.DatabaseName, MIN(SelectedDatabases.StartPosition) AS StartPosition
FROM @tmpDatabases tmpDatabases
INNER JOIN @SelectedDatabases SelectedDatabases
ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]')
AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL)
AND (tmpDatabases.AvailabilityGroup = SelectedDatabases.AvailabilityGroup OR SelectedDatabases.AvailabilityGroup IS NULL)
WHERE SelectedDatabases.Selected = 1
GROUP BY tmpDatabases.DatabaseName) SelectedDatabases2
ON tmpDatabases.DatabaseName = SelectedDatabases2.DatabaseName;
IF @Databases IS NOT NULL AND (NOT EXISTS(SELECT * FROM @SelectedDatabases) OR EXISTS(SELECT * FROM @SelectedDatabases WHERE DatabaseName IS NULL OR DATALENGTH(DatabaseName) = 0))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Databases is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Select availability groups //--
----------------------------------------------------------------------------------------------------
IF @AvailabilityGroups IS NOT NULL AND @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, CHAR(10), '');
SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @AvailabilityGroups) > 0 SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @AvailabilityGroups) > 0 SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, ' ' + @StringDelimiter, @StringDelimiter);
SET @AvailabilityGroups = LTRIM(RTRIM(@AvailabilityGroups));
WITH AvailabilityGroups1 (StartPosition, EndPosition, AvailabilityGroupItem) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, 1), 0), LEN(@AvailabilityGroups) + 1) AS EndPosition,
SUBSTRING(@AvailabilityGroups, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, 1), 0), LEN(@AvailabilityGroups) + 1) - 1) AS AvailabilityGroupItem
WHERE @AvailabilityGroups IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, EndPosition + 1), 0), LEN(@AvailabilityGroups) + 1) AS EndPosition,
SUBSTRING(@AvailabilityGroups, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, EndPosition + 1), 0), LEN(@AvailabilityGroups) + 1) - EndPosition - 1) AS AvailabilityGroupItem
FROM AvailabilityGroups1
WHERE EndPosition < LEN(@AvailabilityGroups) + 1
),
AvailabilityGroups2 (AvailabilityGroupItem, StartPosition, Selected) AS
(
SELECT CASE WHEN AvailabilityGroupItem LIKE '-%' THEN RIGHT(AvailabilityGroupItem,LEN(AvailabilityGroupItem) - 1) ELSE AvailabilityGroupItem END AS AvailabilityGroupItem,
StartPosition,
CASE WHEN AvailabilityGroupItem LIKE '-%' THEN 0 ELSE 1 END AS Selected
FROM AvailabilityGroups1
),
AvailabilityGroups3 (AvailabilityGroupItem, StartPosition, Selected) AS
(
SELECT CASE WHEN AvailabilityGroupItem = 'ALL_AVAILABILITY_GROUPS' THEN '%' ELSE AvailabilityGroupItem END AS AvailabilityGroupItem,
StartPosition,
Selected
FROM AvailabilityGroups2
),
AvailabilityGroups4 (AvailabilityGroupName, StartPosition, Selected) AS
(
SELECT CASE WHEN LEFT(AvailabilityGroupItem,1) = '[' AND RIGHT(AvailabilityGroupItem,1) = ']' THEN PARSENAME(AvailabilityGroupItem,1) ELSE AvailabilityGroupItem END AS AvailabilityGroupItem,
StartPosition,
Selected
FROM AvailabilityGroups3
)
INSERT INTO @SelectedAvailabilityGroups (AvailabilityGroupName, StartPosition, Selected)
SELECT AvailabilityGroupName, StartPosition, Selected
FROM AvailabilityGroups4
OPTION (MAXRECURSION 0);
UPDATE tmpAvailabilityGroups
SET tmpAvailabilityGroups.Selected = SelectedAvailabilityGroups.Selected
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN @SelectedAvailabilityGroups SelectedAvailabilityGroups
ON tmpAvailabilityGroups.AvailabilityGroupName LIKE REPLACE(SelectedAvailabilityGroups.AvailabilityGroupName,'_','[_]')
WHERE SelectedAvailabilityGroups.Selected = 1;
UPDATE tmpAvailabilityGroups
SET tmpAvailabilityGroups.Selected = SelectedAvailabilityGroups.Selected
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN @SelectedAvailabilityGroups SelectedAvailabilityGroups
ON tmpAvailabilityGroups.AvailabilityGroupName LIKE REPLACE(SelectedAvailabilityGroups.AvailabilityGroupName,'_','[_]')
WHERE SelectedAvailabilityGroups.Selected = 0;
UPDATE tmpAvailabilityGroups
SET tmpAvailabilityGroups.StartPosition = SelectedAvailabilityGroups2.StartPosition
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN (SELECT tmpAvailabilityGroups.AvailabilityGroupName, MIN(SelectedAvailabilityGroups.StartPosition) AS StartPosition
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN @SelectedAvailabilityGroups SelectedAvailabilityGroups
ON tmpAvailabilityGroups.AvailabilityGroupName LIKE REPLACE(SelectedAvailabilityGroups.AvailabilityGroupName,'_','[_]')
WHERE SelectedAvailabilityGroups.Selected = 1
GROUP BY tmpAvailabilityGroups.AvailabilityGroupName) SelectedAvailabilityGroups2
ON tmpAvailabilityGroups.AvailabilityGroupName = SelectedAvailabilityGroups2.AvailabilityGroupName;
UPDATE tmpDatabases
SET tmpDatabases.StartPosition = tmpAvailabilityGroups.StartPosition,
tmpDatabases.Selected = 1
FROM @tmpDatabases tmpDatabases
INNER JOIN @tmpDatabasesAvailabilityGroups tmpDatabasesAvailabilityGroups ON tmpDatabases.DatabaseName = tmpDatabasesAvailabilityGroups.DatabaseName
INNER JOIN @tmpAvailabilityGroups tmpAvailabilityGroups ON tmpDatabasesAvailabilityGroups.AvailabilityGroupName = tmpAvailabilityGroups.AvailabilityGroupName
WHERE tmpAvailabilityGroups.Selected = 1;
END;
IF @AvailabilityGroups IS NOT NULL AND (NOT EXISTS(SELECT * FROM @SelectedAvailabilityGroups) OR EXISTS(SELECT * FROM @SelectedAvailabilityGroups WHERE AvailabilityGroupName IS NULL OR AvailabilityGroupName = '') OR @Version < 11 OR SERVERPROPERTY('IsHadrEnabled') = 0)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroups is not supported.', 16, 1;
END;
IF (@Databases IS NULL AND @AvailabilityGroups IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'You need to specify one of the parameters @Databases and @AvailabilityGroups.', 16, 2;
END;
IF (@Databases IS NOT NULL AND @AvailabilityGroups IS NOT NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'You can only specify one of the parameters @Databases and @AvailabilityGroups.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
--// Check database names //--
----------------------------------------------------------------------------------------------------
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @tmpDatabases
WHERE Selected = 1
AND DATALENGTH(DatabaseNameFS) = 0
ORDER BY DatabaseName ASC;
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The names of the following databases are not supported: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 16, 1;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @tmpDatabases
WHERE UPPER(DatabaseNameFS) IN(SELECT UPPER(DatabaseNameFS) FROM @tmpDatabases GROUP BY UPPER(DatabaseNameFS) HAVING COUNT(*) > 1 AND MAX(CAST(Selected AS INT)) = 1)
AND DATALENGTH(DatabaseNameFS) > 0
ORDER BY DatabaseName ASC
OPTION (RECOMPILE);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The names of the following databases are not unique in the file system: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Select default directory //--
----------------------------------------------------------------------------------------------------
IF @Directory IS NULL AND @URL IS NULL AND (@BackupSoftware <> 'DATA_DOMAIN_BOOST' OR @BackupSoftware IS NULL)
BEGIN
IF @Version >= 15
BEGIN
SET @DefaultDirectory = CAST(SERVERPROPERTY('InstanceDefaultBackupPath') AS NVARCHAR(MAX));
END;
ELSE
BEGIN
EXECUTE [master].[dbo].xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\MSSQLServer', N'BackupDirectory', @DefaultDirectory OUTPUT;
END;
IF @DefaultDirectory LIKE 'http://%' OR @DefaultDirectory LIKE 'https://%'
BEGIN
SET @URL = @DefaultDirectory;
END;
ELSE
BEGIN
INSERT INTO @Directories ([Id], DirectoryPath, [mirror], Completed)
SELECT 1, @DefaultDirectory, 0, 0;
END;
END;
----------------------------------------------------------------------------------------------------
--// Select directories //--
----------------------------------------------------------------------------------------------------
SET @Directory = REPLACE(@Directory, CHAR(10), '');
SET @Directory = REPLACE(@Directory, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @Directory) > 0 SET @Directory = REPLACE(@Directory, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @Directory) > 0 SET @Directory = REPLACE(@Directory, ' ' + @StringDelimiter, @StringDelimiter);
SET @Directory = LTRIM(RTRIM(@Directory));
WITH Directories (StartPosition, EndPosition, Directory) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Directory, 1), 0), LEN(@Directory) + 1) AS EndPosition,
SUBSTRING(@Directory, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Directory, 1), 0), LEN(@Directory) + 1) - 1) AS Directory
WHERE @Directory IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Directory, EndPosition + 1), 0), LEN(@Directory) + 1) AS EndPosition,
SUBSTRING(@Directory, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Directory, EndPosition + 1), 0), LEN(@Directory) + 1) - EndPosition - 1) AS Directory
FROM Directories
WHERE EndPosition < LEN(@Directory) + 1
)
INSERT INTO @Directories ([Id], DirectoryPath, [mirror], Completed)
SELECT ROW_NUMBER() OVER(ORDER BY StartPosition ASC) AS [Id],
Directory,
0,
0
FROM Directories
OPTION (MAXRECURSION 0);
SET @MirrorDirectory = REPLACE(@MirrorDirectory, CHAR(10), '');
SET @MirrorDirectory = REPLACE(@MirrorDirectory, CHAR(13), '');
WHILE CHARINDEX(', ',@MirrorDirectory) > 0 SET @MirrorDirectory = REPLACE(@MirrorDirectory,', ',',');
WHILE CHARINDEX(' ,',@MirrorDirectory) > 0 SET @MirrorDirectory = REPLACE(@MirrorDirectory,' ,',',');
SET @MirrorDirectory = LTRIM(RTRIM(@MirrorDirectory));
WITH Directories (StartPosition, EndPosition, Directory) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @MirrorDirectory, 1), 0), LEN(@MirrorDirectory) + 1) AS EndPosition,
SUBSTRING(@MirrorDirectory, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @MirrorDirectory, 1), 0), LEN(@MirrorDirectory) + 1) - 1) AS Directory
WHERE @MirrorDirectory IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @MirrorDirectory, EndPosition + 1), 0), LEN(@MirrorDirectory) + 1) AS EndPosition,
SUBSTRING(@MirrorDirectory, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @MirrorDirectory, EndPosition + 1), 0), LEN(@MirrorDirectory) + 1) - EndPosition - 1) AS Directory
FROM Directories
WHERE EndPosition < LEN(@MirrorDirectory) + 1
)
INSERT INTO @Directories ([Id], DirectoryPath, [mirror], Completed)
SELECT (SELECT COUNT(*) FROM @Directories) + ROW_NUMBER() OVER(ORDER BY StartPosition ASC) AS [Id],
Directory,
1,
0
FROM Directories
OPTION (MAXRECURSION 0);
----------------------------------------------------------------------------------------------------
--// Check directories //--
----------------------------------------------------------------------------------------------------
IF EXISTS (SELECT * FROM @Directories WHERE [mirror] = 0 AND (NOT (DirectoryPath LIKE '_:' OR DirectoryPath LIKE '_:\%' OR DirectoryPath LIKE '\\%\%' OR (DirectoryPath LIKE '/%' AND @HostPlatform = 'Linux') OR DirectoryPath = 'NUL') OR DirectoryPath IS NULL OR LEFT(DirectoryPath,1) = ' ' OR RIGHT(DirectoryPath,1) = ' '))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Directory is not supported.', 16, 1;
END;
IF EXISTS (SELECT * FROM @Directories GROUP BY DirectoryPath HAVING COUNT(*) <> 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Directory is not supported.', 16, 2;
END;
IF (SELECT COUNT(*) FROM @Directories WHERE [mirror] = 0) <> (SELECT COUNT(*) FROM @Directories WHERE [mirror] = 1) AND (SELECT COUNT(*) FROM @Directories WHERE [mirror] = 1) > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The number of directories for the parameters @Directory and @MirrorDirectory has to be the same.', 16, 3;
END;
IF (@Directory IS NOT NULL AND SERVERPROPERTY('EngineEdition') = 8) OR (@Directory IS NOT NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Directory is not supported.', 16, 4;
END;
IF EXISTS (SELECT * FROM @Directories WHERE [mirror] = 0 AND DirectoryPath = 'NUL') AND EXISTS(SELECT * FROM @Directories WHERE [mirror] = 0 AND DirectoryPath <> 'NUL')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Directory is not supported.', 16, 5;
END;
IF EXISTS (SELECT * FROM @Directories WHERE [mirror] = 0 AND DirectoryPath = 'NUL') AND EXISTS(SELECT * FROM @Directories WHERE [mirror] = 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'Mirrored backup is not supported when backing up to NUL', 16, 6;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS(SELECT * FROM @Directories WHERE [mirror] = 1 AND (NOT (DirectoryPath LIKE '_:' OR DirectoryPath LIKE '_:\%' OR DirectoryPath LIKE '\\%\%' OR (DirectoryPath LIKE '/%' AND @HostPlatform = 'Linux')) OR DirectoryPath IS NULL OR LEFT(DirectoryPath,1) = ' ' OR RIGHT(DirectoryPath,1) = ' '))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorDirectory is not supported.', 16, 1;
END;
IF EXISTS (SELECT * FROM @Directories GROUP BY DirectoryPath HAVING COUNT(*) <> 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorDirectory is not supported.', 16, 2;
END;
IF @BackupSoftware IN('SQLBACKUP','SQLSAFE') AND (SELECT COUNT(*) FROM @Directories WHERE [mirror] = 1) > 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorDirectory is not supported.', 16, 4;
END;
IF @MirrorDirectory IS NOT NULL AND SERVERPROPERTY('EngineEdition') = 8
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorDirectory is not supported.', 16, 5;
END;
IF @MirrorDirectory IS NOT NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorDirectory is not supported.', 16, 6;
END;
IF (@BackupSoftware IS NULL AND EXISTS(SELECT * FROM @Directories WHERE [mirror] = 1) AND SERVERPROPERTY('EngineEdition') <> 3)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorDirectory is not supported. Mirrored backup to disk is only available in Enterprise and Developer Edition.', 16, 8;
END;
----------------------------------------------------------------------------------------------------
IF NOT EXISTS (SELECT * FROM @Errors WHERE [severity] >= 16) AND @DirectoryCheck = 'Y'
BEGIN
WHILE (1 = 1)
BEGIN
SELECT TOP 1 @CurrentRootDirectoryID = [Id],
@CurrentRootDirectoryPath = DirectoryPath
FROM @Directories
WHERE Completed = 0
AND DirectoryPath <> 'NUL'
ORDER BY [Id] ASC;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
IF @Version >= 14
BEGIN
INSERT INTO @DirectoryInfo (FileExists, FileIsADirectory, ParentDirectoryExists)
SELECT file_exists,
file_is_a_directory,
parent_directory_exists
FROM [sys].dm_os_file_exists (@CurrentRootDirectoryPath);
END;
ELSE
BEGIN
INSERT INTO @DirectoryInfo (FileExists, FileIsADirectory, ParentDirectoryExists)
EXECUTE [master].[dbo].xp_fileexist @CurrentRootDirectoryPath;
END;
IF NOT EXISTS (SELECT * FROM @DirectoryInfo WHERE FileExists = 0 AND FileIsADirectory = 1 AND ParentDirectoryExists = 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The directory ' + @CurrentRootDirectoryPath + ' does not exist.', 16, 1;
END;
UPDATE @Directories
SET Completed = 1
WHERE [Id] = @CurrentRootDirectoryID;
SET @CurrentRootDirectoryID = NULL;
SET @CurrentRootDirectoryPath = NULL;
DELETE FROM @DirectoryInfo;
END;
END;
----------------------------------------------------------------------------------------------------
--// Select URLs //--
----------------------------------------------------------------------------------------------------
SET @URL = REPLACE(@URL, CHAR(10), '');
SET @URL = REPLACE(@URL, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @URL) > 0 SET @URL = REPLACE(@URL, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @URL) > 0 SET @URL = REPLACE(@URL, ' ' + @StringDelimiter, @StringDelimiter);
SET @URL = LTRIM(RTRIM(@URL));
WITH URLs (StartPosition, EndPosition, [URL]) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @URL, 1), 0), LEN(@URL) + 1) AS EndPosition,
SUBSTRING(@URL, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @URL, 1), 0), LEN(@URL) + 1) - 1) AS [URL]
WHERE @URL IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @URL, EndPosition + 1), 0), LEN(@URL) + 1) AS EndPosition,
SUBSTRING(@URL, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @URL, EndPosition + 1), 0), LEN(@URL) + 1) - EndPosition - 1) AS [URL]
FROM URLs
WHERE EndPosition < LEN(@URL) + 1
)
INSERT INTO @URLs ([Id], DirectoryPath, [mirror])
SELECT ROW_NUMBER() OVER(ORDER BY StartPosition ASC) AS [Id],
[URL],
0
FROM URLs
OPTION (MAXRECURSION 0);
SET @MirrorURL = REPLACE(@MirrorURL, CHAR(10), '');
SET @MirrorURL = REPLACE(@MirrorURL, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @MirrorURL) > 0 SET @MirrorURL = REPLACE(@MirrorURL, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter ,@MirrorURL) > 0 SET @MirrorURL = REPLACE(@MirrorURL, ' ' + @StringDelimiter, @StringDelimiter);
SET @MirrorURL = LTRIM(RTRIM(@MirrorURL));
WITH URLs (StartPosition, EndPosition, [URL]) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @MirrorURL, 1), 0), LEN(@MirrorURL) + 1) AS EndPosition,
SUBSTRING(@MirrorURL, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @MirrorURL, 1), 0), LEN(@MirrorURL) + 1) - 1) AS [URL]
WHERE @MirrorURL IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @MirrorURL, EndPosition + 1), 0), LEN(@MirrorURL) + 1) AS EndPosition,
SUBSTRING(@MirrorURL, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @MirrorURL, EndPosition + 1), 0), LEN(@MirrorURL) + 1) - EndPosition - 1) AS [URL]
FROM URLs
WHERE EndPosition < LEN(@MirrorURL) + 1
)
INSERT INTO @URLs ([Id], DirectoryPath, [mirror])
SELECT (SELECT COUNT(*) FROM @URLs) + ROW_NUMBER() OVER(ORDER BY StartPosition ASC) AS [Id],
[URL],
1
FROM URLs
OPTION (MAXRECURSION 0);
----------------------------------------------------------------------------------------------------
--// Check URLs //--
----------------------------------------------------------------------------------------------------
IF EXISTS(SELECT * FROM @URLs WHERE [mirror] = 0 AND NOT (DirectoryPath LIKE 'https://%/%' OR DirectoryPath LIKE 's3://%/%'))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @URL is not supported.', 16, 1;
END;
IF EXISTS (SELECT * FROM @URLs GROUP BY DirectoryPath HAVING COUNT(*) <> 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @URL is not supported.', 16, 2;
END;
IF (SELECT COUNT(*) FROM @URLs WHERE [mirror] = 0) <> (SELECT COUNT(*) FROM @URLs WHERE [mirror] = 1) AND (SELECT COUNT(*) FROM @URLs WHERE [mirror] = 1) > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @URL is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS(SELECT * FROM @URLs WHERE [mirror] = 1 AND NOT (DirectoryPath LIKE 'https://%/%' OR DirectoryPath LIKE 's3://%/%'))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorURL is not supported.', 16, 1;
END;
IF EXISTS (SELECT * FROM @URLs GROUP BY DirectoryPath HAVING COUNT(*) <> 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorURL is not supported.', 16, 2;
END;
IF (SELECT COUNT(*) FROM @URLs WHERE [mirror] = 0) <> (SELECT COUNT(*) FROM @URLs WHERE [mirror] = 1) AND (SELECT COUNT(*) FROM @URLs WHERE [mirror] = 1) > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorURL is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
--// Get directory separator //--
----------------------------------------------------------------------------------------------------
SELECT @DirectorySeparator = CASE
WHEN @URL IS NOT NULL THEN '/'
WHEN @HostPlatform = 'Windows' THEN '\'
WHEN @HostPlatform = 'Linux' THEN '/'
END;
UPDATE @Directories
SET DirectoryPath = LEFT(DirectoryPath,LEN(DirectoryPath) - 1)
WHERE RIGHT(DirectoryPath,1) = @DirectorySeparator;
UPDATE @URLs
SET DirectoryPath = LEFT(DirectoryPath,LEN(DirectoryPath) - 1)
WHERE RIGHT(DirectoryPath,1) = @DirectorySeparator;
----------------------------------------------------------------------------------------------------
--// Get file extension //--
----------------------------------------------------------------------------------------------------
IF @FileExtensionFull IS NULL
BEGIN
SELECT @FileExtensionFull = CASE
WHEN @BackupSoftware IS NULL THEN 'bak'
WHEN @BackupSoftware = 'LITESPEED' THEN 'bak'
WHEN @BackupSoftware = 'SQLBACKUP' THEN 'sqb'
WHEN @BackupSoftware = 'SQLSAFE' THEN 'safe'
END;
END;
IF @FileExtensionDiff IS NULL
BEGIN
SELECT @FileExtensionDiff = CASE
WHEN @BackupSoftware IS NULL THEN 'bak'
WHEN @BackupSoftware = 'LITESPEED' THEN 'bak'
WHEN @BackupSoftware = 'SQLBACKUP' THEN 'sqb'
WHEN @BackupSoftware = 'SQLSAFE' THEN 'safe'
END;
END;
IF @FileExtensionLog IS NULL
BEGIN
SELECT @FileExtensionLog = CASE
WHEN @BackupSoftware IS NULL THEN 'trn'
WHEN @BackupSoftware = 'LITESPEED' THEN 'trn'
WHEN @BackupSoftware = 'SQLBACKUP' THEN 'sqb'
WHEN @BackupSoftware = 'SQLSAFE' THEN 'safe'
END;
END;
----------------------------------------------------------------------------------------------------
--// Get default checksum //--
----------------------------------------------------------------------------------------------------
IF @Checksum IS NULL
BEGIN
SELECT @Checksum = CASE WHEN EXISTS(SELECT * FROM [sys].[configurations] WHERE [name] = 'backup checksum default' AND [value_in_use] = 1) THEN 'Y'
WHEN NOT EXISTS(SELECT * FROM [sys].[configurations] WHERE [name] = 'backup checksum default' AND [value_in_use] = 1) THEN 'N' END;
END;
----------------------------------------------------------------------------------------------------
--// Get default compression //--
----------------------------------------------------------------------------------------------------
IF @Compress IS NULL
BEGIN
SELECT @Compress = CASE WHEN @BackupSoftware IS NULL AND EXISTS(SELECT * FROM [sys].[configurations] WHERE [name] = 'backup compression default' AND [value_in_use] = 1) THEN 'Y'
WHEN @BackupSoftware IS NULL AND NOT EXISTS(SELECT * FROM [sys].[configurations] WHERE [name] = 'backup compression default' AND [value_in_use] = 1) THEN 'N'
WHEN @BackupSoftware IS NOT NULL AND (@CompressionLevelNumeric IS NULL OR @CompressionLevelNumeric > 0) THEN 'Y'
WHEN @BackupSoftware IS NOT NULL AND @CompressionLevelNumeric = 0 THEN 'N' END;
END;
----------------------------------------------------------------------------------------------------
--// Get default compression algorithm //--
----------------------------------------------------------------------------------------------------
IF @CompressionAlgorithm IS NULL AND @BackupSoftware IS NULL AND @Version >= 16
BEGIN
SELECT @CompressionAlgorithm = CASE WHEN @BackupSoftware IS NULL AND EXISTS(SELECT * FROM [sys].[configurations] WHERE [name] = 'backup compression algorithm' AND [value_in_use] IN (0, 1)) THEN 'MS_XPRESS'
WHEN @BackupSoftware IS NULL AND EXISTS(SELECT * FROM [sys].[configurations] WHERE [name] = 'backup compression algorithm' AND [value_in_use] = 2) THEN 'QAT_DEFLATE'
WHEN @BackupSoftware IS NULL AND EXISTS(SELECT * FROM [sys].[configurations] WHERE [name] = 'backup compression algorithm' AND [value_in_use] = 3) THEN 'ZSTD' END;
END;
----------------------------------------------------------------------------------------------------
--// Get default compression level //--
----------------------------------------------------------------------------------------------------
IF @CompressionLevel IS NULL AND @BackupSoftware IS NULL AND @Version >= 17
BEGIN
SET @CompressionLevel = 'LOW';
END;
----------------------------------------------------------------------------------------------------
--// Check input parameters //--
----------------------------------------------------------------------------------------------------
IF @BackupType NOT IN ('FULL','DIFF','LOG') OR @BackupType IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BackupType is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF SERVERPROPERTY('EngineEdition') = 8 AND NOT (@BackupType = 'FULL' AND @CopyOnly = 'Y')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'SQL Database Managed Instance only supports COPY_ONLY full backups.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Verify NOT IN ('Y','N') OR @Verify IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Verify is not supported.', 16, 1;
END;
IF @BackupSoftware = 'SQLSAFE' AND @Encrypt = 'Y' AND @Verify = 'Y'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Verify is not supported. Verify is not supported with encrypted backups with Idera SQL Safe Backup', 16, 2;
END;
IF @Verify = 'Y' AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Verify is not supported. Verify is not supported with Data Domain Boost', 16, 3;
END;
IF @Verify = 'Y' AND EXISTS(SELECT * FROM @Directories WHERE DirectoryPath = 'NUL')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Verify is not supported. Verify is not supported when backing up to NUL.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF @CleanupTime < 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CleanupTime is not supported.', 16, 1;
END;
IF @CleanupTime IS NOT NULL AND @URL IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CleanupTime is not supported. Cleanup is not supported on Azure Blob Storage.', 16, 2;
END;
IF @CleanupTime IS NOT NULL AND EXISTS(SELECT * FROM @Directories WHERE DirectoryPath = 'NUL')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CleanupTime is not supported. Cleanup is not supported when backing up to NUL.', 16, 4;
END;
IF @CleanupTime IS NOT NULL AND ((@DirectoryStructure NOT LIKE '%{DatabaseName}%' OR @DirectoryStructure IS NULL) OR (SERVERPROPERTY('IsHadrEnabled') = 1 AND (@AvailabilityGroupDirectoryStructure NOT LIKE '%{DatabaseName}%' OR @AvailabilityGroupDirectoryStructure IS NULL)))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CleanupTime is not supported. Cleanup is not supported if the token {DatabaseName} is not part of the directory.', 16, 5;
END;
IF @CleanupTime IS NOT NULL AND ((@DirectoryStructure NOT LIKE '%{BackupType}%' OR @DirectoryStructure IS NULL) OR (SERVERPROPERTY('IsHadrEnabled') = 1 AND (@AvailabilityGroupDirectoryStructure NOT LIKE '%{BackupType}%' OR @AvailabilityGroupDirectoryStructure IS NULL))) AND (SELECT COUNT(*) FROM (SELECT @FileExtensionFull AS FileExtension UNION SELECT @FileExtensionDiff UNION SELECT @FileExtensionLog) FileExtension) <> 3
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CleanupTime is not supported. Cleanup is not supported if the token {BackupType} is not part of the directory and the file extensions are not unique.', 16, 6;
END;
IF @CleanupTime IS NOT NULL AND @CopyOnly = 'Y' AND ((@DirectoryStructure NOT LIKE '%{CopyOnly}%' OR @DirectoryStructure IS NULL) OR (SERVERPROPERTY('IsHadrEnabled') = 1 AND (@AvailabilityGroupDirectoryStructure NOT LIKE '%{CopyOnly}%' OR @AvailabilityGroupDirectoryStructure IS NULL)))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CleanupTime is not supported. Cleanup is not supported if the token {CopyOnly} is not part of the directory.', 16, 7;
END;
----------------------------------------------------------------------------------------------------
IF @CleanupMode NOT IN('BEFORE_BACKUP','AFTER_BACKUP') OR @CleanupMode IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CleanupMode is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Compress NOT IN ('Y','N') OR @Compress IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Compress is not supported.', 16, 1;
END;
IF @Compress = 'Y' AND @BackupSoftware IS NULL AND NOT ((@Version >= 10 AND @Version < 10.5 AND SERVERPROPERTY('EngineEdition') = 3) OR (@Version >= 10.5 AND (SERVERPROPERTY('EngineEdition') IN (3, 8) OR SERVERPROPERTY('EditionID') IN (-1534726760, 284895786))))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Compress is not supported. Backup compression is not supported in this version and edition of SQL Server.', 16, 2;
END;
IF @Compress = 'N' AND @BackupSoftware IN ('LITESPEED','SQLBACKUP','SQLSAFE') AND (@CompressionLevelNumeric IS NULL OR @CompressionLevelNumeric >= 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Compress is not supported.', 16, 3;
END;
IF @Compress = 'Y' AND @BackupSoftware IN ('LITESPEED','SQLBACKUP','SQLSAFE') AND @CompressionLevelNumeric = 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Compress is not supported.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF @CompressionAlgorithm NOT IN ('MS_XPRESS','QAT_DEFLATE','ZSTD')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionAlgorithm is not supported. The allowed values are MS_XPRESS, QAT_DEFLATE and ZSTD.', 16, 1;
END;
IF @CompressionAlgorithm IS NOT NULL AND NOT (@Version >= 16)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionAlgorithm is not supported. Specifying the compression algorithm is only supported in SQL Server 2022 and later.', 16, 2;
END;
IF @CompressionAlgorithm = 'QAT_DEFLATE' AND NOT (SERVERPROPERTY('EngineEdition') IN(2, 3))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionAlgorithm is not supported. Setting the compression algorithm to QAT_DEFLATE is only supported in Standard and Enterprise Edition.', 16, 3;
END;
IF @CompressionAlgorithm = 'ZSTD' AND NOT (@Version >= 17)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionAlgorithm is not supported. Setting the compression algorithm to ZSTD is only supported in SQL Server 2025 and later.', 16, 4;
END;
IF @CompressionAlgorithm IS NOT NULL AND @BackupSoftware IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionAlgorithm is not supported. Setting the compression algorithm is only supported with SQL Server native backup', 16, 5;
END;
----------------------------------------------------------------------------------------------------
IF @CompressionLevel IS NOT NULL AND @BackupSoftware IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionLevel is not supported. For third-party backup software, use the parameter @CompressionLevelNumeric.', 16, 1;
END;
IF @CompressionLevel NOT IN ('LOW','MEDIUM','HIGH')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionLevel is not supported. The supported values are LOW, MEDIUM and HIGH.', 16, 2;
END;
IF @CompressionLevel IS NOT NULL AND NOT (@Version >= 17)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionLevel is not supported. Setting the compression level is only supported in SQL Server 2025 and later.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF @CopyOnly NOT IN ('Y','N') OR @CopyOnly IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CopyOnly is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @ChangeBackupType NOT IN ('Y','N') OR @ChangeBackupType IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ChangeBackupType is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @BackupSoftware NOT IN ('LITESPEED','SQLBACKUP','SQLSAFE','DATA_DOMAIN_BOOST')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BackupSoftware is not supported.', 16, 1;
END;
IF @BackupSoftware IS NOT NULL AND @HostPlatform = 'Linux'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BackupSoftware is not supported. Only native backups are supported on Linux', 16, 2;
END;
IF @BackupSoftware = 'LITESPEED' AND NOT EXISTS (SELECT * FROM [master].[sys].[objects] WHERE [type] = 'X' AND [name] = 'xp_backup_database')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'LiteSpeed for SQL Server is not installed. Download https://www.quest.com/products/litespeed-for-sql-server/.', 16, 3;
END;
IF @BackupSoftware = 'SQLBACKUP' AND NOT EXISTS (SELECT * FROM [master].[sys].[objects] WHERE [type] = 'X' AND [name] = 'sqlbackup')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'Red Gate SQL Backup Pro is not installed. Download https://www.red-gate.com/products/dba/sql-backup/.', 16, 4;
END;
IF @BackupSoftware = 'SQLSAFE' AND NOT EXISTS (SELECT * FROM [master].[sys].[objects] WHERE [type] = 'X' AND [name] = 'xp_ss_backup')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'Idera SQL Safe Backup is not installed. Download https://www.idera.com/productssolutions/sqlserver/sqlsafebackup.', 16, 5;
END;
IF @BackupSoftware = 'DATA_DOMAIN_BOOST' AND NOT EXISTS (SELECT * FROM [master].[sys].[objects] WHERE [type] = 'PC' AND [name] = 'emc_run_backup')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'EMC Data Domain Boost is not installed. Download https://www.emc.com/en-us/data-protection/data-domain.htm.', 16, 6;
END;
----------------------------------------------------------------------------------------------------
IF @Checksum NOT IN ('Y','N') OR @Checksum IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Checksum is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @BlockSize NOT IN (512,1024,2048,4096,8192,16384,32768,65536)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BlockSize is not supported.', 16, 1;
END;
IF @BlockSize IS NOT NULL AND @BackupSoftware = 'SQLBACKUP'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BlockSize is not supported. This parameter is not supported with Redgate SQL Backup Pro', 16, 2;
END;
IF @BlockSize IS NOT NULL AND @BackupSoftware = 'SQLSAFE'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BlockSize is not supported. This parameter is not supported with Idera SQL Safe', 16, 3;
END;
IF @BlockSize IS NOT NULL AND @URL IS NOT NULL AND @Credential IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'BLOCKSIZE is not supported when backing up to URL with page blobs. See https://docs.microsoft.com/en-us/sql/relational-databases/backup-restore/sql-server-backup-to-url', 16, 4;
END;
IF @BlockSize IS NOT NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BlockSize is not supported. This parameter is not supported with Data Domain Boost', 16, 5;
END;
----------------------------------------------------------------------------------------------------
IF @BufferCount <= 0 OR @BufferCount > 2147483647
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BufferCount is not supported.', 16, 1;
END;
IF @BufferCount IS NOT NULL AND @BackupSoftware = 'SQLBACKUP'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BufferCount is not supported.', 16, 2;
END;
IF @BufferCount IS NOT NULL AND @BackupSoftware = 'SQLSAFE'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BufferCount is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF @MaxTransferSize < 65536 OR @MaxTransferSize > 20971520
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxTransferSize is not supported.', 16, 1;
END;
IF @MaxTransferSize > 1048576 AND @BackupSoftware = 'SQLBACKUP'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxTransferSize is not supported.', 16, 2;
END;
IF @MaxTransferSize IS NOT NULL AND @BackupSoftware = 'SQLSAFE'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxTransferSize is not supported.', 16, 3;
END;
IF @MaxTransferSize IS NOT NULL AND @URL IS NOT NULL AND @Credential IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'MAXTRANSFERSIZE is not supported when backing up to URL with page blobs. See https://docs.microsoft.com/en-us/sql/relational-databases/backup-restore/sql-server-backup-to-url', 16, 4;
END;
IF @MaxTransferSize IS NOT NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxTransferSize is not supported.', 16, 5;
END;
----------------------------------------------------------------------------------------------------
IF @NumberOfFiles < 1 OR @NumberOfFiles > 64
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NumberOfFiles is not supported.', 16, 1;
END;
IF @NumberOfFiles > 32 AND @BackupSoftware = 'SQLBACKUP'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NumberOfFiles is not supported.', 16, 2;
END;
IF @NumberOfFiles < (SELECT COUNT(*) FROM @Directories WHERE [mirror] = 0)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NumberOfFiles is not supported.', 16, 3;
END;
IF @NumberOfFiles % (SELECT NULLIF(COUNT(*),0) FROM @Directories WHERE [mirror] = 0) > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NumberOfFiles is not supported.', 16, 4;
END;
IF @URL IS NOT NULL AND @Credential IS NOT NULL AND @NumberOfFiles <> 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'Backup striping to URL with page blobs is not supported. See https://docs.microsoft.com/en-us/sql/relational-databases/backup-restore/sql-server-backup-to-url', 16, 5;
END;
IF @NumberOfFiles > 1 AND @BackupSoftware IN('SQLBACKUP','SQLSAFE') AND EXISTS(SELECT * FROM @Directories WHERE [mirror] = 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NumberOfFiles is not supported.', 16, 6;
END;
IF @NumberOfFiles > 32 AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NumberOfFiles is not supported.', 16, 7;
END;
IF @NumberOfFiles < (SELECT COUNT(*) FROM @URLs WHERE [mirror] = 0)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NumberOfFiles is not supported.', 16, 8;
END;
IF @NumberOfFiles % (SELECT NULLIF(COUNT(*),0) FROM @URLs WHERE [mirror] = 0) > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NumberOfFiles is not supported.', 16, 9;
END;
IF @NumberOfFiles > 32 AND @URL LIKE 's3%' AND @MirrorURL LIKE 's3%'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NumberOfFiles is not supported. The maximum number of files when performing mirrored backups to S3 storage is 32.', 16, 10;
END;
----------------------------------------------------------------------------------------------------
IF @MinBackupSizeForMultipleFiles <= 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MinBackupSizeForMultipleFiles is not supported.', 16, 1;
END;
IF @MinBackupSizeForMultipleFiles IS NOT NULL AND @NumberOfFiles IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MinBackupSizeForMultipleFiles is not supported. This parameter can only be used together with @NumberOfFiles.', 16, 2;
END;
IF @MinBackupSizeForMultipleFiles IS NOT NULL AND @BackupType = 'DIFF' AND NOT EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_file_space_usage') AND [name] = 'modified_extent_page_count')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MinBackupSizeForMultipleFiles is not supported. The column sys.dm_db_file_space_usage.modified_extent_page_count is not available in this version of SQL Server.', 16, 3;
END;
IF @MinBackupSizeForMultipleFiles IS NOT NULL AND @BackupType = 'LOG' AND NOT EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_log_stats') AND [name] = 'log_since_last_log_backup_mb')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MinBackupSizeForMultipleFiles is not supported. The column sys.dm_db_log_stats.log_since_last_log_backup_mb is not available in this version of SQL Server.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF @MaxFileSize <= 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxFileSize is not supported.', 16, 1;
END;
IF @MaxFileSize IS NOT NULL AND @NumberOfFiles IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameters @MaxFileSize and @NumberOfFiles cannot be used together.', 16, 2;
END;
IF @MaxFileSize IS NOT NULL AND @BackupType = 'DIFF' AND NOT EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_file_space_usage') AND [name] = 'modified_extent_page_count')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxFileSize is not supported. The column sys.dm_db_file_space_usage.modified_extent_page_count is not available in this version of SQL Server.', 16, 3;
END;
IF @MaxFileSize IS NOT NULL AND @BackupType = 'LOG' AND NOT EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_log_stats') AND [name] = 'log_since_last_log_backup_mb')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxFileSize is not supported. The column sys.dm_db_log_stats.log_since_last_log_backup_mb is not available in this version of SQL Server.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF (@BackupSoftware IS NULL AND @CompressionLevelNumeric IS NOT NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionLevelNumeric is not supported.', 16, 1;
END;
IF @BackupSoftware = 'LITESPEED' AND (@CompressionLevelNumeric < 0 OR @CompressionLevelNumeric > 8)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionLevelNumeric is not supported.', 16, 2;
END;
IF @BackupSoftware = 'SQLBACKUP' AND (@CompressionLevelNumeric < 0 OR @CompressionLevelNumeric > 4)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionLevelNumeric is not supported.', 16, 3;
END;
IF @BackupSoftware = 'SQLSAFE' AND (@CompressionLevelNumeric < 1 OR @CompressionLevelNumeric > 4)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionLevelNumeric is not supported.', 16, 4;
END;
IF @CompressionLevelNumeric IS NOT NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CompressionLevelNumeric is not supported.', 16, 5;
END;
----------------------------------------------------------------------------------------------------
IF LEN(@Description) > 255
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Description is not supported.', 16, 1;
END;
IF @BackupSoftware = 'LITESPEED' AND LEN(@Description) > 128
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Description is not supported.', 16, 2;
END;
IF @BackupSoftware = 'DATA_DOMAIN_BOOST' AND LEN(@Description) > 254
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Description is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF LEN(@BackupSetName) > 128
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BackupSetName is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Threads IS NOT NULL AND (@BackupSoftware NOT IN('LITESPEED','SQLBACKUP','SQLSAFE') OR @BackupSoftware IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Threads is not supported.', 16, 1;
END;
IF @BackupSoftware = 'LITESPEED' AND (@Threads < 1 OR @Threads > 32)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Threads is not supported.', 16, 2;
END;
IF @BackupSoftware = 'SQLBACKUP' AND (@Threads < 2 OR @Threads > 32)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Threads is not supported.', 16, 3;
END;
IF @BackupSoftware = 'SQLSAFE' AND (@Threads < 1 OR @Threads > 64)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Threads is not supported.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF @Throttle < 1 OR @Throttle > 100
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Throttle is not supported.', 16, 1;
END;
IF @Throttle IS NOT NULL AND (@BackupSoftware NOT IN('LITESPEED') OR @BackupSoftware IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Throttle is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @Encrypt NOT IN('Y','N') OR @Encrypt IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Encrypt is not supported.', 16, 1;
END;
IF @Encrypt = 'Y' AND @BackupSoftware IS NULL AND NOT (@Version >= 12 AND (SERVERPROPERTY('EngineEdition') IN(3, 8) OR SERVERPROPERTY('EditionID') IN(-1534726760, 284895786)))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Encrypt is not supported.', 16, 2;
END;
IF @Encrypt = 'Y' AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Encrypt is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF @BackupSoftware IS NULL AND @Encrypt = 'Y' AND (@EncryptionAlgorithm NOT IN('AES_128','AES_192','AES_256','TRIPLE_DES_3KEY') OR @EncryptionAlgorithm IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @EncryptionAlgorithm is not supported.', 16, 1;
END;
IF @BackupSoftware = 'LITESPEED' AND @Encrypt = 'Y' AND (@EncryptionAlgorithm NOT IN('RC2_40','RC2_56','RC2_112','RC2_128','TRIPLE_DES_3KEY','RC4_128','AES_128','AES_192','AES_256') OR @EncryptionAlgorithm IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @EncryptionAlgorithm is not supported.', 16, 2;
END;
IF @BackupSoftware = 'SQLBACKUP' AND @Encrypt = 'Y' AND (@EncryptionAlgorithm NOT IN('AES_128','AES_256') OR @EncryptionAlgorithm IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @EncryptionAlgorithm is not supported.', 16, 3;
END;
IF @BackupSoftware = 'SQLSAFE' AND @Encrypt = 'Y' AND (@EncryptionAlgorithm NOT IN('AES_128','AES_256') OR @EncryptionAlgorithm IS NULL)
OR (@EncryptionAlgorithm IS NOT NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @EncryptionAlgorithm is not supported.', 16, 4;
END;
IF @EncryptionAlgorithm IS NOT NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @EncryptionAlgorithm is not supported.', 16, 5;
END;
----------------------------------------------------------------------------------------------------
IF (NOT (@BackupSoftware IS NULL AND @Encrypt = 'Y') AND @ServerCertificate IS NOT NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ServerCertificate is not supported.', 16, 1;
END;
IF @BackupSoftware IS NULL AND @Encrypt = 'Y' AND @ServerCertificate IS NULL AND @ServerAsymmetricKey IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ServerCertificate is not supported.', 16, 2;
END;
IF @BackupSoftware IS NULL AND @Encrypt = 'Y' AND @ServerCertificate IS NOT NULL AND @ServerAsymmetricKey IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ServerCertificate is not supported.', 16, 3;
END;
IF @ServerCertificate IS NOT NULL AND NOT EXISTS(SELECT * FROM master.[sys].[certificates] WHERE [name] = @ServerCertificate)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ServerCertificate is not supported.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF NOT (@BackupSoftware IS NULL AND @Encrypt = 'Y') AND @ServerAsymmetricKey IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ServerAsymmetricKey is not supported.', 16, 1;
END;
IF @BackupSoftware IS NULL AND @Encrypt = 'Y' AND @ServerAsymmetricKey IS NULL AND @ServerCertificate IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ServerAsymmetricKey is not supported.', 16, 2;
END;
IF @BackupSoftware IS NULL AND @Encrypt = 'Y' AND @ServerAsymmetricKey IS NOT NULL AND @ServerCertificate IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ServerAsymmetricKey is not supported.', 16, 3;
END;
IF @ServerAsymmetricKey IS NOT NULL AND NOT EXISTS(SELECT * FROM master.[sys].[asymmetric_keys] WHERE [name] = @ServerAsymmetricKey)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ServerAsymmetricKey is not supported.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF @EncryptionKey IS NOT NULL AND @BackupSoftware IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @EncryptionKey is not supported.', 16, 1;
END;
IF @EncryptionKey IS NOT NULL AND @Encrypt = 'N'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @EncryptionKey is not supported.', 16, 2;
END;
IF @EncryptionKey IS NULL AND @Encrypt = 'Y' AND @BackupSoftware IN('LITESPEED','SQLBACKUP','SQLSAFE')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @EncryptionKey is not supported.', 16, 3;
END;
IF @EncryptionKey IS NOT NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @EncryptionKey is not supported.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF @ReadWriteFileGroups NOT IN('Y','N') OR @ReadWriteFileGroups IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ReadWriteFileGroups is not supported.', 16, 1;
END;
IF @ReadWriteFileGroups = 'Y' AND @BackupType = 'LOG'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ReadWriteFileGroups is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @OverrideBackupPreference NOT IN('Y','N') OR @OverrideBackupPreference IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @OverrideBackupPreference is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @NoRecovery NOT IN('Y','N') OR @NoRecovery IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NoRecovery is not supported.', 16, 1;
END;
IF @NoRecovery = 'Y' AND @BackupType <> 'LOG'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NoRecovery is not supported.', 16, 2;
END;
IF @NoRecovery = 'Y' AND @BackupSoftware = 'SQLSAFE'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NoRecovery is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF @URL IS NOT NULL AND @Directory IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @URL is not supported.', 16, 1;
END;
IF @URL IS NOT NULL AND @MirrorDirectory IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @URL is not supported.', 16, 2;
END;
IF @URL IS NOT NULL AND @Version < 11.03339
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @URL is not supported.', 16, 3;
END;
IF @URL IS NOT NULL AND @BackupSoftware IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @URL is not supported.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF @Credential IS NULL AND @URL IS NOT NULL AND NOT (@Version >= 13 OR SERVERPROPERTY('EngineEdition') = 8)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Credential is not supported.', 16, 1;
END;
IF @Credential IS NOT NULL AND @URL IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Credential is not supported.', 16, 2;
END;
IF @URL IS NOT NULL AND @Credential IS NULL AND NOT EXISTS(SELECT * FROM [sys].[credentials] WHERE UPPER([credential_identity]) IN('SHARED ACCESS SIGNATURE','MANAGED IDENTITY','S3 ACCESS KEY'))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Credential is not supported.', 16, 3;
END;
IF @Credential IS NOT NULL AND NOT EXISTS(SELECT * FROM [sys].[credentials] WHERE [name] = @Credential)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Credential is not supported.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF @MirrorCleanupTime < 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorCleanupTime is not supported.', 16, 1;
END;
IF @MirrorCleanupTime IS NOT NULL AND @MirrorDirectory IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorCleanupTime is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @MirrorCleanupMode NOT IN('BEFORE_BACKUP','AFTER_BACKUP') OR @MirrorCleanupMode IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorCleanupMode is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @MirrorURL IS NOT NULL AND @Directory IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorURL is not supported.', 16, 1;
END;
IF @MirrorURL IS NOT NULL AND @MirrorDirectory IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorURL is not supported.', 16, 2;
END;
IF @MirrorURL IS NOT NULL AND @Version < 11.03339
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorURL is not supported.', 16, 3;
END;
IF @MirrorURL IS NOT NULL AND @BackupSoftware IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorURL is not supported.', 16, 4;
END;
IF @MirrorURL IS NOT NULL AND @URL IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MirrorURL is not supported.', 16, 5;
END;
----------------------------------------------------------------------------------------------------
IF @Updateability NOT IN('READ_ONLY','READ_WRITE','ALL') OR @Updateability IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Updateability is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @AdaptiveCompression NOT IN('SIZE','SPEED')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AdaptiveCompression is not supported.', 16, 1;
END;
IF @AdaptiveCompression IS NOT NULL AND (@BackupSoftware NOT IN('LITESPEED') OR @BackupSoftware IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AdaptiveCompression is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @ModificationLevel IS NOT NULL AND NOT EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_file_space_usage') AND [name] = 'modified_extent_page_count')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ModificationLevel is not supported.', 16, 1;
END;
IF @ModificationLevel <= 0 OR @ModificationLevel > 100
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ModificationLevel is not supported.', 16, 2;
END;
IF @ModificationLevel IS NOT NULL AND @ChangeBackupType = 'N'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameter @ModificationLevel can only be used together with @ChangeBackupType = ''Y''.', 16, 3;
END;
IF @ModificationLevel IS NOT NULL AND @BackupType <> 'DIFF'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameter @ModificationLevel can only be used for differential backups.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF @MinDatabaseSizeForDifferentialBackup <= 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MinDatabaseSizeForDifferentialBackup is not supported.', 16, 1;
END;
IF @MinDatabaseSizeForDifferentialBackup IS NOT NULL AND @BackupType <> 'DIFF'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameter @MinDatabaseSizeForDifferentialBackup can only be used for differential backups.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @LogSizeSinceLastLogBackup IS NOT NULL AND NOT EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_log_stats') AND [name] = 'log_since_last_log_backup_mb')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LogSizeSinceLastLogBackup is not supported.', 16, 1;
END;
IF @LogSizeSinceLastLogBackup IS NOT NULL AND @BackupType <> 'LOG'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LogSizeSinceLastLogBackup is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @TimeSinceLastLogBackup IS NOT NULL AND NOT EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_log_stats') AND [name] = 'log_backup_time')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @TimeSinceLastLogBackup is not supported.', 16, 1;
END;
IF @TimeSinceLastLogBackup IS NOT NULL AND @BackupType <> 'LOG'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @TimeSinceLastLogBackup is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF (@TimeSinceLastLogBackup IS NOT NULL AND @LogSizeSinceLastLogBackup IS NULL) OR (@TimeSinceLastLogBackup IS NULL AND @LogSizeSinceLastLogBackup IS NOT NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameters @TimeSinceLastLogBackup and @LogSizeSinceLastLogBackup can only be used together.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @DataDomainBoostHost IS NOT NULL AND (@BackupSoftware <> 'DATA_DOMAIN_BOOST' OR @BackupSoftware IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DataDomainBoostHost is not supported.', 16, 1;
END;
IF @DataDomainBoostHost IS NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DataDomainBoostHost is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @DataDomainBoostUser IS NOT NULL AND (@BackupSoftware <> 'DATA_DOMAIN_BOOST' OR @BackupSoftware IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DataDomainBoostUser is not supported.', 16, 1;
END;
IF @DataDomainBoostUser IS NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DataDomainBoostUser is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @DataDomainBoostDevicePath IS NOT NULL AND (@BackupSoftware <> 'DATA_DOMAIN_BOOST' OR @BackupSoftware IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DataDomainBoostDevicePath is not supported.', 16, 1;
END;
IF @DataDomainBoostDevicePath IS NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DataDomainBoostDevicePath is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @DataDomainBoostLockboxPath IS NOT NULL AND (@BackupSoftware <> 'DATA_DOMAIN_BOOST' OR @BackupSoftware IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DataDomainBoostLockboxPath is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @DirectoryStructure = ''
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DirectoryStructure is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @AvailabilityGroupDirectoryStructure = ''
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroupDirectoryStructure is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @DirectoryStructureCase NOT IN('LOWER','UPPER')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DirectoryStructureCase is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @FileName IS NULL OR @FileName = ''
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileName is not supported.', 16, 1;
END;
IF @FileName NOT LIKE '%.{FileExtension}'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileName is not supported.', 16, 2;
END;
IF (@NumberOfFiles > 1 AND @FileName NOT LIKE '%{FileNumber}%')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileName is not supported.', 16, 3;
END;
IF @FileName LIKE '%{DirectorySeparator}%'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileName is not supported.', 16, 4;
END;
IF @FileName LIKE '%/%'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileName is not supported.', 16, 5;
END;
IF @FileName LIKE '%\%'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileName is not supported.', 16, 6;
END;
----------------------------------------------------------------------------------------------------
IF (SERVERPROPERTY('IsHadrEnabled') = 1 AND @AvailabilityGroupFileName IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroupFileName is not supported.', 16, 1;
END;
IF @AvailabilityGroupFileName = ''
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroupFileName is not supported.', 16, 2;
END;
IF @AvailabilityGroupFileName NOT LIKE '%.{FileExtension}'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroupFileName is not supported.', 16, 3;
END;
IF (@NumberOfFiles > 1 AND @AvailabilityGroupFileName NOT LIKE '%{FileNumber}%')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroupFileName is not supported.', 16, 4;
END;
IF @AvailabilityGroupFileName LIKE '%{DirectorySeparator}%'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroupFileName is not supported.', 16, 5;
END;
IF @AvailabilityGroupFileName LIKE '%/%'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroupFileName is not supported.', 16, 6;
END;
IF @AvailabilityGroupFileName LIKE '%\%'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroupFileName is not supported.', 16, 7;
END;
----------------------------------------------------------------------------------------------------
IF @FileNameCase NOT IN('LOWER','UPPER')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileNameCase is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS (SELECT * FROM (SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@DirectoryStructure,'{DirectorySeparator}',''),'{ServerName}',''),'{InstanceName}',''),'{ServiceName}',''),'{ClusterName}',''),'{AvailabilityGroupName}',''),'{DatabaseName}',''),'{BackupType}',''),'{Partial}',''),'{CopyOnly}',''),'{Description}',''),'{BackupSetName}',''),'{Year}',''),'{Month}',''),'{Day}',''),'{Week}',''),'{Weekday}',''),'{Hour}',''),'{Minute}',''),'{Second}',''),'{Millisecond}',''),'{Microsecond}',''),'{MajorVersion}',''),'{MinorVersion}','') AS DirectoryStructure) Temp WHERE DirectoryStructure LIKE '%{%' OR DirectoryStructure LIKE '%}%')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameter @DirectoryStructure contains one or more tokens that are not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS (SELECT * FROM (SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@AvailabilityGroupDirectoryStructure,'{DirectorySeparator}',''),'{ServerName}',''),'{InstanceName}',''),'{ServiceName}',''),'{ClusterName}',''),'{AvailabilityGroupName}',''),'{DatabaseName}',''),'{BackupType}',''),'{Partial}',''),'{CopyOnly}',''),'{Description}',''),'{BackupSetName}',''),'{Year}',''),'{Month}',''),'{Day}',''),'{Week}',''),'{Weekday}',''),'{Hour}',''),'{Minute}',''),'{Second}',''),'{Millisecond}',''),'{Microsecond}',''),'{MajorVersion}',''),'{MinorVersion}','') AS AvailabilityGroupDirectoryStructure) Temp WHERE AvailabilityGroupDirectoryStructure LIKE '%{%' OR AvailabilityGroupDirectoryStructure LIKE '%}%')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameter @AvailabilityGroupDirectoryStructure contains one or more tokens that are not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS (SELECT * FROM (SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@FileName,'{DirectorySeparator}',''),'{ServerName}',''),'{InstanceName}',''),'{ServiceName}',''),'{ClusterName}',''),'{AvailabilityGroupName}',''),'{DatabaseName}',''),'{BackupType}',''),'{Partial}',''),'{CopyOnly}',''),'{Description}',''),'{BackupSetName}',''),'{Year}',''),'{Month}',''),'{Day}',''),'{Week}',''),'{Weekday}',''),'{Hour}',''),'{Minute}',''),'{Second}',''),'{Millisecond}',''),'{Microsecond}',''),'{FileNumber}',''),'{NumberOfFiles}',''),'{FileExtension}',''),'{MajorVersion}',''),'{MinorVersion}','') AS [FileName]) Temp WHERE [FileName] LIKE '%{%' OR [FileName] LIKE '%}%')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameter @FileName contains one or more tokens that are not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS (SELECT * FROM (SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(@AvailabilityGroupFileName,'{DirectorySeparator}',''),'{ServerName}',''),'{InstanceName}',''),'{ServiceName}',''),'{ClusterName}',''),'{AvailabilityGroupName}',''),'{DatabaseName}',''),'{BackupType}',''),'{Partial}',''),'{CopyOnly}',''),'{Description}',''),'{BackupSetName}',''),'{Year}',''),'{Month}',''),'{Day}',''),'{Week}',''),'{Weekday}',''),'{Hour}',''),'{Minute}',''),'{Second}',''),'{Millisecond}',''),'{Microsecond}',''),'{FileNumber}',''),'{NumberOfFiles}',''),'{FileExtension}',''),'{MajorVersion}',''),'{MinorVersion}','') AS AvailabilityGroupFileName) Temp WHERE AvailabilityGroupFileName LIKE '%{%' OR AvailabilityGroupFileName LIKE '%}%')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameter @AvailabilityGroupFileName contains one or more tokens that are not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @TokenTimezone NOT IN('LOCAL','UTC') OR @TokenTimezone IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @TokenTimezone is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @FileExtensionFull LIKE '%.%'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileExtensionFull is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @FileExtensionDiff LIKE '%.%'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileExtensionDiff is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @FileExtensionLog LIKE '%.%'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileExtensionLog is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Init NOT IN('Y','N') OR @Init IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Init is not supported.', 16, 1;
END;
IF @Init = 'Y' AND @BackupType = 'LOG'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Init is not supported.', 16, 2;
END;
IF @Init = 'Y' AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Init is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF @Format NOT IN('Y','N') OR @Format IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Format is not supported.', 16, 1;
END;
IF @Format = 'Y' AND @BackupType = 'LOG'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Format is not supported.', 16, 2;
END;
IF @Format = 'Y' AND @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Format is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF @ObjectLevelRecoveryMap NOT IN('Y','N') OR @ObjectLevelRecoveryMap IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ObjectLevelRecovery is not supported.', 16, 1;
END;
IF @ObjectLevelRecoveryMap = 'Y' AND @BackupSoftware IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ObjectLevelRecovery is not supported.', 16, 2;
END;
IF @ObjectLevelRecoveryMap = 'Y' AND @BackupSoftware <> 'LITESPEED'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ObjectLevelRecovery is not supported.', 16, 3;
END;
IF @ObjectLevelRecoveryMap = 'Y' AND @BackupType = 'LOG'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ObjectLevelRecovery is not supported.', 16, 4;
END;
----------------------------------------------------------------------------------------------------
IF @ExcludeLogShippedFromLogBackup NOT IN('Y','N') OR @ExcludeLogShippedFromLogBackup IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ExcludeLogShippedFromLogBackup is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @DirectoryCheck NOT IN('Y','N') OR @DirectoryCheck IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DirectoryCheck is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @BackupOptions IS NOT NULL AND @URL IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @BackupOptions is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Stats <= 0 OR @Stats > 100
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Stats is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @ExpireDate IS NOT NULL AND @BackupSoftware <> 'LITESPEED'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ExpireDate is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @RetainDays < 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @RetainDays is not supported.', 16, 1;
END;
IF @RetainDays IS NOT NULL AND @BackupSoftware <> 'LITESPEED'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @RetainDays is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @StringDelimiter IS NULL OR LEN(@StringDelimiter) > 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @StringDelimiter is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @DatabaseOrder NOT IN('DATABASE_NAME_ASC','DATABASE_NAME_DESC','DATABASE_SIZE_ASC','DATABASE_SIZE_DESC','LOG_SIZE_SINCE_LAST_LOG_BACKUP_ASC','LOG_SIZE_SINCE_LAST_LOG_BACKUP_DESC')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseOrder is not supported.', 16, 1;
END;
IF @DatabaseOrder IN('LOG_SIZE_SINCE_LAST_LOG_BACKUP_ASC','LOG_SIZE_SINCE_LAST_LOG_BACKUP_DESC') AND NOT EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_log_stats') AND [name] = 'log_since_last_log_backup_mb')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseOrder is not supported. The column sys.dm_db_log_stats.log_since_last_log_backup_mb is not available in this version of SQL Server.', 16, 2;
END;
IF @DatabaseOrder IS NOT NULL AND SERVERPROPERTY('EngineEdition') = 5
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseOrder is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF @DatabasesInParallel NOT IN('Y','N') OR @DatabasesInParallel IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabasesInParallel is not supported.', 16, 1;
END;
IF @DatabasesInParallel = 'Y' AND SERVERPROPERTY('EngineEdition') = 5
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabasesInParallel is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @LogToTable NOT IN('Y','N') OR @LogToTable IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LogToTable is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Execute NOT IN('Y','N') OR @Execute IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Execute is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS(SELECT * FROM @Errors)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The documentation is available at https://ola.hallengren.com/sql-server-backup.html.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Check that selected databases and availability groups exist //--
----------------------------------------------------------------------------------------------------
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @SelectedDatabases
WHERE DatabaseName NOT LIKE '%[%]%'
AND DatabaseName NOT IN (SELECT DatabaseName FROM @tmpDatabases);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following databases in the @Databases parameter do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(AvailabilityGroupName) + ', '
FROM @SelectedAvailabilityGroups
WHERE AvailabilityGroupName NOT LIKE '%[%]%'
AND AvailabilityGroupName NOT IN (SELECT AvailabilityGroupName FROM @tmpAvailabilityGroups);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following availability groups do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
----------------------------------------------------------------------------------------------------
--// Check @@SERVERNAME //--
----------------------------------------------------------------------------------------------------
IF UPPER(@@SERVERNAME) <> UPPER(CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(MAX))) AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The @@SERVERNAME does not match SERVERPROPERTY(''ServerName''). See ' + CASE WHEN SERVERPROPERTY('IsClustered') = 0 THEN 'https://docs.microsoft.com/en-us/sql/database-engine/install-windows/rename-a-computer-that-hosts-a-stand-alone-instance-of-sql-server' WHEN SERVERPROPERTY('IsClustered') = 1 THEN 'https://docs.microsoft.com/en-us/sql/sql-server/failover-clusters/install/rename-a-sql-server-failover-cluster-instance' END + '.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Raise errors //--
----------------------------------------------------------------------------------------------------
DECLARE ErrorCursor CURSOR FAST_FORWARD FOR SELECT [Message], [severity], [State] FROM @Errors ORDER BY [ID] ASC;
OPEN ErrorCursor;
FETCH ErrorCursor INTO @CurrentMessage, @CurrentSeverity, @CurrentState;
WHILE @@FETCH_STATUS = 0
BEGIN
RAISERROR('%s', @CurrentSeverity, @CurrentState, @CurrentMessage) WITH NOWAIT;
RAISERROR(@EmptyLine, 10, 1) WITH NOWAIT;
FETCH NEXT FROM ErrorCursor INTO @CurrentMessage, @CurrentSeverity, @CurrentState;
END;
CLOSE ErrorCursor;
DEALLOCATE ErrorCursor;
IF EXISTS (SELECT * FROM @Errors WHERE [severity] >= 16)
BEGIN
SET @ReturnCode = 50000;
GOTO Logging;
END;
----------------------------------------------------------------------------------------------------
--// Check Availability Group cluster name //--
----------------------------------------------------------------------------------------------------
IF @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
SELECT @Cluster = NULLIF([cluster_name],'')
FROM [sys].[dm_hadr_cluster];
END;
----------------------------------------------------------------------------------------------------
--// Update database order //--
----------------------------------------------------------------------------------------------------
IF @DatabaseOrder IN('DATABASE_SIZE_ASC','DATABASE_SIZE_DESC')
BEGIN
UPDATE tmpDatabases
SET DatabaseSize = (SELECT SUM(CAST(SIZE AS BIGINT)) FROM [sys].[master_files] WHERE [type] = 0 AND [database_id] = DB_ID(tmpDatabases.DatabaseName))
FROM @tmpDatabases tmpDatabases;
END;
IF @DatabaseOrder IN('LOG_SIZE_SINCE_LAST_LOG_BACKUP_ASC','LOG_SIZE_SINCE_LAST_LOG_BACKUP_DESC')
BEGIN
UPDATE tmpDatabases
SET LogSizeSinceLastLogBackup = (SELECT log_since_last_log_backup_mb FROM [sys].dm_db_log_stats(DB_ID(tmpDatabases.DatabaseName)))
FROM @tmpDatabases tmpDatabases;
END;
IF @DatabaseOrder IS NULL
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY StartPosition ASC, DatabaseName ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_NAME_ASC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseName ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_NAME_DESC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseName DESC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_SIZE_ASC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseSize ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_SIZE_DESC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseSize DESC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'LOG_SIZE_SINCE_LAST_LOG_BACKUP_ASC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY LogSizeSinceLastLogBackup ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'LOG_SIZE_SINCE_LAST_LOG_BACKUP_DESC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY LogSizeSinceLastLogBackup DESC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
----------------------------------------------------------------------------------------------------
--// Update the queue //--
----------------------------------------------------------------------------------------------------
IF @DatabasesInParallel = 'Y'
BEGIN
BEGIN TRY
SELECT @QueueID = QueueID
FROM [dbo].[Queue]
WHERE SchemaName = @SchemaName
AND ObjectName = @ObjectName
AND [Parameters] = @Parameters;
IF @QueueID IS NULL
BEGIN
BEGIN TRANSACTION;
SELECT @QueueID = QueueID
FROM [dbo].[Queue] WITH (UPDLOCK, HOLDLOCK)
WHERE SchemaName = @SchemaName
AND ObjectName = @ObjectName
AND [Parameters] = @Parameters;
IF @QueueID IS NULL
BEGIN
INSERT INTO [dbo].[Queue] (SchemaName, ObjectName, [Parameters])
SELECT @SchemaName, @ObjectName, @Parameters;
SET @QueueID = SCOPE_IDENTITY();
END;
COMMIT TRANSACTION;
END;
BEGIN TRANSACTION;
UPDATE [Queue]
SET QueueStartTime = SYSDATETIME(),
SessionID = @@SPID,
RequestID = (SELECT [request_id] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID),
RequestStartTime = (SELECT [start_time] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID)
FROM [dbo].[Queue] [Queue]
WHERE QueueID = @QueueID
AND NOT EXISTS (SELECT *
FROM [sys].[dm_exec_requests]
WHERE [session_id] = [Queue].SessionID
AND [request_id] = [Queue].RequestID
AND [start_time] = [Queue].RequestStartTime)
AND NOT EXISTS (SELECT *
FROM [dbo].QueueDatabase QueueDatabase
INNER JOIN [sys].[dm_exec_requests] ON QueueDatabase.SessionID = [session_id] AND QueueDatabase.RequestID = [request_id] AND QueueDatabase.RequestStartTime = [start_time]
WHERE QueueDatabase.QueueID = @QueueID);
IF @@ROWCOUNT = 1
BEGIN
INSERT INTO [dbo].QueueDatabase (QueueID, DatabaseName)
SELECT @QueueID AS QueueID,
DatabaseName
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
AND NOT EXISTS (SELECT * FROM [dbo].QueueDatabase WHERE DatabaseName = tmpDatabases.DatabaseName AND QueueID = @QueueID);
DELETE QueueDatabase
FROM [dbo].QueueDatabase QueueDatabase
WHERE QueueID = @QueueID
AND NOT EXISTS (SELECT * FROM @tmpDatabases tmpDatabases WHERE DatabaseName = QueueDatabase.DatabaseName AND Selected = 1);
UPDATE QueueDatabase
SET DatabaseOrder = tmpDatabases.[Order]
FROM [dbo].QueueDatabase QueueDatabase
INNER JOIN @tmpDatabases tmpDatabases ON QueueDatabase.DatabaseName = tmpDatabases.DatabaseName
WHERE QueueID = @QueueID;
END;
COMMIT TRANSACTION;
SELECT @QueueStartTime = QueueStartTime
FROM [dbo].[Queue]
WHERE QueueID = @QueueID;
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0
BEGIN
ROLLBACK TRANSACTION;
END;
SET @ErrorMessage = 'Msg ' + CAST(ERROR_NUMBER() AS NVARCHAR) + ', ' + ISNULL(ERROR_MESSAGE(),'');
RAISERROR('%s',16,1,@ErrorMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
SET @ReturnCode = ERROR_NUMBER();
GOTO Logging;
END CATCH;
END;
----------------------------------------------------------------------------------------------------
--// Execute backup commands //--
----------------------------------------------------------------------------------------------------
WHILE (1 = 1)
BEGIN -- Start of database loop
IF @DatabasesInParallel = 'Y'
BEGIN
UPDATE QueueDatabase
SET DatabaseStartTime = NULL,
SessionID = NULL,
RequestID = NULL,
RequestStartTime = NULL
FROM [dbo].QueueDatabase QueueDatabase
WHERE QueueID = @QueueID
AND DatabaseStartTime IS NOT NULL
AND DatabaseEndTime IS NULL
AND NOT EXISTS (SELECT * FROM [sys].[dm_exec_requests] WHERE [session_id] = QueueDatabase.SessionID AND [request_id] = QueueDatabase.RequestID AND [start_time] = QueueDatabase.RequestStartTime);
UPDATE QueueDatabase
SET DatabaseStartTime = SYSDATETIME(),
DatabaseEndTime = NULL,
SessionID = @@SPID,
RequestID = (SELECT [request_id] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID),
RequestStartTime = (SELECT [start_time] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID),
@CurrentDatabaseName = DatabaseName,
@CurrentDatabaseNameFS = (SELECT DatabaseNameFS FROM @tmpDatabases WHERE DatabaseName = QueueDatabase.DatabaseName)
FROM (SELECT TOP 1 DatabaseStartTime,
DatabaseEndTime,
SessionID,
RequestID,
RequestStartTime,
DatabaseName
FROM [dbo].QueueDatabase
WHERE QueueID = @QueueID
AND (DatabaseStartTime < @QueueStartTime OR DatabaseStartTime IS NULL)
AND NOT (DatabaseStartTime IS NOT NULL AND DatabaseEndTime IS NULL)
ORDER BY DatabaseOrder ASC
) QueueDatabase;
END;
ELSE
BEGIN
SELECT TOP 1 @CurrentDBID = [Id],
@CurrentDatabaseName = DatabaseName,
@CurrentDatabaseNameFS = DatabaseNameFS
FROM @tmpDatabases
WHERE Selected = 1
AND Completed = 0
ORDER BY [Order] ASC;
END;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
SET @CurrentDatabase_sp_executesql = QUOTENAME(@CurrentDatabaseName) + '.sys.sp_executesql';
BEGIN
SET @DatabaseMessage = 'Date and time: ' + CONVERT(NVARCHAR,SYSDATETIME(),120);
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Database: ' + QUOTENAME(@CurrentDatabaseName);
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
SELECT @CurrentUserAccess = [user_access_desc],
@CurrentIsReadOnly = [is_read_only],
@CurrentDatabaseState = [state_desc],
@CurrentInStandby = [is_in_standby],
@CurrentRecoveryModel = [recovery_model_desc],
@CurrentIsEncrypted = [is_encrypted],
@CurrentDatabaseSize = (SELECT SUM(CAST(SIZE AS BIGINT)) FROM [sys].[master_files] WHERE [type] = 0 AND [database_id] = [sys].[databases].[database_id])
FROM [sys].[databases]
WHERE [name] = @CurrentDatabaseName;
BEGIN
SET @DatabaseMessage = 'State: ' + @CurrentDatabaseState;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Standby: ' + CASE WHEN @CurrentInStandby = 1 THEN 'Yes' ELSE 'No' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Updateability: ' + CASE WHEN @CurrentIsReadOnly = 1 THEN 'READ_ONLY' WHEN @CurrentIsReadOnly = 0 THEN 'READ_WRITE' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'User access: ' + @CurrentUserAccess;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Recovery model: ' + @CurrentRecoveryModel;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Encrypted: ' + CASE WHEN @CurrentIsEncrypted = 1 THEN 'Yes' WHEN @CurrentIsEncrypted = 0 THEN 'No' ELSE 'N/A' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
SELECT @CurrentMaxTransferSize = CASE
WHEN @MaxTransferSize IS NOT NULL THEN @MaxTransferSize
WHEN @MaxTransferSize IS NULL AND @Compress = 'Y' AND @CurrentIsEncrypted = 1 AND @BackupSoftware IS NULL AND (@Version >= 13 AND @Version < 15.0404316) AND @Credential IS NULL THEN 65537
END;
IF @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
SELECT @CurrentReplicaID = [databases].[replica_id]
FROM [sys].[databases] [databases]
INNER JOIN [sys].[availability_replicas] [availability_replicas] ON [databases].[replica_id] = [availability_replicas].[replica_id]
WHERE [databases].[name] = @CurrentDatabaseName;
SELECT @CurrentAvailabilityGroupID = [group_id]
FROM [sys].[availability_replicas]
WHERE [replica_id] = @CurrentReplicaID;
SELECT @CurrentAvailabilityGroupRole = [role_desc]
FROM [sys].[dm_hadr_availability_replica_states]
WHERE [replica_id] = @CurrentReplicaID;
SELECT @CurrentAvailabilityGroupDatabaseReplicaSynchronizationState = [synchronization_state_desc],
@CurrentAvailabilityGroupDatabaseReplicaSynchronizationHealth = [synchronization_health_desc]
FROM [sys].[dm_hadr_database_replica_states]
WHERE [replica_id] = @CurrentReplicaID
AND [database_id] = DB_ID(@CurrentDatabaseName);
SELECT @CurrentAvailabilityGroup = [name],
@CurrentAvailabilityGroupBackupPreference = UPPER([automated_backup_preference_desc])
FROM [sys].[availability_groups]
WHERE [group_id] = @CurrentAvailabilityGroupID;
END;
IF @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1 AND @CurrentAvailabilityGroup IS NOT NULL
BEGIN
SELECT @CurrentIsPreferredBackupReplica = [sys].fn_hadr_backup_is_preferred_replica(@CurrentDatabaseName);
END;
SELECT @CurrentDifferentialBaseLSN = [differential_base_lsn]
FROM [sys].[master_files]
WHERE [database_id] = DB_ID(@CurrentDatabaseName)
AND [type] = 0
AND [file_id] = 1;
IF @CurrentDatabaseState = 'ONLINE' AND NOT (@CurrentInStandby = 1)
BEGIN
SELECT @CurrentLogLSN = [last_log_backup_lsn]
FROM [sys].[database_recovery_status]
WHERE [database_id] = DB_ID(@CurrentDatabaseName);
END;
IF @CurrentDatabaseState = 'ONLINE' AND NOT (@CurrentInStandby = 1)
AND EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_file_space_usage') AND [name] = 'modified_extent_page_count')
AND (@CurrentAvailabilityGroupRole = 'PRIMARY' OR @CurrentAvailabilityGroupRole IS NULL)
AND (@BackupType IN('DIFF','FULL') OR (@ChangeBackupType = 'Y' AND @CurrentBackupType = 'LOG' AND @CurrentRecoveryModel IN('FULL','BULK_LOGGED') AND @CurrentLogLSN IS NULL AND @CurrentDatabaseName <> 'master'))
AND (@ModificationLevel IS NOT NULL OR @MinBackupSizeForMultipleFiles IS NOT NULL OR @MaxFileSize IS NOT NULL OR @MinDatabaseSizeForDifferentialBackup IS NOT NULL)
BEGIN
SET @CurrentCommand = 'SELECT @ParamAllocatedExtentPageCount = SUM(allocated_extent_page_count), @ParamModifiedExtentPageCount = SUM(modified_extent_page_count) FROM sys.dm_db_file_space_usage';
EXECUTE @CurrentDatabase_sp_executesql @stmt = @CurrentCommand, @params = N'@ParamAllocatedExtentPageCount bigint OUTPUT, @ParamModifiedExtentPageCount bigint OUTPUT', @ParamAllocatedExtentPageCount = @CurrentAllocatedExtentPageCount OUTPUT, @ParamModifiedExtentPageCount = @CurrentModifiedExtentPageCount OUTPUT;
END;
SET @CurrentBackupType = @BackupType;
IF @ChangeBackupType = 'Y'
BEGIN
IF @CurrentBackupType = 'LOG' AND @CurrentRecoveryModel IN('FULL','BULK_LOGGED') AND @CurrentLogLSN IS NULL AND @CurrentDatabaseName <> 'master'
BEGIN
SET @CurrentBackupType = 'DIFF';
END;
IF @CurrentBackupType = 'DIFF' AND (@CurrentDatabaseName = 'master' OR @CurrentDifferentialBaseLSN IS NULL OR (@CurrentModifiedExtentPageCount * 1. / @CurrentAllocatedExtentPageCount * 100 >= @ModificationLevel) OR (COALESCE(CAST(@CurrentAllocatedExtentPageCount AS BIGINT) * 8192, CAST(@CurrentDatabaseSize AS BIGINT) * 8192) < CAST(@MinDatabaseSizeForDifferentialBackup AS BIGINT) * 1024 * 1024))
BEGIN
SET @CurrentBackupType = 'FULL';
END;
END;
IF @CurrentDatabaseState = 'ONLINE' AND NOT (@CurrentInStandby = 1)
AND EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_log_stats') AND [name] = 'log_since_last_log_backup_mb')
BEGIN
SELECT @CurrentLastLogBackup = log_backup_time,
@CurrentLogSizeSinceLastLogBackup = log_since_last_log_backup_mb
FROM [sys].dm_db_log_stats (DB_ID(@CurrentDatabaseName));
END;
IF @CurrentBackupType = 'DIFF'
BEGIN
SELECT @CurrentDifferentialBaseIsSnapshot = [is_snapshot]
FROM msdb.[dbo].[backupset]
WHERE [database_name] = @CurrentDatabaseName
AND [type] = 'D'
AND [checkpoint_lsn] = @CurrentDifferentialBaseLSN;
END;
IF @ChangeBackupType = 'Y'
BEGIN
IF @CurrentBackupType = 'DIFF' AND @CurrentDifferentialBaseIsSnapshot = 1
BEGIN
SET @CurrentBackupType = 'FULL';
END;
END;
WITH CurrentDatabase AS
(
SELECT BackupSize = CASE WHEN @CurrentBackupType = 'FULL' THEN COALESCE(CAST(@CurrentAllocatedExtentPageCount AS BIGINT) * 8192, CAST(@CurrentDatabaseSize AS BIGINT) * 8192)
WHEN @CurrentBackupType = 'DIFF' THEN CAST(@CurrentModifiedExtentPageCount AS BIGINT) * 8192
WHEN @CurrentBackupType = 'LOG' THEN CAST(@CurrentLogSizeSinceLastLogBackup * 1024 * 1024 AS BIGINT)
END,
MaxNumberOfFiles = CASE WHEN @BackupSoftware IN('SQLBACKUP','DATA_DOMAIN_BOOST') THEN 32 ELSE 64 END,
CASE WHEN (SELECT COUNT(*) FROM @Directories WHERE [mirror] = 0) > 0 THEN (SELECT COUNT(*) FROM @Directories WHERE [mirror] = 0) ELSE (SELECT COUNT(*) FROM @URLs WHERE [mirror] = 0) END AS NumberOfDirectories,
CAST(@MinBackupSizeForMultipleFiles AS BIGINT) * 1024 * 1024 AS MinBackupSizeForMultipleFiles,
CAST(@MaxFileSize AS BIGINT) * 1024 * 1024 AS MaxFileSize
)
SELECT @CurrentNumberOfFiles = CASE WHEN @NumberOfFiles IS NULL AND @BackupSoftware = 'DATA_DOMAIN_BOOST' THEN 1
WHEN @NumberOfFiles IS NULL AND @MaxFileSize IS NULL THEN NumberOfDirectories
WHEN @NumberOfFiles = 1 THEN @NumberOfFiles
WHEN @NumberOfFiles > 1 AND (BackupSize >= MinBackupSizeForMultipleFiles OR MinBackupSizeForMultipleFiles IS NULL OR BackupSize IS NULL) THEN @NumberOfFiles
WHEN @NumberOfFiles > 1 AND (BackupSize < MinBackupSizeForMultipleFiles) THEN NumberOfDirectories
WHEN @NumberOfFiles IS NULL AND @MaxFileSize IS NOT NULL AND (BackupSize IS NULL OR BackupSize = 0) THEN NumberOfDirectories
WHEN @NumberOfFiles IS NULL AND @MaxFileSize IS NOT NULL THEN (SELECT MIN(NumberOfFilesInEachDirectory)
FROM (SELECT ((BackupSize / NumberOfDirectories) / MaxFileSize + CASE WHEN (BackupSize / NumberOfDirectories) % MaxFileSize = 0 THEN 0 ELSE 1 END) AS NumberOfFilesInEachDirectory
UNION
SELECT MaxNumberOfFiles / NumberOfDirectories) Files) * NumberOfDirectories
END
FROM CurrentDatabase;
SELECT @CurrentDatabaseMirroringRole = UPPER([mirroring_role_desc])
FROM [sys].[database_mirroring] [database_mirroring]
INNER JOIN [sys].[databases] [databases] ON [database_mirroring].[database_id] = [databases].[database_id]
WHERE [databases].[name] = @CurrentDatabaseName;
IF EXISTS (SELECT * FROM msdb.[dbo].[log_shipping_primary_databases] WHERE [primary_database] = @CurrentDatabaseName)
BEGIN
SET @CurrentLogShippingRole = 'PRIMARY';
END;
ELSE
IF EXISTS (SELECT * FROM msdb.[dbo].[log_shipping_secondary_databases] WHERE [secondary_database] = @CurrentDatabaseName)
BEGIN
SET @CurrentLogShippingRole = 'SECONDARY';
END;
IF @CurrentAvailabilityGroup IS NOT NULL
BEGIN
IF ((@CurrentBackupType = 'FULL' AND @CopyOnly = 'N' AND @Version >= 17)
OR (@CurrentBackupType = 'DIFF' AND @CopyOnly = 'N' AND @Version >= 17)
OR (@CurrentBackupType = 'FULL' AND @CopyOnly = 'Y')
OR (@CurrentBackupType = 'LOG' AND @CopyOnly = 'N'))
BEGIN
SET @CurrentBackupOperationSupportedOnSecondaryReplicas = 1;
END;
ELSE
BEGIN
SET @CurrentBackupOperationSupportedOnSecondaryReplicas = 0;
END;
END;
IF @CurrentAvailabilityGroup IS NOT NULL
BEGIN
SET @DatabaseMessage = 'Availability group: ' + ISNULL(@CurrentAvailabilityGroup,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Availability group role: ' + ISNULL(@CurrentAvailabilityGroupRole,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Availability group database replica synchronization state: ' + ISNULL(@CurrentAvailabilityGroupDatabaseReplicaSynchronizationState,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Availability group database replica synchronization health: ' + ISNULL(@CurrentAvailabilityGroupDatabaseReplicaSynchronizationHealth,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Availability group backup preference: ' + ISNULL(@CurrentAvailabilityGroupBackupPreference,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Is preferred backup replica: ' + CASE WHEN @CurrentIsPreferredBackupReplica = 1 THEN 'Yes' WHEN @CurrentIsPreferredBackupReplica = 0 THEN 'No' ELSE 'N/A' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
IF @CurrentAvailabilityGroupBackupPreference IN('SECONDARY', 'SECONDARY_ONLY')
BEGIN
SET @DatabaseMessage = 'Is backup operation supported on secondary replicas: ' + CASE WHEN @CurrentBackupOperationSupportedOnSecondaryReplicas = 1 THEN 'Yes' WHEN @CurrentBackupOperationSupportedOnSecondaryReplicas = 0 THEN 'No' ELSE 'N/A' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
END;
IF @CurrentDatabaseMirroringRole IS NOT NULL
BEGIN
SET @DatabaseMessage = 'Database mirroring role: ' + @CurrentDatabaseMirroringRole;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
IF @CurrentLogShippingRole IS NOT NULL
BEGIN
SET @DatabaseMessage = 'Log shipping role: ' + @CurrentLogShippingRole;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
SET @DatabaseMessage = 'Differential base LSN: ' + ISNULL(CAST(@CurrentDifferentialBaseLSN AS NVARCHAR),'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
IF @CurrentBackupType = 'DIFF' OR @CurrentDifferentialBaseIsSnapshot IS NOT NULL
BEGIN
SET @DatabaseMessage = 'Differential base is snapshot: ' + CASE WHEN @CurrentDifferentialBaseIsSnapshot = 1 THEN 'Yes' WHEN @CurrentDifferentialBaseIsSnapshot = 0 THEN 'No' ELSE 'N/A' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
SET @DatabaseMessage = 'Last log backup LSN: ' + ISNULL(CAST(@CurrentLogLSN AS NVARCHAR),'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
IF @CurrentBackupType IN('DIFF','FULL') AND EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_file_space_usage') AND [name] = 'modified_extent_page_count')
BEGIN
SET @DatabaseMessage = 'Allocated extent page count: ' + ISNULL(CAST(@CurrentAllocatedExtentPageCount AS NVARCHAR) + ' (' + CAST(@CurrentAllocatedExtentPageCount * 1. * 8 / 1024 AS NVARCHAR) + ' MB)','N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Modified extent page count: ' + ISNULL(CAST(@CurrentModifiedExtentPageCount AS NVARCHAR) + ' (' + CAST(@CurrentModifiedExtentPageCount * 1. * 8 / 1024 AS NVARCHAR) + ' MB)','N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
IF @CurrentBackupType = 'LOG' AND EXISTS(SELECT * FROM [sys].[all_columns] WHERE OBJECT_ID = OBJECT_ID('sys.dm_db_log_stats') AND [name] = 'log_since_last_log_backup_mb')
BEGIN
SET @DatabaseMessage = 'Last log backup: ' + ISNULL(CONVERT(NVARCHAR(19),NULLIF(@CurrentLastLogBackup,'1900-01-01'),120),'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Log size since last log backup (MB): ' + ISNULL(CAST(@CurrentLogSizeSinceLastLogBackup AS NVARCHAR),'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF @CurrentDatabaseState = 'ONLINE'
AND NOT (@CurrentUserAccess = 'SINGLE_USER')
AND NOT (@CurrentInStandby = 1)
AND NOT (@CurrentBackupType = 'LOG' AND @CurrentRecoveryModel = 'SIMPLE')
AND NOT (@CurrentBackupType = 'LOG' AND @CurrentRecoveryModel IN('FULL','BULK_LOGGED') AND @CurrentLogLSN IS NULL)
AND NOT (@CurrentBackupType = 'DIFF' AND @CurrentDifferentialBaseLSN IS NULL)
AND NOT (@CurrentBackupType IN('DIFF','LOG') AND @CurrentDatabaseName = 'master')
AND NOT (@CurrentAvailabilityGroup IS NOT NULL AND @CurrentBackupOperationSupportedOnSecondaryReplicas = 0 AND (@CurrentAvailabilityGroupRole <> 'PRIMARY' OR @CurrentAvailabilityGroupRole IS NULL))
AND NOT (@CurrentAvailabilityGroup IS NOT NULL AND @CurrentBackupOperationSupportedOnSecondaryReplicas = 1 AND (@CurrentIsPreferredBackupReplica <> 1 OR @CurrentIsPreferredBackupReplica IS NULL) AND @OverrideBackupPreference = 'N')
AND NOT (@CurrentIsReadOnly = 1 AND @Updateability = 'READ_WRITE')
AND NOT (@CurrentIsReadOnly = 0 AND @Updateability = 'READ_ONLY')
AND NOT (@CurrentBackupType = 'LOG' AND @LogSizeSinceLastLogBackup IS NOT NULL AND @TimeSinceLastLogBackup IS NOT NULL AND NOT(@CurrentLogSizeSinceLastLogBackup >= @LogSizeSinceLastLogBackup OR @CurrentLogSizeSinceLastLogBackup IS NULL OR DATEDIFF(SECOND,@CurrentLastLogBackup,SYSDATETIME()) >= @TimeSinceLastLogBackup OR @CurrentLastLogBackup IS NULL))
AND NOT (@CurrentBackupType = 'LOG' AND @Updateability = 'READ_ONLY' AND @BackupSoftware = 'DATA_DOMAIN_BOOST')
AND NOT (@CurrentBackupType = 'DIFF' AND @MinDatabaseSizeForDifferentialBackup IS NOT NULL AND (COALESCE(CAST(@CurrentAllocatedExtentPageCount AS BIGINT) * 8192, CAST(@CurrentDatabaseSize AS BIGINT) * 8192) < CAST(@MinDatabaseSizeForDifferentialBackup AS BIGINT) * 1024 * 1024))
BEGIN -- Start of database backup check
IF @CurrentBackupType = 'LOG' AND (@CleanupTime IS NOT NULL OR @MirrorCleanupTime IS NOT NULL)
BEGIN
SELECT @CurrentLatestBackup = MAX([backup_start_date])
FROM msdb.[dbo].[backupset]
WHERE ([type] IN('D','I')
OR ([type] = 'L' AND [last_lsn] < @CurrentDifferentialBaseLSN))
AND [is_damaged] = 0
AND [database_name] = @CurrentDatabaseName;
END;
SET @CurrentDate = SYSDATETIME();
SET @CurrentDateUTC = SYSUTCDATETIME();
INSERT INTO @CurrentCleanupDates (CleanupDate)
SELECT @CurrentDate;
IF @CurrentBackupType = 'LOG'
BEGIN
INSERT INTO @CurrentCleanupDates (CleanupDate)
SELECT @CurrentLatestBackup;
END;
SELECT @CurrentDirectoryStructure = CASE
WHEN @CurrentAvailabilityGroup IS NOT NULL THEN @AvailabilityGroupDirectoryStructure
ELSE @DirectoryStructure
END;
IF @CurrentDirectoryStructure IS NOT NULL
BEGIN
-- Directory structure - remove tokens that are not needed
IF @ReadWriteFileGroups = 'N' SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Partial}','');
IF @CopyOnly = 'N' SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{CopyOnly}','');
IF @Cluster IS NULL SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{ClusterName}','');
IF @CurrentAvailabilityGroup IS NULL SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{AvailabilityGroupName}','');
IF SERVERPROPERTY('InstanceName') IS NULL SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{InstanceName}','');
IF @@SERVICENAME IS NULL SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{ServiceName}','');
IF @Description IS NULL SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Description}','');
IF @BackupSetName IS NULL SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{BackupSetName}','');
IF @Directory IS NULL AND @MirrorDirectory IS NULL AND @URL IS NULL AND @DefaultDirectory LIKE '%' + '.' + @@SERVICENAME + @DirectorySeparator + 'MSSQL' + @DirectorySeparator + 'Backup'
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{ServerName}','');
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{InstanceName}','');
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{ClusterName}','');
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{AvailabilityGroupName}','');
END;
WHILE (@Updated = 1 OR @Updated IS NULL)
BEGIN
SET @Updated = 0;
IF CHARINDEX('\',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'\','{DirectorySeparator}');
SET @Updated = 1;
END;
IF CHARINDEX('/',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'/','{DirectorySeparator}');
SET @Updated = 1;
END;
IF CHARINDEX('__',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'__','_');
SET @Updated = 1;
END;
IF CHARINDEX('--',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'--','-');
SET @Updated = 1;
END;
IF CHARINDEX('{DirectorySeparator}{DirectorySeparator}',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{DirectorySeparator}{DirectorySeparator}','{DirectorySeparator}');
SET @Updated = 1;
END;
IF CHARINDEX('{DirectorySeparator}$',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{DirectorySeparator}$','{DirectorySeparator}');
SET @Updated = 1;
END;
IF CHARINDEX('${DirectorySeparator}',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'${DirectorySeparator}','{DirectorySeparator}');
SET @Updated = 1;
END;
IF CHARINDEX('{DirectorySeparator}_',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{DirectorySeparator}_','{DirectorySeparator}');
SET @Updated = 1;
END;
IF CHARINDEX('_{DirectorySeparator}',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'_{DirectorySeparator}','{DirectorySeparator}');
SET @Updated = 1;
END;
IF CHARINDEX('{DirectorySeparator}-',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{DirectorySeparator}-','{DirectorySeparator}');
SET @Updated = 1;
END;
IF CHARINDEX('-{DirectorySeparator}',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'-{DirectorySeparator}','{DirectorySeparator}');
SET @Updated = 1;
END;
IF CHARINDEX('_$',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'_$','_');
SET @Updated = 1;
END;
IF CHARINDEX('$_',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'$_','_');
SET @Updated = 1;
END;
IF CHARINDEX('-$',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'-$','-');
SET @Updated = 1;
END;
IF CHARINDEX('$-',@CurrentDirectoryStructure) > 0
BEGIN
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'$-','-');
SET @Updated = 1;
END;
IF LEFT(@CurrentDirectoryStructure,1) = '_'
BEGIN
SET @CurrentDirectoryStructure = RIGHT(@CurrentDirectoryStructure,LEN(@CurrentDirectoryStructure) - 1);
SET @Updated = 1;
END;
IF RIGHT(@CurrentDirectoryStructure,1) = '_'
BEGIN
SET @CurrentDirectoryStructure = LEFT(@CurrentDirectoryStructure,LEN(@CurrentDirectoryStructure) - 1);
SET @Updated = 1;
END;
IF LEFT(@CurrentDirectoryStructure,1) = '-'
BEGIN
SET @CurrentDirectoryStructure = RIGHT(@CurrentDirectoryStructure,LEN(@CurrentDirectoryStructure) - 1);
SET @Updated = 1;
END;
IF RIGHT(@CurrentDirectoryStructure,1) = '-'
BEGIN
SET @CurrentDirectoryStructure = LEFT(@CurrentDirectoryStructure,LEN(@CurrentDirectoryStructure) - 1);
SET @Updated = 1;
END;
IF LEFT(@CurrentDirectoryStructure,1) = '$'
BEGIN
SET @CurrentDirectoryStructure = RIGHT(@CurrentDirectoryStructure,LEN(@CurrentDirectoryStructure) - 1);
SET @Updated = 1;
END;
IF RIGHT(@CurrentDirectoryStructure,1) = '$'
BEGIN
SET @CurrentDirectoryStructure = LEFT(@CurrentDirectoryStructure,LEN(@CurrentDirectoryStructure) - 1);
SET @Updated = 1;
END;
IF LEFT(@CurrentDirectoryStructure,20) = '{DirectorySeparator}'
BEGIN
SET @CurrentDirectoryStructure = RIGHT(@CurrentDirectoryStructure,LEN(@CurrentDirectoryStructure) - 20);
SET @Updated = 1;
END;
IF RIGHT(@CurrentDirectoryStructure,20) = '{DirectorySeparator}'
BEGIN
SET @CurrentDirectoryStructure = LEFT(@CurrentDirectoryStructure,LEN(@CurrentDirectoryStructure) - 20);
SET @Updated = 1;
END;
END;
SET @Updated = NULL;
-- Directory structure - replace tokens with real values
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{DirectorySeparator}',@DirectorySeparator);
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{ServerName}',CASE WHEN SERVERPROPERTY('EngineEdition') = 8 THEN LEFT(CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(MAX)),CHARINDEX('.',CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(MAX))) - 1) ELSE CAST(SERVERPROPERTY('MachineName') AS NVARCHAR(MAX)) END);
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{InstanceName}',ISNULL(CAST(SERVERPROPERTY('InstanceName') AS NVARCHAR(MAX)),''));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{ServiceName}',ISNULL(@@SERVICENAME,''));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{ClusterName}',ISNULL(@Cluster,''));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{AvailabilityGroupName}',ISNULL(@CurrentAvailabilityGroup,''));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{DatabaseName}',@CurrentDatabaseNameFS);
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{BackupType}',@CurrentBackupType);
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Partial}','PARTIAL');
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{CopyOnly}','COPY_ONLY');
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Description}',LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(@Description,''),'\',''),'/',''),':',''),'*',''),'?',''),'"',''),'<',''),'>',''),'|',''))));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{BackupSetName}',LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(@BackupSetName,''),'\',''),'/',''),':',''),'*',''),'?',''),'"',''),'<',''),'>',''),'|',''))));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Year}',CAST(DATEPART(YEAR,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Month}',RIGHT('0' + CAST(DATEPART(MONTH,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Day}',RIGHT('0' + CAST(DATEPART(DAY,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Week}',RIGHT('0' + CAST(DATEPART(WEEK,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Weekday}',DATENAME(WEEKDAY,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Hour}',RIGHT('0' + CAST(DATEPART(HOUR,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Minute}',RIGHT('0' + CAST(DATEPART(MINUTE,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Second}',RIGHT('0' + CAST(DATEPART(SECOND,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Millisecond}',RIGHT('00' + CAST(DATEPART(MILLISECOND,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),3));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{Microsecond}',RIGHT('00000' + CAST(DATEPART(MICROSECOND,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),6));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{MajorVersion}',ISNULL(CAST(SERVERPROPERTY('ProductMajorVersion') AS NVARCHAR),PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR),4)));
SET @CurrentDirectoryStructure = REPLACE(@CurrentDirectoryStructure,'{MinorVersion}',ISNULL(CAST(SERVERPROPERTY('ProductMinorVersion') AS NVARCHAR),PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR),3)));
END;
IF @DirectoryStructureCase IS NOT NULL
BEGIN
SET @CurrentDirectoryStructure = CASE WHEN @DirectoryStructureCase = 'LOWER' THEN LOWER(@CurrentDirectoryStructure)
WHEN @DirectoryStructureCase = 'UPPER' THEN UPPER(@CurrentDirectoryStructure) END;
END;
INSERT INTO @CurrentDirectories ([Id], DirectoryPath, [mirror], DirectoryNumber, CreateCompleted, CleanupCompleted)
SELECT ROW_NUMBER() OVER (ORDER BY [Id]),
DirectoryPath + CASE WHEN DirectoryPath = 'NUL' THEN '' WHEN @CurrentDirectoryStructure IS NOT NULL THEN @DirectorySeparator + @CurrentDirectoryStructure ELSE '' END,
[mirror],
ROW_NUMBER() OVER (PARTITION BY [mirror] ORDER BY [Id] ASC),
0,
0
FROM @Directories
ORDER BY [Id] ASC;
INSERT INTO @CurrentURLs ([Id], DirectoryPath, [mirror], DirectoryNumber)
SELECT ROW_NUMBER() OVER (ORDER BY [Id]),
DirectoryPath + CASE WHEN @CurrentDirectoryStructure IS NOT NULL THEN @DirectorySeparator + @CurrentDirectoryStructure ELSE '' END,
[mirror],
ROW_NUMBER() OVER (PARTITION BY [mirror] ORDER BY [Id] ASC)
FROM @URLs
ORDER BY [Id] ASC;
SELECT @CurrentDatabaseFileName = CASE
WHEN @CurrentAvailabilityGroup IS NOT NULL THEN @AvailabilityGroupFileName
ELSE @FileName
END;
-- File name - remove tokens that are not needed
IF @ReadWriteFileGroups = 'N' SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Partial}','');
IF @CopyOnly = 'N' SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{CopyOnly}','');
IF @Cluster IS NULL SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{ClusterName}','');
IF @CurrentAvailabilityGroup IS NULL SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{AvailabilityGroupName}','');
IF SERVERPROPERTY('InstanceName') IS NULL SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{InstanceName}','');
IF @@SERVICENAME IS NULL SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{ServiceName}','');
IF @Description IS NULL SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Description}','');
IF @BackupSetName IS NULL SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{BackupSetName}','');
IF @CurrentNumberOfFiles = 1 SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{FileNumber}','');
IF @CurrentNumberOfFiles = 1 SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{NumberOfFiles}','');
WHILE (@Updated = 1 OR @Updated IS NULL)
BEGIN
SET @Updated = 0;
IF CHARINDEX('__',@CurrentDatabaseFileName) > 0
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'__','_');
SET @Updated = 1;
END;
IF CHARINDEX('--',@CurrentDatabaseFileName) > 0
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'--','-');
SET @Updated = 1;
END;
IF CHARINDEX('_$',@CurrentDatabaseFileName) > 0
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'_$','_');
SET @Updated = 1;
END;
IF CHARINDEX('$_',@CurrentDatabaseFileName) > 0
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'$_','_');
SET @Updated = 1;
END;
IF CHARINDEX('-$',@CurrentDatabaseFileName) > 0
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'-$','-');
SET @Updated = 1;
END;
IF CHARINDEX('$-',@CurrentDatabaseFileName) > 0
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'$-','-');
SET @Updated = 1;
END;
IF CHARINDEX('_.',@CurrentDatabaseFileName) > 0
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'_.','.');
SET @Updated = 1;
END;
IF CHARINDEX('-.',@CurrentDatabaseFileName) > 0
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'-.','.');
SET @Updated = 1;
END;
IF CHARINDEX('of.',@CurrentDatabaseFileName) > 0
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'of.','.');
SET @Updated = 1;
END;
IF LEFT(@CurrentDatabaseFileName,1) = '_'
BEGIN
SET @CurrentDatabaseFileName = RIGHT(@CurrentDatabaseFileName,LEN(@CurrentDatabaseFileName) - 1);
SET @Updated = 1;
END;
IF RIGHT(@CurrentDatabaseFileName,1) = '_'
BEGIN
SET @CurrentDatabaseFileName = LEFT(@CurrentDatabaseFileName,LEN(@CurrentDatabaseFileName) - 1);
SET @Updated = 1;
END;
IF LEFT(@CurrentDatabaseFileName,1) = '-'
BEGIN
SET @CurrentDatabaseFileName = RIGHT(@CurrentDatabaseFileName,LEN(@CurrentDatabaseFileName) - 1);
SET @Updated = 1;
END;
IF RIGHT(@CurrentDatabaseFileName,1) = '-'
BEGIN
SET @CurrentDatabaseFileName = LEFT(@CurrentDatabaseFileName,LEN(@CurrentDatabaseFileName) - 1);
SET @Updated = 1;
END;
IF LEFT(@CurrentDatabaseFileName,1) = '$'
BEGIN
SET @CurrentDatabaseFileName = RIGHT(@CurrentDatabaseFileName,LEN(@CurrentDatabaseFileName) - 1);
SET @Updated = 1;
END;
IF RIGHT(@CurrentDatabaseFileName,1) = '$'
BEGIN
SET @CurrentDatabaseFileName = LEFT(@CurrentDatabaseFileName,LEN(@CurrentDatabaseFileName) - 1);
SET @Updated = 1;
END;
END;
SET @Updated = NULL;
SELECT @CurrentFileExtension = CASE
WHEN @CurrentBackupType = 'FULL' THEN @FileExtensionFull
WHEN @CurrentBackupType = 'DIFF' THEN @FileExtensionDiff
WHEN @CurrentBackupType = 'LOG' THEN @FileExtensionLog
END;
-- File name - replace tokens with real values
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{ServerName}',CASE WHEN SERVERPROPERTY('EngineEdition') = 8 THEN LEFT(CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(MAX)),CHARINDEX('.',CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(MAX))) - 1) ELSE CAST(SERVERPROPERTY('MachineName') AS NVARCHAR(MAX)) END);
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{InstanceName}',ISNULL(CAST(SERVERPROPERTY('InstanceName') AS NVARCHAR(MAX)),''));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{ServiceName}',ISNULL(@@SERVICENAME,''));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{ClusterName}',ISNULL(@Cluster,''));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{AvailabilityGroupName}',ISNULL(@CurrentAvailabilityGroup,''));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{BackupType}',@CurrentBackupType);
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Partial}','PARTIAL');
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{CopyOnly}','COPY_ONLY');
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Description}',LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(@Description,''),'\',''),'/',''),':',''),'*',''),'?',''),'"',''),'<',''),'>',''),'|',''))));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{BackupSetName}',LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(ISNULL(@BackupSetName,''),'\',''),'/',''),':',''),'*',''),'?',''),'"',''),'<',''),'>',''),'|',''))));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Year}',CAST(DATEPART(YEAR,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Month}',RIGHT('0' + CAST(DATEPART(MONTH,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Day}',RIGHT('0' + CAST(DATEPART(DAY,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Week}',RIGHT('0' + CAST(DATEPART(WEEK,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Weekday}',DATENAME(WEEKDAY,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Hour}',RIGHT('0' + CAST(DATEPART(HOUR,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Minute}',RIGHT('0' + CAST(DATEPART(MINUTE,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Second}',RIGHT('0' + CAST(DATEPART(SECOND,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),2));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Millisecond}',RIGHT('00' + CAST(DATEPART(MILLISECOND,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),3));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{Microsecond}',RIGHT('00000' + CAST(DATEPART(MICROSECOND,CASE WHEN @TokenTimezone = 'UTC' THEN @CurrentDateUTC ELSE @CurrentDate END) AS NVARCHAR),6));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{NumberOfFiles}',@CurrentNumberOfFiles);
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{FileExtension}',@CurrentFileExtension);
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{MajorVersion}',ISNULL(CAST(SERVERPROPERTY('ProductMajorVersion') AS NVARCHAR),PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR),4)));
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{MinorVersion}',ISNULL(CAST(SERVERPROPERTY('ProductMinorVersion') AS NVARCHAR),PARSENAME(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR),3)));
SELECT @CurrentMaxFilePathLength = CASE
WHEN EXISTS (SELECT * FROM @CurrentDirectories) THEN (SELECT MAX(LEN(DirectoryPath + @DirectorySeparator)) FROM @CurrentDirectories)
WHEN EXISTS (SELECT * FROM @CurrentURLs) THEN (SELECT MAX(LEN(DirectoryPath + @DirectorySeparator)) FROM @CurrentURLs)
END
+ LEN(REPLACE(REPLACE(@CurrentDatabaseFileName,'{DatabaseName}',@CurrentDatabaseNameFS), '{FileNumber}', CASE WHEN @CurrentNumberOfFiles >= 1 AND @CurrentNumberOfFiles <= 9 THEN '1' WHEN @CurrentNumberOfFiles >= 10 THEN '01' END));
-- The maximum length of a backup device is 259 characters
IF @CurrentMaxFilePathLength > 259
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{DatabaseName}',LEFT(@CurrentDatabaseNameFS,CASE WHEN (LEN(@CurrentDatabaseNameFS) + 259 - @CurrentMaxFilePathLength - 3) < 20 THEN 20 ELSE (LEN(@CurrentDatabaseNameFS) + 259 - @CurrentMaxFilePathLength - 3) END) + '...');
END;
ELSE
BEGIN
SET @CurrentDatabaseFileName = REPLACE(@CurrentDatabaseFileName,'{DatabaseName}',@CurrentDatabaseNameFS);
END;
IF @FileNameCase IS NOT NULL
BEGIN
SET @CurrentDatabaseFileName = CASE WHEN @FileNameCase = 'LOWER' THEN LOWER(@CurrentDatabaseFileName)
WHEN @FileNameCase = 'UPPER' THEN UPPER(@CurrentDatabaseFileName) END;
END;
IF EXISTS (SELECT * FROM @CurrentDirectories WHERE [mirror] = 0)
BEGIN
SET @CurrentFileNumber = 0;
WHILE @CurrentFileNumber < @CurrentNumberOfFiles
BEGIN
SET @CurrentFileNumber = @CurrentFileNumber + 1;
SELECT @CurrentDirectoryPath = DirectoryPath
FROM @CurrentDirectories
WHERE @CurrentFileNumber >= (DirectoryNumber - 1) * (SELECT @CurrentNumberOfFiles / COUNT(*) FROM @CurrentDirectories WHERE [mirror] = 0) + 1
AND @CurrentFileNumber <= DirectoryNumber * (SELECT @CurrentNumberOfFiles / COUNT(*) FROM @CurrentDirectories WHERE [mirror] = 0)
AND [mirror] = 0;
SET @CurrentFileName = REPLACE(@CurrentDatabaseFileName, '{FileNumber}', CASE WHEN @CurrentNumberOfFiles >= 1 AND @CurrentNumberOfFiles <= 9 THEN CAST(@CurrentFileNumber AS NVARCHAR) WHEN @CurrentNumberOfFiles >= 10 THEN RIGHT('0' + CAST(@CurrentFileNumber AS NVARCHAR),2) END);
IF @CurrentDirectoryPath = 'NUL'
BEGIN
SET @CurrentFilePath = 'NUL';
END;
ELSE
BEGIN
SET @CurrentFilePath = @CurrentDirectoryPath + @DirectorySeparator + @CurrentFileName;
END;
INSERT INTO @CurrentFiles ([Type], FilePath, [mirror])
SELECT 'DISK', @CurrentFilePath, 0;
SET @CurrentDirectoryPath = NULL;
SET @CurrentFileName = NULL;
SET @CurrentFilePath = NULL;
END;
INSERT INTO @CurrentBackupSet ([mirror], VerifyCompleted)
SELECT 0, 0;
END;
IF EXISTS (SELECT * FROM @CurrentDirectories WHERE [mirror] = 1)
BEGIN
SET @CurrentFileNumber = 0;
WHILE @CurrentFileNumber < @CurrentNumberOfFiles
BEGIN
SET @CurrentFileNumber = @CurrentFileNumber + 1;
SELECT @CurrentDirectoryPath = DirectoryPath
FROM @CurrentDirectories
WHERE @CurrentFileNumber >= (DirectoryNumber - 1) * (SELECT @CurrentNumberOfFiles / COUNT(*) FROM @CurrentDirectories WHERE [mirror] = 1) + 1
AND @CurrentFileNumber <= DirectoryNumber * (SELECT @CurrentNumberOfFiles / COUNT(*) FROM @CurrentDirectories WHERE [mirror] = 1)
AND [mirror] = 1;
SET @CurrentFileName = REPLACE(@CurrentDatabaseFileName, '{FileNumber}', CASE WHEN @CurrentNumberOfFiles > 1 AND @CurrentNumberOfFiles <= 9 THEN CAST(@CurrentFileNumber AS NVARCHAR) WHEN @CurrentNumberOfFiles >= 10 THEN RIGHT('0' + CAST(@CurrentFileNumber AS NVARCHAR),2) ELSE '' END);
SET @CurrentFilePath = @CurrentDirectoryPath + @DirectorySeparator + @CurrentFileName;
INSERT INTO @CurrentFiles ([Type], FilePath, [mirror])
SELECT 'DISK', @CurrentFilePath, 1;
SET @CurrentDirectoryPath = NULL;
SET @CurrentFileName = NULL;
SET @CurrentFilePath = NULL;
END;
INSERT INTO @CurrentBackupSet ([mirror], VerifyCompleted)
SELECT 1, 0;
END;
IF EXISTS (SELECT * FROM @CurrentURLs WHERE [mirror] = 0)
BEGIN
SET @CurrentFileNumber = 0;
WHILE @CurrentFileNumber < @CurrentNumberOfFiles
BEGIN
SET @CurrentFileNumber = @CurrentFileNumber + 1;
SELECT @CurrentDirectoryPath = DirectoryPath
FROM @CurrentURLs
WHERE @CurrentFileNumber >= (DirectoryNumber - 1) * (SELECT @CurrentNumberOfFiles / COUNT(*) FROM @CurrentURLs WHERE [mirror] = 0) + 1
AND @CurrentFileNumber <= DirectoryNumber * (SELECT @CurrentNumberOfFiles / COUNT(*) FROM @CurrentURLs WHERE [mirror] = 0)
AND [mirror] = 0;
SET @CurrentFileName = REPLACE(@CurrentDatabaseFileName, '{FileNumber}', CASE WHEN @CurrentNumberOfFiles > 1 AND @CurrentNumberOfFiles <= 9 THEN CAST(@CurrentFileNumber AS NVARCHAR) WHEN @CurrentNumberOfFiles >= 10 THEN RIGHT('0' + CAST(@CurrentFileNumber AS NVARCHAR),2) ELSE '' END);
SET @CurrentFilePath = @CurrentDirectoryPath + @DirectorySeparator + @CurrentFileName;
INSERT INTO @CurrentFiles ([Type], FilePath, [mirror])
SELECT 'URL', @CurrentFilePath, 0;
SET @CurrentDirectoryPath = NULL;
SET @CurrentFileName = NULL;
SET @CurrentFilePath = NULL;
END;
INSERT INTO @CurrentBackupSet ([mirror], VerifyCompleted)
SELECT 0, 0;
END;
IF EXISTS (SELECT * FROM @CurrentURLs WHERE [mirror] = 1)
BEGIN
SET @CurrentFileNumber = 0;
WHILE @CurrentFileNumber < @CurrentNumberOfFiles
BEGIN
SET @CurrentFileNumber = @CurrentFileNumber + 1;
SELECT @CurrentDirectoryPath = DirectoryPath
FROM @CurrentURLs
WHERE @CurrentFileNumber >= (DirectoryNumber - 1) * (SELECT @CurrentNumberOfFiles / COUNT(*) FROM @CurrentURLs WHERE [mirror] = 0) + 1
AND @CurrentFileNumber <= DirectoryNumber * (SELECT @CurrentNumberOfFiles / COUNT(*) FROM @CurrentURLs WHERE [mirror] = 0)
AND [mirror] = 1;
SET @CurrentFileName = REPLACE(@CurrentDatabaseFileName, '{FileNumber}', CASE WHEN @CurrentNumberOfFiles > 1 AND @CurrentNumberOfFiles <= 9 THEN CAST(@CurrentFileNumber AS NVARCHAR) WHEN @CurrentNumberOfFiles >= 10 THEN RIGHT('0' + CAST(@CurrentFileNumber AS NVARCHAR),2) ELSE '' END);
SET @CurrentFilePath = @CurrentDirectoryPath + @DirectorySeparator + @CurrentFileName;
INSERT INTO @CurrentFiles ([Type], FilePath, [mirror])
SELECT 'URL', @CurrentFilePath, 1;
SET @CurrentDirectoryPath = NULL;
SET @CurrentFileName = NULL;
SET @CurrentFilePath = NULL;
END;
INSERT INTO @CurrentBackupSet ([mirror], VerifyCompleted)
SELECT 1, 0;
END;
-- Create directory
IF @HostPlatform = 'Windows'
AND (@BackupSoftware <> 'DATA_DOMAIN_BOOST' OR @BackupSoftware IS NULL)
AND NOT EXISTS(SELECT * FROM @CurrentDirectories WHERE DirectoryPath = 'NUL' OR DirectoryPath IN(SELECT DirectoryPath FROM @Directories))
BEGIN
WHILE (1 = 1)
BEGIN
SELECT TOP 1 @CurrentDirectoryID = [Id],
@CurrentDirectoryPath = DirectoryPath
FROM @CurrentDirectories
WHERE CreateCompleted = 0
ORDER BY [Id] ASC;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
IF @DirectoryCheck = 'Y'
BEGIN
IF @Version >= 14
BEGIN
INSERT INTO @DirectoryInfo (FileExists, FileIsADirectory, ParentDirectoryExists)
SELECT file_exists,
file_is_a_directory,
parent_directory_exists
FROM [sys].dm_os_file_exists (@CurrentDirectoryPath);
END;
ELSE
BEGIN
INSERT INTO @DirectoryInfo (FileExists, FileIsADirectory, ParentDirectoryExists)
EXECUTE [master].[dbo].xp_fileexist @CurrentDirectoryPath;
END;
END;
IF NOT EXISTS (SELECT * FROM @DirectoryInfo WHERE FileExists = 0 AND FileIsADirectory = 1 AND ParentDirectoryExists = 1)
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'xp_create_subdir';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_create_subdir N''' + REPLACE(@CurrentDirectoryPath,'''','''''') + ''' IF @ReturnCode <> 0 RAISERROR(''Error creating directory.'', 16, 1)';
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseContext, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 1, @DatabaseName = @CurrentDatabaseName, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
UPDATE @CurrentDirectories
SET CreateCompleted = 1,
CreateOutput = @CurrentCommandOutput
WHERE [Id] = @CurrentDirectoryID;
END;
ELSE
BEGIN
UPDATE @CurrentDirectories
SET CreateCompleted = 1,
CreateOutput = 0
WHERE [Id] = @CurrentDirectoryID;
END;
SET @CurrentDirectoryID = NULL;
SET @CurrentDirectoryPath = NULL;
SET @CurrentDatabaseContext = NULL;
SET @CurrentCommand = NULL;
SET @CurrentCommandOutput = NULL;
SET @CurrentCommandType = NULL;
DELETE FROM @DirectoryInfo;
END;
END;
IF @CleanupMode = 'BEFORE_BACKUP'
BEGIN
INSERT INTO @CurrentCleanupDates (CleanupDate, [mirror])
SELECT DATEADD(hh,-(@CleanupTime),SYSDATETIME()), 0;
IF NOT EXISTS(SELECT * FROM @CurrentCleanupDates WHERE ([mirror] = 0 OR [mirror] IS NULL) AND CleanupDate IS NULL)
BEGIN
UPDATE @CurrentDirectories
SET CleanupDate = (SELECT MIN(CleanupDate)
FROM @CurrentCleanupDates
WHERE ([mirror] = 0 OR [mirror] IS NULL)),
CleanupMode = 'BEFORE_BACKUP'
WHERE [mirror] = 0;
END;
END;
IF @MirrorCleanupMode = 'BEFORE_BACKUP'
BEGIN
INSERT INTO @CurrentCleanupDates (CleanupDate, [mirror])
SELECT DATEADD(hh,-(@MirrorCleanupTime),SYSDATETIME()), 1;
IF NOT EXISTS(SELECT * FROM @CurrentCleanupDates WHERE ([mirror] = 1 OR [mirror] IS NULL) AND CleanupDate IS NULL)
BEGIN
UPDATE @CurrentDirectories
SET CleanupDate = (SELECT MIN(CleanupDate)
FROM @CurrentCleanupDates
WHERE ([mirror] = 1 OR [mirror] IS NULL)),
CleanupMode = 'BEFORE_BACKUP'
WHERE [mirror] = 1;
END;
END;
-- Delete old backup files, before backup
IF (NOT EXISTS (SELECT * FROM @CurrentDirectories WHERE CreateOutput <> 0 OR CreateOutput IS NULL) OR @HostPlatform = 'Linux')
AND (@BackupSoftware <> 'DATA_DOMAIN_BOOST' OR @BackupSoftware IS NULL)
AND @CurrentBackupType = @BackupType
BEGIN
WHILE (1 = 1)
BEGIN
SELECT TOP 1 @CurrentDirectoryID = [Id],
@CurrentDirectoryPath = DirectoryPath,
@CurrentCleanupDate = CleanupDate
FROM @CurrentDirectories
WHERE CleanupDate IS NOT NULL
AND CleanupMode = 'BEFORE_BACKUP'
AND CleanupCompleted = 0
ORDER BY [Id] ASC;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
IF @BackupSoftware IS NULL
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'xp_delete_file';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_delete_file 0, N''' + REPLACE(@CurrentDirectoryPath,'''','''''') + ''', ''' + @CurrentFileExtension + ''', ''' + CONVERT(NVARCHAR(19),@CurrentCleanupDate,126) + ''' IF @ReturnCode <> 0 RAISERROR(''Error deleting files.'', 16, 1)';
END;
IF @BackupSoftware = 'LITESPEED'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'xp_slssqlmaint';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_slssqlmaint N''-MAINTDEL -DELFOLDER "' + REPLACE(@CurrentDirectoryPath,'''','''''') + '" -DELEXTENSION "' + @CurrentFileExtension + '" -DELUNIT "' + CAST(DATEDIFF(mi,@CurrentCleanupDate,SYSDATETIME()) + 1 AS NVARCHAR) + '" -DELUNITTYPE "minutes" -DELUSEAGE'' IF @ReturnCode <> 0 RAISERROR(''Error deleting LiteSpeed backup files.'', 16, 1)';
END;
IF @BackupSoftware = 'SQLBACKUP'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'sqbutility';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.sqbutility 1032, N''' + REPLACE(@CurrentDatabaseName,'''','''''') + ''', N''' + REPLACE(@CurrentDirectoryPath,'''','''''') + ''', ''' + CASE WHEN @CurrentBackupType = 'FULL' THEN 'D' WHEN @CurrentBackupType = 'DIFF' THEN 'I' WHEN @CurrentBackupType = 'LOG' THEN 'L' END + ''', ''' + CAST(DATEDIFF(hh,@CurrentCleanupDate,SYSDATETIME()) + 1 AS NVARCHAR) + 'h'', ' + ISNULL('''' + REPLACE(@EncryptionKey,'''','''''') + '''','NULL') + ' IF @ReturnCode <> 0 RAISERROR(''Error deleting SQLBackup backup files.'', 16, 1)';
END;
IF @BackupSoftware = 'SQLSAFE'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'xp_ss_delete';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_ss_delete @filename = N''' + REPLACE(@CurrentDirectoryPath,'''','''''') + '\*.' + @CurrentFileExtension + ''', @age = ''' + CAST(DATEDIFF(mi,@CurrentCleanupDate,SYSDATETIME()) + 1 AS NVARCHAR) + 'Minutes'' IF @ReturnCode <> 0 RAISERROR(''Error deleting SQLsafe backup files.'', 16, 1)';
END;
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseContext, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 1, @DatabaseName = @CurrentDatabaseName, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
UPDATE @CurrentDirectories
SET CleanupCompleted = 1,
CleanupOutput = @CurrentCommandOutput
WHERE [Id] = @CurrentDirectoryID;
SET @CurrentDirectoryID = NULL;
SET @CurrentDirectoryPath = NULL;
SET @CurrentCleanupDate = NULL;
SET @CurrentDatabaseContext = NULL;
SET @CurrentCommand = NULL;
SET @CurrentCommandOutput = NULL;
SET @CurrentCommandType = NULL;
END;
END;
-- Perform a backup
IF NOT EXISTS (SELECT * FROM @CurrentDirectories WHERE DirectoryPath <> 'NUL' AND DirectoryPath NOT IN(SELECT DirectoryPath FROM @Directories) AND (CreateOutput <> 0 OR CreateOutput IS NULL))
OR @HostPlatform = 'Linux'
BEGIN
IF @BackupSoftware IS NULL
BEGIN
SET @CurrentDatabaseContext = 'master';
SELECT @CurrentCommandType = CASE
WHEN @CurrentBackupType IN('DIFF','FULL') THEN 'BACKUP_DATABASE'
WHEN @CurrentBackupType = 'LOG' THEN 'BACKUP_LOG'
END;
SELECT @CurrentCommand = CASE
WHEN @CurrentBackupType IN('DIFF','FULL') THEN 'BACKUP DATABASE ' + QUOTENAME(@CurrentDatabaseName)
WHEN @CurrentBackupType = 'LOG' THEN 'BACKUP LOG ' + QUOTENAME(@CurrentDatabaseName)
END;
IF @ReadWriteFileGroups = 'Y' AND @CurrentDatabaseName <> 'master' SET @CurrentCommand += ' READ_WRITE_FILEGROUPS';
SET @CurrentCommand += ' TO';
SELECT @CurrentCommand += ' ' + [Type] + ' = N''' + REPLACE(FilePath,'''','''''') + '''' + CASE WHEN ROW_NUMBER() OVER (ORDER BY FilePath ASC) <> @CurrentNumberOfFiles THEN ',' ELSE '' END
FROM @CurrentFiles
WHERE [mirror] = 0
ORDER BY FilePath ASC;
IF EXISTS(SELECT * FROM @CurrentFiles WHERE [mirror] = 1)
BEGIN
SET @CurrentCommand += ' MIRROR TO';
SELECT @CurrentCommand += ' ' + [Type] + ' = N''' + REPLACE(FilePath,'''','''''') + '''' + CASE WHEN ROW_NUMBER() OVER (ORDER BY FilePath ASC) <> @CurrentNumberOfFiles THEN ',' ELSE '' END
FROM @CurrentFiles
WHERE [mirror] = 1
ORDER BY FilePath ASC;
END;
SET @CurrentCommand += ' WITH ';
IF @Checksum = 'Y' SET @CurrentCommand += 'CHECKSUM';
IF @Checksum = 'N' SET @CurrentCommand += 'NO_CHECKSUM';
IF @Version >= 10
BEGIN
SET @CurrentCommand += CASE WHEN @Compress = 'Y' AND (@CurrentIsEncrypted = 0 OR (@CurrentIsEncrypted = 1 AND ((@Version >= 13 AND @CurrentMaxTransferSize >= 65537) OR @Version >= 15.0404316 OR SERVERPROPERTY('EngineEdition') = 8))) THEN ', COMPRESSION' ELSE ', NO_COMPRESSION' END;
END;
IF @Compress = 'Y' AND @CompressionAlgorithm IS NOT NULL
BEGIN
SET @CurrentCommand += ' (ALGORITHM = ' + @CompressionAlgorithm + CASE WHEN @CompressionLevel IS NOT NULL THEN ', LEVEL = ' + @CompressionLevel ELSE '' END + ')';
END;
IF @CurrentBackupType = 'DIFF' SET @CurrentCommand += ', DIFFERENTIAL';
IF EXISTS(SELECT * FROM @CurrentFiles WHERE [mirror] = 1)
BEGIN
SET @CurrentCommand += ', FORMAT';
END;
IF @CopyOnly = 'Y' SET @CurrentCommand += ', COPY_ONLY';
IF @NoRecovery = 'Y' AND @CurrentBackupType = 'LOG' SET @CurrentCommand += ', NORECOVERY';
IF @Init = 'Y' SET @CurrentCommand += ', INIT';
IF @Format = 'Y' SET @CurrentCommand += ', FORMAT';
IF @BlockSize IS NOT NULL SET @CurrentCommand += ', BLOCKSIZE = ' + CAST(@BlockSize AS NVARCHAR);
IF @BufferCount IS NOT NULL SET @CurrentCommand += ', BUFFERCOUNT = ' + CAST(@BufferCount AS NVARCHAR);
IF @CurrentMaxTransferSize IS NOT NULL SET @CurrentCommand += ', MAXTRANSFERSIZE = ' + CAST(@CurrentMaxTransferSize AS NVARCHAR);
IF @Description IS NOT NULL SET @CurrentCommand += ', DESCRIPTION = N''' + REPLACE(@Description,'''','''''') + '''';
IF @BackupSetName IS NOT NULL SET @CurrentCommand += ', NAME = N''' + REPLACE(@BackupSetName,'''','''''') + '''';
IF @Stats IS NOT NULL SET @CurrentCommand += ', STATS = ' + CAST(@Stats AS NVARCHAR);
IF @BackupOptions IS NOT NULL SET @CurrentCommand += ', BACKUP_OPTIONS = N''' + REPLACE(@BackupOptions,'''','''''') + '''';
IF @Encrypt = 'Y' SET @CurrentCommand += ', ENCRYPTION (ALGORITHM = ' + UPPER(@EncryptionAlgorithm) + ', ';
IF @Encrypt = 'Y' AND @ServerCertificate IS NOT NULL SET @CurrentCommand += 'SERVER CERTIFICATE = ' + QUOTENAME(@ServerCertificate);
IF @Encrypt = 'Y' AND @ServerAsymmetricKey IS NOT NULL SET @CurrentCommand += 'SERVER ASYMMETRIC KEY = ' + QUOTENAME(@ServerAsymmetricKey);
IF @Encrypt = 'Y' SET @CurrentCommand += ')';
IF @URL IS NOT NULL AND @Credential IS NOT NULL SET @CurrentCommand += ', CREDENTIAL = N''' + REPLACE(@Credential,'''','''''') + '''';
IF @ExpireDate IS NOT NULL SET @CurrentCommand += ', EXPIREDATE = ''' + CONVERT(NVARCHAR, @ExpireDate, 21) + '''';
IF @RetainDays IS NOT NULL SET @CurrentCommand += ', RETAINDAYS = ' + CAST(@RetainDays AS NVARCHAR);
END;
IF @BackupSoftware = 'LITESPEED'
BEGIN
SET @CurrentDatabaseContext = 'master';
SELECT @CurrentCommandType = CASE
WHEN @CurrentBackupType IN('DIFF','FULL') THEN 'xp_backup_database'
WHEN @CurrentBackupType = 'LOG' THEN 'xp_backup_log'
END;
SELECT @CurrentCommand = CASE
WHEN @CurrentBackupType IN('DIFF','FULL') THEN 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_backup_database @database = N''' + REPLACE(@CurrentDatabaseName,'''','''''') + ''''
WHEN @CurrentBackupType = 'LOG' THEN 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_backup_log @database = N''' + REPLACE(@CurrentDatabaseName,'''','''''') + ''''
END;
SELECT @CurrentCommand += ', @filename = N''' + REPLACE(FilePath,'''','''''') + ''''
FROM @CurrentFiles
WHERE [mirror] = 0
ORDER BY FilePath ASC;
IF EXISTS(SELECT * FROM @CurrentFiles WHERE [mirror] = 1)
BEGIN
SELECT @CurrentCommand += ', @mirror = N''' + REPLACE(FilePath,'''','''''') + ''''
FROM @CurrentFiles
WHERE [mirror] = 1
ORDER BY FilePath ASC;
END;
SET @CurrentCommand += ', @with = ''';
IF @Checksum = 'Y' SET @CurrentCommand += 'CHECKSUM';
IF @Checksum = 'N' SET @CurrentCommand += 'NO_CHECKSUM';
IF @CurrentBackupType = 'DIFF' SET @CurrentCommand += ', DIFFERENTIAL';
IF @CopyOnly = 'Y' SET @CurrentCommand += ', COPY_ONLY';
IF @NoRecovery = 'Y' AND @CurrentBackupType = 'LOG' SET @CurrentCommand += ', NORECOVERY';
IF @BlockSize IS NOT NULL SET @CurrentCommand += ', BLOCKSIZE = ' + CAST(@BlockSize AS NVARCHAR);
SET @CurrentCommand += '''';
IF @ReadWriteFileGroups = 'Y' AND @CurrentDatabaseName <> 'master' SET @CurrentCommand += ', @read_write_filegroups = 1';
IF @CompressionLevelNumeric IS NOT NULL SET @CurrentCommand += ', @compressionlevel = ' + CAST(@CompressionLevelNumeric AS NVARCHAR);
IF @AdaptiveCompression IS NOT NULL SET @CurrentCommand += ', @adaptivecompression = ''' + CASE WHEN @AdaptiveCompression = 'SIZE' THEN 'Size' WHEN @AdaptiveCompression = 'SPEED' THEN 'Speed' END + '''';
IF @BufferCount IS NOT NULL SET @CurrentCommand += ', @buffercount = ' + CAST(@BufferCount AS NVARCHAR);
IF @CurrentMaxTransferSize IS NOT NULL SET @CurrentCommand += ', @maxtransfersize = ' + CAST(@CurrentMaxTransferSize AS NVARCHAR);
IF @Threads IS NOT NULL SET @CurrentCommand += ', @threads = ' + CAST(@Threads AS NVARCHAR);
IF @Init = 'Y' SET @CurrentCommand += ', @init = 1';
IF @Format = 'Y' SET @CurrentCommand += ', @format = 1';
IF @Throttle IS NOT NULL SET @CurrentCommand += ', @throttle = ' + CAST(@Throttle AS NVARCHAR);
IF @Description IS NOT NULL SET @CurrentCommand += ', @desc = N''' + REPLACE(@Description,'''','''''') + '''';
IF @ObjectLevelRecoveryMap = 'Y' SET @CurrentCommand += ', @olrmap = 1';
IF @ExpireDate IS NOT NULL SET @CurrentCommand += ', @expiration = ''' + CONVERT(NVARCHAR, @ExpireDate, 21) + '''';
IF @RetainDays IS NOT NULL SET @CurrentCommand += ', @retaindays = ' + CAST(@RetainDays AS NVARCHAR);
IF @EncryptionAlgorithm IS NOT NULL SET @CurrentCommand += ', @cryptlevel = ' + CASE
WHEN @EncryptionAlgorithm = 'RC2_40' THEN '0'
WHEN @EncryptionAlgorithm = 'RC2_56' THEN '1'
WHEN @EncryptionAlgorithm = 'RC2_112' THEN '2'
WHEN @EncryptionAlgorithm = 'RC2_128' THEN '3'
WHEN @EncryptionAlgorithm = 'TRIPLE_DES_3KEY' THEN '4'
WHEN @EncryptionAlgorithm = 'RC4_128' THEN '5'
WHEN @EncryptionAlgorithm = 'AES_128' THEN '6'
WHEN @EncryptionAlgorithm = 'AES_192' THEN '7'
WHEN @EncryptionAlgorithm = 'AES_256' THEN '8'
END;
IF @EncryptionKey IS NOT NULL SET @CurrentCommand += ', @encryptionkey = N''' + REPLACE(@EncryptionKey,'''','''''') + '''';
SET @CurrentCommand += ' IF @ReturnCode <> 0 RAISERROR(''Error performing LiteSpeed backup.'', 16, 1)';
END;
IF @BackupSoftware = 'SQLBACKUP'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'sqlbackup';
SELECT @CurrentCommand = CASE
WHEN @CurrentBackupType IN('DIFF','FULL') THEN 'BACKUP DATABASE ' + QUOTENAME(@CurrentDatabaseName)
WHEN @CurrentBackupType = 'LOG' THEN 'BACKUP LOG ' + QUOTENAME(@CurrentDatabaseName)
END;
IF @ReadWriteFileGroups = 'Y' AND @CurrentDatabaseName <> 'master' SET @CurrentCommand += ' READ_WRITE_FILEGROUPS';
SET @CurrentCommand += ' TO';
SELECT @CurrentCommand += ' DISK = N''' + REPLACE(FilePath,'''','''''') + '''' + CASE WHEN ROW_NUMBER() OVER (ORDER BY FilePath ASC) <> @CurrentNumberOfFiles THEN ',' ELSE '' END
FROM @CurrentFiles
WHERE [mirror] = 0
ORDER BY FilePath ASC;
SET @CurrentCommand += ' WITH ';
IF EXISTS(SELECT * FROM @CurrentFiles WHERE [mirror] = 1)
BEGIN
SET @CurrentCommand += ' MIRRORFILE' + ' = N''' + REPLACE((SELECT FilePath FROM @CurrentFiles WHERE [mirror] = 1),'''','''''') + ''', ';
END;
IF @Checksum = 'Y' SET @CurrentCommand += 'CHECKSUM';
IF @Checksum = 'N' SET @CurrentCommand += 'NO_CHECKSUM';
IF @CurrentBackupType = 'DIFF' SET @CurrentCommand += ', DIFFERENTIAL';
IF @CopyOnly = 'Y' SET @CurrentCommand += ', COPY_ONLY';
IF @NoRecovery = 'Y' AND @CurrentBackupType = 'LOG' SET @CurrentCommand += ', NORECOVERY';
IF @Init = 'Y' SET @CurrentCommand += ', INIT';
IF @Format = 'Y' SET @CurrentCommand += ', FORMAT';
IF @CompressionLevelNumeric IS NOT NULL SET @CurrentCommand += ', COMPRESSION = ' + CAST(@CompressionLevelNumeric AS NVARCHAR);
IF @Threads IS NOT NULL SET @CurrentCommand += ', THREADCOUNT = ' + CAST(@Threads AS NVARCHAR);
IF @CurrentMaxTransferSize IS NOT NULL SET @CurrentCommand += ', MAXTRANSFERSIZE = ' + CAST(@CurrentMaxTransferSize AS NVARCHAR);
IF @Description IS NOT NULL SET @CurrentCommand += ', DESCRIPTION = N''' + REPLACE(@Description,'''','''''') + '''';
IF @EncryptionAlgorithm IS NOT NULL SET @CurrentCommand += ', KEYSIZE = ' + CASE
WHEN @EncryptionAlgorithm = 'AES_128' THEN '128'
WHEN @EncryptionAlgorithm = 'AES_256' THEN '256'
END;
IF @EncryptionKey IS NOT NULL SET @CurrentCommand += ', PASSWORD = N''' + REPLACE(@EncryptionKey,'''','''''') + '''';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.sqlbackup N''-SQL "' + REPLACE(@CurrentCommand,'''','''''') + '"''' + ' IF @ReturnCode <> 0 RAISERROR(''Error performing SQLBackup backup.'', 16, 1)';
END;
IF @BackupSoftware = 'SQLSAFE'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'xp_ss_backup';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_ss_backup @database = N''' + REPLACE(@CurrentDatabaseName,'''','''''') + '''';
SELECT @CurrentCommand += ', ' + CASE WHEN ROW_NUMBER() OVER (ORDER BY FilePath ASC) = 1 THEN '@filename' ELSE '@backupfile' END + ' = N''' + REPLACE(FilePath,'''','''''') + ''''
FROM @CurrentFiles
WHERE [mirror] = 0
ORDER BY FilePath ASC;
SELECT @CurrentCommand += ', @mirrorfile = N''' + REPLACE(FilePath,'''','''''') + ''''
FROM @CurrentFiles
WHERE [mirror] = 1
ORDER BY FilePath ASC;
SET @CurrentCommand += ', @backuptype = ' + CASE WHEN @CurrentBackupType = 'FULL' THEN '''Full''' WHEN @CurrentBackupType = 'DIFF' THEN '''Differential''' WHEN @CurrentBackupType = 'LOG' THEN '''Log''' END;
IF @ReadWriteFileGroups = 'Y' AND @CurrentDatabaseName <> 'master' SET @CurrentCommand += ', @readwritefilegroups = 1';
SET @CurrentCommand += ', @checksum = ' + CASE WHEN @Checksum = 'Y' THEN '1' WHEN @Checksum = 'N' THEN '0' END;
SET @CurrentCommand += ', @copyonly = ' + CASE WHEN @CopyOnly = 'Y' THEN '1' WHEN @CopyOnly = 'N' THEN '0' END;
IF @CompressionLevelNumeric IS NOT NULL SET @CurrentCommand += ', @compressionlevel = ' + CAST(@CompressionLevelNumeric AS NVARCHAR);
IF @Threads IS NOT NULL SET @CurrentCommand += ', @threads = ' + CAST(@Threads AS NVARCHAR);
IF @Init = 'Y' SET @CurrentCommand += ', @overwrite = 1';
IF @Description IS NOT NULL SET @CurrentCommand += ', @desc = N''' + REPLACE(@Description,'''','''''') + '''';
IF @EncryptionAlgorithm IS NOT NULL SET @CurrentCommand += ', @encryptiontype = N''' + CASE
WHEN @EncryptionAlgorithm = 'AES_128' THEN 'AES128'
WHEN @EncryptionAlgorithm = 'AES_256' THEN 'AES256'
END + '''';
IF @EncryptionKey IS NOT NULL SET @CurrentCommand += ', @encryptedbackuppassword = N''' + REPLACE(@EncryptionKey,'''','''''') + '''';
SET @CurrentCommand += ' IF @ReturnCode <> 0 RAISERROR(''Error performing SQLsafe backup.'', 16, 1)';
END;
IF @BackupSoftware = 'DATA_DOMAIN_BOOST'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'emc_run_backup';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.emc_run_backup ''';
SET @CurrentCommand += ' -c ' + CASE WHEN @Cluster IS NOT NULL AND @CurrentAvailabilityGroup IS NOT NULL THEN @Cluster ELSE CAST(SERVERPROPERTY('MachineName') AS NVARCHAR) END;
SET @CurrentCommand += ' -l ' + CASE
WHEN @CurrentBackupType = 'FULL' THEN 'full'
WHEN @CurrentBackupType = 'DIFF' THEN 'diff'
WHEN @CurrentBackupType = 'LOG' THEN 'incr'
END;
IF @NoRecovery = 'Y' SET @CurrentCommand += ' -H';
IF @CleanupTime IS NOT NULL SET @CurrentCommand += ' -y +' + CAST(@CleanupTime/24 + CASE WHEN @CleanupTime%24 > 0 THEN 1 ELSE 0 END AS NVARCHAR) + 'd';
IF @Checksum = 'Y' SET @CurrentCommand += ' -k';
SET @CurrentCommand += ' -S ' + CAST(@CurrentNumberOfFiles AS NVARCHAR);
IF @Description IS NOT NULL SET @CurrentCommand += ' -b "' + REPLACE(@Description,'''','''''') + '"';
IF @BufferCount IS NOT NULL SET @CurrentCommand += ' -O "BUFFERCOUNT=' + CAST(@BufferCount AS NVARCHAR) + '"';
IF @ReadWriteFileGroups = 'Y' AND @CurrentDatabaseName <> 'master' SET @CurrentCommand += ' -O "READ_WRITE_FILEGROUPS"';
IF @DataDomainBoostHost IS NOT NULL SET @CurrentCommand += ' -a "NSR_DFA_SI_DD_HOST=' + REPLACE(@DataDomainBoostHost,'''','''''') + '"';
IF @DataDomainBoostUser IS NOT NULL SET @CurrentCommand += ' -a "NSR_DFA_SI_DD_USER=' + REPLACE(@DataDomainBoostUser,'''','''''') + '"';
IF @DataDomainBoostDevicePath IS NOT NULL SET @CurrentCommand += ' -a "NSR_DFA_SI_DEVICE_PATH=' + REPLACE(@DataDomainBoostDevicePath,'''','''''') + '"';
IF @DataDomainBoostLockboxPath IS NOT NULL SET @CurrentCommand += ' -a "NSR_DFA_SI_DD_LOCKBOX_PATH=' + REPLACE(@DataDomainBoostLockboxPath,'''','''''') + '"';
SET @CurrentCommand += ' -a "NSR_SKIP_NON_BACKUPABLE_STATE_DB=TRUE"';
SET @CurrentCommand += ' -a "BACKUP_PROMOTION=NONE"';
IF @CopyOnly = 'Y' SET @CurrentCommand += ' -a "NSR_COPY_ONLY=TRUE"';
IF @BackupSetName IS NOT NULL SET @CurrentCommand += ' -N "' + REPLACE(@BackupSetName,'''','''''') + '"';
IF SERVERPROPERTY('InstanceName') IS NULL SET @CurrentCommand += ' "MSSQL';
IF SERVERPROPERTY('InstanceName') IS NOT NULL SET @CurrentCommand += ' "MSSQL$' + CAST(SERVERPROPERTY('InstanceName') AS NVARCHAR);
SET @CurrentCommand += ':' + REPLACE(REPLACE(@CurrentDatabaseName,'''',''''''),'.','\.') + '"';
SET @CurrentCommand += '''';
SET @CurrentCommand += ' IF @ReturnCode <> 0 RAISERROR(''Error performing Data Domain Boost backup.'', 16, 1)';
END;
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseContext, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 1, @DatabaseName = @CurrentDatabaseName, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
SET @CurrentBackupOutput = @CurrentCommandOutput;
END;
-- Verify the backup
IF @CurrentBackupOutput = 0 AND @Verify = 'Y'
BEGIN
WHILE (1 = 1)
BEGIN
SELECT TOP 1 @CurrentBackupSetID = [Id],
@CurrentIsMirror = [mirror]
FROM @CurrentBackupSet
WHERE VerifyCompleted = 0
ORDER BY [Id] ASC;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
IF @BackupSoftware IS NULL
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'RESTORE_VERIFYONLY';
SET @CurrentCommand = 'RESTORE VERIFYONLY FROM';
SELECT @CurrentCommand += ' ' + [Type] + ' = N''' + REPLACE(FilePath,'''','''''') + '''' + CASE WHEN ROW_NUMBER() OVER (ORDER BY FilePath ASC) <> @CurrentNumberOfFiles THEN ',' ELSE '' END
FROM @CurrentFiles
WHERE [mirror] = @CurrentIsMirror
ORDER BY FilePath ASC;
SET @CurrentCommand += ' WITH ';
IF @Checksum = 'Y' SET @CurrentCommand += 'CHECKSUM';
IF @Checksum = 'N' SET @CurrentCommand += 'NO_CHECKSUM';
IF @Stats IS NOT NULL SET @CurrentCommand += ', STATS = ' + CAST(@Stats AS NVARCHAR);
IF @BackupOptions IS NOT NULL SET @CurrentCommand += ', RESTORE_OPTIONS = N''' + REPLACE(@BackupOptions,'''','''''') + '''';
IF @URL IS NOT NULL AND @Credential IS NOT NULL SET @CurrentCommand += ', CREDENTIAL = N''' + REPLACE(@Credential,'''','''''') + '''';
END;
IF @BackupSoftware = 'LITESPEED'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'xp_restore_verifyonly';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_restore_verifyonly';
SELECT @CurrentCommand += ' @filename = N''' + REPLACE(FilePath,'''','''''') + '''' + CASE WHEN ROW_NUMBER() OVER (ORDER BY FilePath ASC) <> @CurrentNumberOfFiles THEN ',' ELSE '' END
FROM @CurrentFiles
WHERE [mirror] = @CurrentIsMirror
ORDER BY FilePath ASC;
SET @CurrentCommand += ', @with = ''';
IF @Checksum = 'Y' SET @CurrentCommand += 'CHECKSUM';
IF @Checksum = 'N' SET @CurrentCommand += 'NO_CHECKSUM';
SET @CurrentCommand += '''';
IF @EncryptionKey IS NOT NULL SET @CurrentCommand += ', @encryptionkey = N''' + REPLACE(@EncryptionKey,'''','''''') + '''';
SET @CurrentCommand += ' IF @ReturnCode <> 0 RAISERROR(''Error verifying LiteSpeed backup.'', 16, 1)';
END;
IF @BackupSoftware = 'SQLBACKUP'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'sqlbackup';
SET @CurrentCommand = 'RESTORE VERIFYONLY FROM';
SELECT @CurrentCommand += ' DISK = N''' + REPLACE(FilePath,'''','''''') + '''' + CASE WHEN ROW_NUMBER() OVER (ORDER BY FilePath ASC) <> @CurrentNumberOfFiles THEN ',' ELSE '' END
FROM @CurrentFiles
WHERE [mirror] = @CurrentIsMirror
ORDER BY FilePath ASC;
SET @CurrentCommand += ' WITH ';
IF @Checksum = 'Y' SET @CurrentCommand += 'CHECKSUM';
IF @Checksum = 'N' SET @CurrentCommand += 'NO_CHECKSUM';
IF @EncryptionKey IS NOT NULL SET @CurrentCommand += ', PASSWORD = N''' + REPLACE(@EncryptionKey,'''','''''') + '''';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.sqlbackup N''-SQL "' + REPLACE(@CurrentCommand,'''','''''') + '"''' + ' IF @ReturnCode <> 0 RAISERROR(''Error verifying SQLBackup backup.'', 16, 1)';
END;
IF @BackupSoftware = 'SQLSAFE'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'xp_ss_verify';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_ss_verify @database = N''' + REPLACE(@CurrentDatabaseName,'''','''''') + '''';
SELECT @CurrentCommand += ', ' + CASE WHEN ROW_NUMBER() OVER (ORDER BY FilePath ASC) = 1 THEN '@filename' ELSE '@backupfile' END + ' = N''' + REPLACE(FilePath,'''','''''') + ''''
FROM @CurrentFiles
WHERE [mirror] = @CurrentIsMirror
ORDER BY FilePath ASC;
SET @CurrentCommand += ' IF @ReturnCode <> 0 RAISERROR(''Error verifying SQLsafe backup.'', 16, 1)';
END;
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseContext, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 1, @DatabaseName = @CurrentDatabaseName, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
UPDATE @CurrentBackupSet
SET VerifyCompleted = 1,
VerifyOutput = @CurrentCommandOutput
WHERE [Id] = @CurrentBackupSetID;
SET @CurrentBackupSetID = NULL;
SET @CurrentIsMirror = NULL;
SET @CurrentDatabaseContext = NULL;
SET @CurrentCommand = NULL;
SET @CurrentCommandOutput = NULL;
SET @CurrentCommandType = NULL;
END;
END;
IF @CleanupMode = 'AFTER_BACKUP'
BEGIN
INSERT INTO @CurrentCleanupDates (CleanupDate, [mirror])
SELECT DATEADD(hh,-(@CleanupTime),SYSDATETIME()), 0;
IF NOT EXISTS(SELECT * FROM @CurrentCleanupDates WHERE ([mirror] = 0 OR [mirror] IS NULL) AND CleanupDate IS NULL)
BEGIN
UPDATE @CurrentDirectories
SET CleanupDate = (SELECT MIN(CleanupDate)
FROM @CurrentCleanupDates
WHERE ([mirror] = 0 OR [mirror] IS NULL)),
CleanupMode = 'AFTER_BACKUP'
WHERE [mirror] = 0;
END;
END;
IF @MirrorCleanupMode = 'AFTER_BACKUP'
BEGIN
INSERT INTO @CurrentCleanupDates (CleanupDate, [mirror])
SELECT DATEADD(hh,-(@MirrorCleanupTime),SYSDATETIME()), 1;
IF NOT EXISTS(SELECT * FROM @CurrentCleanupDates WHERE ([mirror] = 1 OR [mirror] IS NULL) AND CleanupDate IS NULL)
BEGIN
UPDATE @CurrentDirectories
SET CleanupDate = (SELECT MIN(CleanupDate)
FROM @CurrentCleanupDates
WHERE ([mirror] = 1 OR [mirror] IS NULL)),
CleanupMode = 'AFTER_BACKUP'
WHERE [mirror] = 1;
END;
END;
-- Delete old backup files, after backup
IF ((@CurrentBackupOutput = 0 AND @Verify = 'N')
OR (@CurrentBackupOutput = 0 AND @Verify = 'Y' AND NOT EXISTS (SELECT * FROM @CurrentBackupSet WHERE VerifyOutput <> 0 OR VerifyOutput IS NULL)))
AND (@BackupSoftware <> 'DATA_DOMAIN_BOOST' OR @BackupSoftware IS NULL)
AND @CurrentBackupType = @BackupType
BEGIN
WHILE (1 = 1)
BEGIN
SELECT TOP 1 @CurrentDirectoryID = [Id],
@CurrentDirectoryPath = DirectoryPath,
@CurrentCleanupDate = CleanupDate
FROM @CurrentDirectories
WHERE CleanupDate IS NOT NULL
AND CleanupMode = 'AFTER_BACKUP'
AND CleanupCompleted = 0
ORDER BY [Id] ASC;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
IF @BackupSoftware IS NULL
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'xp_delete_file';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_delete_file 0, N''' + REPLACE(@CurrentDirectoryPath,'''','''''') + ''', ''' + @CurrentFileExtension + ''', ''' + CONVERT(NVARCHAR(19),@CurrentCleanupDate,126) + ''' IF @ReturnCode <> 0 RAISERROR(''Error deleting files.'', 16, 1)';
END;
IF @BackupSoftware = 'LITESPEED'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'xp_slssqlmaint';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_slssqlmaint N''-MAINTDEL -DELFOLDER "' + REPLACE(@CurrentDirectoryPath,'''','''''') + '" -DELEXTENSION "' + @CurrentFileExtension + '" -DELUNIT "' + CAST(DATEDIFF(mi,@CurrentCleanupDate,SYSDATETIME()) + 1 AS NVARCHAR) + '" -DELUNITTYPE "minutes" -DELUSEAGE'' IF @ReturnCode <> 0 RAISERROR(''Error deleting LiteSpeed backup files.'', 16, 1)';
END;
IF @BackupSoftware = 'SQLBACKUP'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'sqbutility';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.sqbutility 1032, N''' + REPLACE(@CurrentDatabaseName,'''','''''') + ''', N''' + REPLACE(@CurrentDirectoryPath,'''','''''') + ''', ''' + CASE WHEN @CurrentBackupType = 'FULL' THEN 'D' WHEN @CurrentBackupType = 'DIFF' THEN 'I' WHEN @CurrentBackupType = 'LOG' THEN 'L' END + ''', ''' + CAST(DATEDIFF(hh,@CurrentCleanupDate,SYSDATETIME()) + 1 AS NVARCHAR) + 'h'', ' + ISNULL('''' + REPLACE(@EncryptionKey,'''','''''') + '''','NULL') + ' IF @ReturnCode <> 0 RAISERROR(''Error deleting SQLBackup backup files.'', 16, 1)';
END;
IF @BackupSoftware = 'SQLSAFE'
BEGIN
SET @CurrentDatabaseContext = 'master';
SET @CurrentCommandType = 'xp_ss_delete';
SET @CurrentCommand = 'DECLARE @ReturnCode int EXECUTE @ReturnCode = dbo.xp_ss_delete @filename = N''' + REPLACE(@CurrentDirectoryPath,'''','''''') + '\*.' + @CurrentFileExtension + ''', @age = ''' + CAST(DATEDIFF(mi,@CurrentCleanupDate,SYSDATETIME()) + 1 AS NVARCHAR) + 'Minutes'' IF @ReturnCode <> 0 RAISERROR(''Error deleting SQLsafe backup files.'', 16, 1)';
END;
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseContext, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 1, @DatabaseName = @CurrentDatabaseName, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
UPDATE @CurrentDirectories
SET CleanupCompleted = 1,
CleanupOutput = @CurrentCommandOutput
WHERE [Id] = @CurrentDirectoryID;
SET @CurrentDirectoryID = NULL;
SET @CurrentDirectoryPath = NULL;
SET @CurrentCleanupDate = NULL;
SET @CurrentDatabaseContext = NULL;
SET @CurrentCommand = NULL;
SET @CurrentCommandOutput = NULL;
SET @CurrentCommandType = NULL;
END;
END;
END; -- End of database backup check
IF @CurrentDatabaseState = 'SUSPECT'
BEGIN
SET @ErrorMessage = 'The database ' + QUOTENAME(@CurrentDatabaseName) + ' is in a SUSPECT state.';
RAISERROR('%s',16,1,@ErrorMessage) WITH NOWAIT;
SET @Error = @@ERROR;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
END;
-- Update that the database is completed
IF @DatabasesInParallel = 'Y'
BEGIN
UPDATE [dbo].QueueDatabase
SET DatabaseEndTime = SYSDATETIME()
WHERE QueueID = @QueueID
AND DatabaseName = @CurrentDatabaseName;
END;
ELSE
BEGIN
UPDATE @tmpDatabases
SET Completed = 1
WHERE Selected = 1
AND Completed = 0
AND [Id] = @CurrentDBID;
END;
-- Clear variables
SET @CurrentDBID = NULL;
SET @CurrentDatabaseName = NULL;
SET @CurrentDatabase_sp_executesql = NULL;
SET @CurrentUserAccess = NULL;
SET @CurrentIsReadOnly = NULL;
SET @CurrentDatabaseState = NULL;
SET @CurrentInStandby = NULL;
SET @CurrentRecoveryModel = NULL;
SET @CurrentIsEncrypted = NULL;
SET @CurrentDatabaseSize = NULL;
SET @CurrentBackupType = NULL;
SET @CurrentMaxTransferSize = NULL;
SET @CurrentNumberOfFiles = NULL;
SET @CurrentFileExtension = NULL;
SET @CurrentFileNumber = NULL;
SET @CurrentDifferentialBaseLSN = NULL;
SET @CurrentDifferentialBaseIsSnapshot = NULL;
SET @CurrentLogLSN = NULL;
SET @CurrentLatestBackup = NULL;
SET @CurrentDatabaseNameFS = NULL;
SET @CurrentDirectoryStructure = NULL;
SET @CurrentDatabaseFileName = NULL;
SET @CurrentMaxFilePathLength = NULL;
SET @CurrentDate = NULL;
SET @CurrentDateUTC = NULL;
SET @CurrentCleanupDate = NULL;
SET @CurrentReplicaID = NULL;
SET @CurrentAvailabilityGroupID = NULL;
SET @CurrentAvailabilityGroup = NULL;
SET @CurrentAvailabilityGroupRole = NULL;
SET @CurrentAvailabilityGroupDatabaseReplicaSynchronizationState = NULL;
SET @CurrentAvailabilityGroupDatabaseReplicaSynchronizationHealth = NULL;
SET @CurrentAvailabilityGroupBackupPreference = NULL;
SET @CurrentIsPreferredBackupReplica = NULL;
SET @CurrentDatabaseMirroringRole = NULL;
SET @CurrentLogShippingRole = NULL;
SET @CurrentBackupOperationSupportedOnSecondaryReplicas = NULL;
SET @CurrentLastLogBackup = NULL;
SET @CurrentLogSizeSinceLastLogBackup = NULL;
SET @CurrentAllocatedExtentPageCount = NULL;
SET @CurrentModifiedExtentPageCount = NULL;
SET @CurrentDatabaseContext = NULL;
SET @CurrentCommand = NULL;
SET @CurrentCommandOutput = NULL;
SET @CurrentCommandType = NULL;
SET @CurrentBackupOutput = NULL;
DELETE FROM @CurrentDirectories;
DELETE FROM @CurrentURLs;
DELETE FROM @CurrentFiles;
DELETE FROM @CurrentCleanupDates;
DELETE FROM @CurrentBackupSet;
END; -- End of database loop
----------------------------------------------------------------------------------------------------
--// Log completing information //--
----------------------------------------------------------------------------------------------------
Logging:;
SET @EndMessage = 'Date and time: ' + CONVERT(NVARCHAR,SYSDATETIME(),120);
RAISERROR('%s',10,1,@EndMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF @ReturnCode <> 0
BEGIN
RETURN @ReturnCode;
END;
----------------------------------------------------------------------------------------------------
END;
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
IF NOT EXISTS (SELECT * FROM [sys].[objects] WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[DatabaseIntegrityCheck]') AND TYPE IN (N'P', N'PC'))
BEGIN
EXECUTE [dbo].sp_executesql @statement = N'CREATE PROCEDURE [dbo].[DatabaseIntegrityCheck] AS';
END;
GO
ALTER PROCEDURE [dbo].[DatabaseIntegrityCheck]
@Databases NVARCHAR(MAX) = NULL,
@CheckCommands NVARCHAR(MAX) = 'CHECKDB',
@PhysicalOnly NVARCHAR(MAX) = 'N',
@DataPurity NVARCHAR(MAX) = 'N',
@NoIndex NVARCHAR(MAX) = 'N',
@ExtendedLogicalChecks NVARCHAR(MAX) = 'N',
@NoInformationalMessages NVARCHAR(MAX) = 'N',
@TabLock NVARCHAR(MAX) = 'N',
@FileGroups NVARCHAR(MAX) = NULL,
@Objects NVARCHAR(MAX) = NULL,
@MaxDOP INT = NULL,
@AvailabilityGroups NVARCHAR(MAX) = NULL,
@AvailabilityGroupReplicas NVARCHAR(MAX) = 'ALL',
@Updateability NVARCHAR(MAX) = 'ALL',
@TimeLimit INT = NULL,
@LockTimeout INT = NULL,
@LockMessageSeverity INT = 16,
@StringDelimiter NVARCHAR(MAX) = ',',
@DatabaseOrder NVARCHAR(MAX) = NULL,
@DatabasesInParallel NVARCHAR(MAX) = 'N',
@LogToTable NVARCHAR(MAX) = 'N',
@Execute NVARCHAR(MAX) = 'Y'
AS
BEGIN
----------------------------------------------------------------------------------------------------
--// Source: https://ola.hallengren.com //--
--// License: https://ola.hallengren.com/license.html //--
--// GitHub: https://github.com/olahallengren/sql-server-maintenance-solution //--
--// Version: 2025-07-22 16:49:16 //--
----------------------------------------------------------------------------------------------------
SET NOCOUNT ON;
DECLARE @StartMessage NVARCHAR(MAX);
DECLARE @EndMessage NVARCHAR(MAX);
DECLARE @DatabaseMessage NVARCHAR(MAX);
DECLARE @ErrorMessage NVARCHAR(MAX);
DECLARE @Severity INT;
DECLARE @StartTime DATETIME2 = SYSDATETIME();
DECLARE @SchemaName NVARCHAR(MAX) = OBJECT_SCHEMA_NAME(@@PROCID);
DECLARE @ObjectName NVARCHAR(MAX) = OBJECT_NAME(@@PROCID);
DECLARE @VersionTimestamp NVARCHAR(MAX) = SUBSTRING(OBJECT_DEFINITION(@@PROCID),CHARINDEX('--// Version: ',OBJECT_DEFINITION(@@PROCID)) + LEN('--// Version: ') + 1, 19);
DECLARE @Parameters NVARCHAR(MAX);
DECLARE @HostPlatform NVARCHAR(MAX);
DECLARE @QueueID INT;
DECLARE @QueueStartTime DATETIME2;
DECLARE @CurrentDBID INT;
DECLARE @CurrentDatabaseName NVARCHAR(MAX);
DECLARE @CurrentDatabase_sp_executesql NVARCHAR(MAX);
DECLARE @CurrentUserAccess NVARCHAR(MAX);
DECLARE @CurrentIsReadOnly BIT;
DECLARE @CurrentDatabaseState NVARCHAR(MAX);
DECLARE @CurrentInStandby BIT;
DECLARE @CurrentRecoveryModel NVARCHAR(MAX);
DECLARE @CurrentReplicaID UNIQUEIDENTIFIER;
DECLARE @CurrentAvailabilityGroupID UNIQUEIDENTIFIER;
DECLARE @CurrentAvailabilityGroup NVARCHAR(MAX);
DECLARE @CurrentAvailabilityGroupRole NVARCHAR(MAX);
DECLARE @CurrentAvailabilityGroupBackupPreference NVARCHAR(MAX);
DECLARE @CurrentSecondaryRoleAllowConnections NVARCHAR(MAX);
DECLARE @CurrentIsPreferredBackupReplica BIT;
DECLARE @CurrentDatabaseMirroringRole NVARCHAR(MAX);
DECLARE @CurrentFGID INT;
DECLARE @CurrentFileGroupID INT;
DECLARE @CurrentFileGroupName NVARCHAR(MAX);
DECLARE @CurrentFileGroupExists BIT;
DECLARE @CurrentOID INT;
DECLARE @CurrentSchemaID INT;
DECLARE @CurrentSchemaName NVARCHAR(MAX);
DECLARE @CurrentObjectID INT;
DECLARE @CurrentObjectName NVARCHAR(MAX);
DECLARE @CurrentObjectType NVARCHAR(MAX);
DECLARE @CurrentObjectExists BIT;
DECLARE @CurrentDatabaseContext NVARCHAR(MAX);
DECLARE @CurrentCommand NVARCHAR(MAX);
DECLARE @CurrentCommandOutput INT;
DECLARE @CurrentCommandType NVARCHAR(MAX);
DECLARE @Errors TABLE ([Id] INT IDENTITY PRIMARY KEY,
[Message] NVARCHAR(MAX) NOT NULL,
[severity] INT NOT NULL,
[State] INT);
DECLARE @CurrentMessage NVARCHAR(MAX);
DECLARE @CurrentSeverity INT;
DECLARE @CurrentState INT;
DECLARE @tmpDatabases TABLE ([Id] INT IDENTITY,
DatabaseName NVARCHAR(MAX),
DatabaseType NVARCHAR(MAX),
AvailabilityGroup BIT,
[Snapshot] BIT,
StartPosition INT,
LastCommandTime DATETIME2,
DatabaseSize BIGINT,
LastGoodCheckDbTime DATETIME2,
[Order] INT,
Selected BIT,
Completed BIT,
PRIMARY KEY(Selected, Completed, [Order], [Id]));
DECLARE @tmpAvailabilityGroups TABLE ([Id] INT IDENTITY PRIMARY KEY,
AvailabilityGroupName NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @tmpDatabasesAvailabilityGroups TABLE (DatabaseName NVARCHAR(MAX),
AvailabilityGroupName NVARCHAR(MAX));
DECLARE @tmpFileGroups TABLE ([Id] INT IDENTITY,
FileGroupID INT,
FileGroupName NVARCHAR(MAX),
StartPosition INT,
[Order] INT,
Selected BIT,
Completed BIT,
PRIMARY KEY(Selected, Completed, [Order], [Id]));
DECLARE @tmpObjects TABLE ([Id] INT IDENTITY,
SchemaID INT,
SchemaName NVARCHAR(MAX),
[objectid] INT,
ObjectName NVARCHAR(MAX),
ObjectType NVARCHAR(MAX),
StartPosition INT,
[Order] INT,
Selected BIT,
Completed BIT,
PRIMARY KEY(Selected, Completed, [Order], [Id]));
DECLARE @SelectedDatabases TABLE (DatabaseName NVARCHAR(MAX),
DatabaseType NVARCHAR(MAX),
AvailabilityGroup NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @SelectedAvailabilityGroups TABLE (AvailabilityGroupName NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @SelectedFileGroups TABLE (DatabaseName NVARCHAR(MAX),
FileGroupName NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @SelectedObjects TABLE (DatabaseName NVARCHAR(MAX),
SchemaName NVARCHAR(MAX),
ObjectName NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @SelectedCheckCommands TABLE (CheckCommand NVARCHAR(MAX));
DECLARE @Error INT = 0;
DECLARE @ReturnCode INT = 0;
DECLARE @EmptyLine NVARCHAR(MAX) = CHAR(9);
DECLARE @Version NUMERIC(18,10) = CAST(LEFT(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)),CHARINDEX('.',CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX))) - 1) + '.' + REPLACE(RIGHT(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)), LEN(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX))) - CHARINDEX('.',CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)))),'.','') AS NUMERIC(18,10));
IF @Version >= 14
BEGIN
SELECT @HostPlatform = [host_platform]
FROM [sys].[dm_os_host_info];
END;
ELSE
BEGIN
SET @HostPlatform = 'Windows';
END;
DECLARE @AmazonRDS BIT = CASE WHEN SERVERPROPERTY('EngineEdition') IN (5, 8) THEN 0 WHEN EXISTS (SELECT * FROM [sys].[databases] WHERE [name] = 'rdsadmin') AND SUSER_SNAME(0x01) = 'rdsa' THEN 1 ELSE 0 END;
----------------------------------------------------------------------------------------------------
--// Log initial information //--
----------------------------------------------------------------------------------------------------
SET @Parameters = '@Databases = ' + ISNULL('''' + REPLACE(@Databases,'''','''''') + '''','NULL');
SET @Parameters += ', @CheckCommands = ' + ISNULL('''' + REPLACE(@CheckCommands,'''','''''') + '''','NULL');
SET @Parameters += ', @PhysicalOnly = ' + ISNULL('''' + REPLACE(@PhysicalOnly,'''','''''') + '''','NULL');
SET @Parameters += ', @DataPurity = ' + ISNULL('''' + REPLACE(@DataPurity,'''','''''') + '''','NULL');
SET @Parameters += ', @NoIndex = ' + ISNULL('''' + REPLACE(@NoIndex,'''','''''') + '''','NULL');
SET @Parameters += ', @ExtendedLogicalChecks = ' + ISNULL('''' + REPLACE(@ExtendedLogicalChecks,'''','''''') + '''','NULL');
SET @Parameters += ', @NoInformationalMessages = ' + ISNULL('''' + REPLACE(@NoInformationalMessages,'''','''''') + '''','NULL');
SET @Parameters += ', @TabLock = ' + ISNULL('''' + REPLACE(@TabLock,'''','''''') + '''','NULL');
SET @Parameters += ', @FileGroups = ' + ISNULL('''' + REPLACE(@FileGroups,'''','''''') + '''','NULL');
SET @Parameters += ', @Objects = ' + ISNULL('''' + REPLACE(@Objects,'''','''''') + '''','NULL');
SET @Parameters += ', @MaxDOP = ' + ISNULL(CAST(@MaxDOP AS NVARCHAR),'NULL');
SET @Parameters += ', @AvailabilityGroups = ' + ISNULL('''' + REPLACE(@AvailabilityGroups,'''','''''') + '''','NULL');
SET @Parameters += ', @AvailabilityGroupReplicas = ' + ISNULL('''' + REPLACE(@AvailabilityGroupReplicas,'''','''''') + '''','NULL');
SET @Parameters += ', @Updateability = ' + ISNULL('''' + REPLACE(@Updateability,'''','''''') + '''','NULL');
SET @Parameters += ', @TimeLimit = ' + ISNULL(CAST(@TimeLimit AS NVARCHAR),'NULL');
SET @Parameters += ', @LockTimeout = ' + ISNULL(CAST(@LockTimeout AS NVARCHAR),'NULL');
SET @Parameters += ', @LockMessageSeverity = ' + ISNULL(CAST(@LockMessageSeverity AS NVARCHAR),'NULL');
SET @Parameters += ', @StringDelimiter = ' + ISNULL('''' + REPLACE(@StringDelimiter,'''','''''') + '''','NULL');
SET @Parameters += ', @DatabaseOrder = ' + ISNULL('''' + REPLACE(@DatabaseOrder,'''','''''') + '''','NULL');
SET @Parameters += ', @DatabasesInParallel = ' + ISNULL('''' + REPLACE(@DatabasesInParallel,'''','''''') + '''','NULL');
SET @Parameters += ', @LogToTable = ' + ISNULL('''' + REPLACE(@LogToTable,'''','''''') + '''','NULL');
SET @Parameters += ', @Execute = ' + ISNULL('''' + REPLACE(@Execute,'''','''''') + '''','NULL');
SET @StartMessage = 'Date and time: ' + CONVERT(NVARCHAR,@StartTime,120);
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Server: ' + CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(MAX));
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Version: ' + CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX));
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Edition: ' + CAST(SERVERPROPERTY('Edition') AS NVARCHAR(MAX));
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Platform: ' + @HostPlatform;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Procedure: ' + QUOTENAME(DB_NAME()) + '.' + QUOTENAME(@SchemaName) + '.' + QUOTENAME(@ObjectName);
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Parameters: ' + @Parameters;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Version: ' + @VersionTimestamp;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Source: https://ola.hallengren.com';
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
----------------------------------------------------------------------------------------------------
--// Check core requirements //--
----------------------------------------------------------------------------------------------------
IF NOT (SELECT [compatibility_level] FROM [sys].[databases] WHERE [name] = DB_NAME()) >= 90
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The database ' + QUOTENAME(DB_NAME()) + ' has to be in compatibility level 90 or higher.', 16, 1;
END;
IF NOT (SELECT [uses_ansi_nulls] FROM [sys].[sql_modules] WHERE [object_id] = @@PROCID) = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'ANSI_NULLS has to be set to ON for the stored procedure.', 16, 1;
END;
IF NOT (SELECT [uses_quoted_identifier] FROM [sys].[sql_modules] WHERE [object_id] = @@PROCID) = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'QUOTED_IDENTIFIER has to be set to ON for the stored procedure.', 16, 1;
END;
IF NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'P' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'CommandExecute')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The stored procedure CommandExecute is missing. Download https://ola.hallengren.com/scripts/CommandExecute.sql.', 16, 1;
END;
IF EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'P' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'CommandExecute' AND OBJECT_DEFINITION([objects].[object_id]) NOT LIKE '%@DatabaseContext%')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The stored procedure CommandExecute needs to be updated. Download https://ola.hallengren.com/scripts/CommandExecute.sql.', 16, 1;
END;
IF @LogToTable = 'Y' AND NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'U' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'CommandLog')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The table CommandLog is missing. Download https://ola.hallengren.com/scripts/CommandLog.sql.', 16, 1;
END;
IF @DatabasesInParallel = 'Y' AND NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'U' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'Queue')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The table Queue is missing. Download https://ola.hallengren.com/scripts/Queue.sql.', 16, 1;
END;
IF @DatabasesInParallel = 'Y' AND NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'U' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'QueueDatabase')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The table QueueDatabase is missing. Download https://ola.hallengren.com/scripts/QueueDatabase.sql.', 16, 1;
END;
IF @@TRANCOUNT <> 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The transaction count is not 0.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Select databases //--
----------------------------------------------------------------------------------------------------
SET @Databases = REPLACE(@Databases, CHAR(10), '');
SET @Databases = REPLACE(@Databases, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @Databases) > 0 SET @Databases = REPLACE(@Databases, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @Databases) > 0 SET @Databases = REPLACE(@Databases, ' ' + @StringDelimiter, @StringDelimiter);
SET @Databases = LTRIM(RTRIM(@Databases));
WITH Databases1 (StartPosition, EndPosition, DatabaseItem) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, 1), 0), LEN(@Databases) + 1) AS EndPosition,
SUBSTRING(@Databases, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, 1), 0), LEN(@Databases) + 1) - 1) AS DatabaseItem
WHERE @Databases IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, EndPosition + 1), 0), LEN(@Databases) + 1) AS EndPosition,
SUBSTRING(@Databases, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, EndPosition + 1), 0), LEN(@Databases) + 1) - EndPosition - 1) AS DatabaseItem
FROM Databases1
WHERE EndPosition < LEN(@Databases) + 1
),
Databases2 (DatabaseItem, StartPosition, Selected) AS
(
SELECT CASE WHEN DatabaseItem LIKE '-%' THEN RIGHT(DatabaseItem,LEN(DatabaseItem) - 1) ELSE DatabaseItem END AS DatabaseItem,
StartPosition,
CASE WHEN DatabaseItem LIKE '-%' THEN 0 ELSE 1 END AS Selected
FROM Databases1
),
Databases3 (DatabaseItem, DatabaseType, AvailabilityGroup, StartPosition, Selected) AS
(
SELECT CASE WHEN DatabaseItem IN('ALL_DATABASES','SYSTEM_DATABASES','USER_DATABASES','AVAILABILITY_GROUP_DATABASES') THEN '%' ELSE DatabaseItem END AS DatabaseItem,
CASE WHEN DatabaseItem = 'SYSTEM_DATABASES' THEN 'S' WHEN DatabaseItem = 'USER_DATABASES' THEN 'U' ELSE NULL END AS DatabaseType,
CASE WHEN DatabaseItem = 'AVAILABILITY_GROUP_DATABASES' THEN 1 ELSE NULL END AvailabilityGroup,
StartPosition,
Selected
FROM Databases2
),
Databases4 (DatabaseName, DatabaseType, AvailabilityGroup, StartPosition, Selected) AS
(
SELECT CASE WHEN LEFT(DatabaseItem,1) = '[' AND RIGHT(DatabaseItem,1) = ']' THEN PARSENAME(DatabaseItem,1) ELSE DatabaseItem END AS DatabaseItem,
DatabaseType,
AvailabilityGroup,
StartPosition,
Selected
FROM Databases3
)
INSERT INTO @SelectedDatabases (DatabaseName, DatabaseType, AvailabilityGroup, StartPosition, Selected)
SELECT DatabaseName,
DatabaseType,
AvailabilityGroup,
StartPosition,
Selected
FROM Databases4
OPTION (MAXRECURSION 0);
IF @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
INSERT INTO @tmpAvailabilityGroups (AvailabilityGroupName, Selected)
SELECT [name] AS AvailabilityGroupName,
0 AS Selected
FROM [sys].[availability_groups];
INSERT INTO @tmpDatabasesAvailabilityGroups (DatabaseName, AvailabilityGroupName)
SELECT [databases].[name],
[availability_groups].[name]
FROM [sys].[databases] [databases]
INNER JOIN [sys].[availability_replicas] [availability_replicas] ON [databases].[replica_id] = [availability_replicas].[replica_id]
INNER JOIN [sys].[availability_groups] [availability_groups] ON [availability_replicas].[group_id] = [availability_groups].[group_id];
END;
INSERT INTO @tmpDatabases (DatabaseName, DatabaseType, AvailabilityGroup, [Snapshot], [Order], Selected, Completed)
SELECT [name] AS DatabaseName,
CASE WHEN [name] IN('master','msdb','model') OR [is_distributor] = 1 THEN 'S' ELSE 'U' END AS DatabaseType,
NULL AS AvailabilityGroup,
CASE WHEN [source_database_id] IS NOT NULL THEN 1 ELSE 0 END AS [Snapshot],
0 AS [Order],
0 AS Selected,
0 AS Completed
FROM [sys].[databases]
ORDER BY [name] ASC;
UPDATE tmpDatabases
SET AvailabilityGroup = CASE WHEN EXISTS (SELECT * FROM @tmpDatabasesAvailabilityGroups WHERE DatabaseName = tmpDatabases.DatabaseName) THEN 1 ELSE 0 END
FROM @tmpDatabases tmpDatabases;
UPDATE tmpDatabases
SET tmpDatabases.Selected = SelectedDatabases.Selected
FROM @tmpDatabases tmpDatabases
INNER JOIN @SelectedDatabases SelectedDatabases
ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]')
AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL)
AND (tmpDatabases.AvailabilityGroup = SelectedDatabases.AvailabilityGroup OR SelectedDatabases.AvailabilityGroup IS NULL)
AND NOT ((tmpDatabases.DatabaseName = 'tempdb' OR tmpDatabases.[Snapshot] = 1) AND tmpDatabases.DatabaseName <> SelectedDatabases.DatabaseName)
WHERE SelectedDatabases.Selected = 1;
UPDATE tmpDatabases
SET tmpDatabases.Selected = SelectedDatabases.Selected
FROM @tmpDatabases tmpDatabases
INNER JOIN @SelectedDatabases SelectedDatabases
ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]')
AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL)
AND (tmpDatabases.AvailabilityGroup = SelectedDatabases.AvailabilityGroup OR SelectedDatabases.AvailabilityGroup IS NULL)
AND NOT ((tmpDatabases.DatabaseName = 'tempdb' OR tmpDatabases.[Snapshot] = 1) AND tmpDatabases.DatabaseName <> SelectedDatabases.DatabaseName)
WHERE SelectedDatabases.Selected = 0;
UPDATE tmpDatabases
SET tmpDatabases.StartPosition = SelectedDatabases2.StartPosition
FROM @tmpDatabases tmpDatabases
INNER JOIN (SELECT tmpDatabases.DatabaseName, MIN(SelectedDatabases.StartPosition) AS StartPosition
FROM @tmpDatabases tmpDatabases
INNER JOIN @SelectedDatabases SelectedDatabases
ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]')
AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL)
AND (tmpDatabases.AvailabilityGroup = SelectedDatabases.AvailabilityGroup OR SelectedDatabases.AvailabilityGroup IS NULL)
WHERE SelectedDatabases.Selected = 1
GROUP BY tmpDatabases.DatabaseName) SelectedDatabases2
ON tmpDatabases.DatabaseName = SelectedDatabases2.DatabaseName;
IF @Databases IS NOT NULL AND (NOT EXISTS(SELECT * FROM @SelectedDatabases) OR EXISTS(SELECT * FROM @SelectedDatabases WHERE DatabaseName IS NULL OR DATALENGTH(DatabaseName) = 0))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Databases is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Select availability groups //--
----------------------------------------------------------------------------------------------------
IF @AvailabilityGroups IS NOT NULL AND @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, CHAR(10), '');
SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @AvailabilityGroups) > 0 SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @AvailabilityGroups) > 0 SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, ' ' + @StringDelimiter, @StringDelimiter);
SET @AvailabilityGroups = LTRIM(RTRIM(@AvailabilityGroups));
WITH AvailabilityGroups1 (StartPosition, EndPosition, AvailabilityGroupItem) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, 1), 0), LEN(@AvailabilityGroups) + 1) AS EndPosition,
SUBSTRING(@AvailabilityGroups, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, 1), 0), LEN(@AvailabilityGroups) + 1) - 1) AS AvailabilityGroupItem
WHERE @AvailabilityGroups IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, EndPosition + 1), 0), LEN(@AvailabilityGroups) + 1) AS EndPosition,
SUBSTRING(@AvailabilityGroups, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, EndPosition + 1), 0), LEN(@AvailabilityGroups) + 1) - EndPosition - 1) AS AvailabilityGroupItem
FROM AvailabilityGroups1
WHERE EndPosition < LEN(@AvailabilityGroups) + 1
),
AvailabilityGroups2 (AvailabilityGroupItem, StartPosition, Selected) AS
(
SELECT CASE WHEN AvailabilityGroupItem LIKE '-%' THEN RIGHT(AvailabilityGroupItem,LEN(AvailabilityGroupItem) - 1) ELSE AvailabilityGroupItem END AS AvailabilityGroupItem,
StartPosition,
CASE WHEN AvailabilityGroupItem LIKE '-%' THEN 0 ELSE 1 END AS Selected
FROM AvailabilityGroups1
),
AvailabilityGroups3 (AvailabilityGroupItem, StartPosition, Selected) AS
(
SELECT CASE WHEN AvailabilityGroupItem = 'ALL_AVAILABILITY_GROUPS' THEN '%' ELSE AvailabilityGroupItem END AS AvailabilityGroupItem,
StartPosition,
Selected
FROM AvailabilityGroups2
),
AvailabilityGroups4 (AvailabilityGroupName, StartPosition, Selected) AS
(
SELECT CASE WHEN LEFT(AvailabilityGroupItem,1) = '[' AND RIGHT(AvailabilityGroupItem,1) = ']' THEN PARSENAME(AvailabilityGroupItem,1) ELSE AvailabilityGroupItem END AS AvailabilityGroupItem,
StartPosition,
Selected
FROM AvailabilityGroups3
)
INSERT INTO @SelectedAvailabilityGroups (AvailabilityGroupName, StartPosition, Selected)
SELECT AvailabilityGroupName, StartPosition, Selected
FROM AvailabilityGroups4
OPTION (MAXRECURSION 0);
UPDATE tmpAvailabilityGroups
SET tmpAvailabilityGroups.Selected = SelectedAvailabilityGroups.Selected
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN @SelectedAvailabilityGroups SelectedAvailabilityGroups
ON tmpAvailabilityGroups.AvailabilityGroupName LIKE REPLACE(SelectedAvailabilityGroups.AvailabilityGroupName,'_','[_]')
WHERE SelectedAvailabilityGroups.Selected = 1;
UPDATE tmpAvailabilityGroups
SET tmpAvailabilityGroups.Selected = SelectedAvailabilityGroups.Selected
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN @SelectedAvailabilityGroups SelectedAvailabilityGroups
ON tmpAvailabilityGroups.AvailabilityGroupName LIKE REPLACE(SelectedAvailabilityGroups.AvailabilityGroupName,'_','[_]')
WHERE SelectedAvailabilityGroups.Selected = 0;
UPDATE tmpAvailabilityGroups
SET tmpAvailabilityGroups.StartPosition = SelectedAvailabilityGroups2.StartPosition
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN (SELECT tmpAvailabilityGroups.AvailabilityGroupName, MIN(SelectedAvailabilityGroups.StartPosition) AS StartPosition
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN @SelectedAvailabilityGroups SelectedAvailabilityGroups
ON tmpAvailabilityGroups.AvailabilityGroupName LIKE REPLACE(SelectedAvailabilityGroups.AvailabilityGroupName,'_','[_]')
WHERE SelectedAvailabilityGroups.Selected = 1
GROUP BY tmpAvailabilityGroups.AvailabilityGroupName) SelectedAvailabilityGroups2
ON tmpAvailabilityGroups.AvailabilityGroupName = SelectedAvailabilityGroups2.AvailabilityGroupName;
UPDATE tmpDatabases
SET tmpDatabases.StartPosition = tmpAvailabilityGroups.StartPosition,
tmpDatabases.Selected = 1
FROM @tmpDatabases tmpDatabases
INNER JOIN @tmpDatabasesAvailabilityGroups tmpDatabasesAvailabilityGroups ON tmpDatabases.DatabaseName = tmpDatabasesAvailabilityGroups.DatabaseName
INNER JOIN @tmpAvailabilityGroups tmpAvailabilityGroups ON tmpDatabasesAvailabilityGroups.AvailabilityGroupName = tmpAvailabilityGroups.AvailabilityGroupName
WHERE tmpAvailabilityGroups.Selected = 1;
END;
IF @AvailabilityGroups IS NOT NULL AND (NOT EXISTS(SELECT * FROM @SelectedAvailabilityGroups) OR EXISTS(SELECT * FROM @SelectedAvailabilityGroups WHERE AvailabilityGroupName IS NULL OR AvailabilityGroupName = '') OR @Version < 11 OR SERVERPROPERTY('IsHadrEnabled') = 0)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroups is not supported.', 16, 1;
END;
IF (@Databases IS NULL AND @AvailabilityGroups IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'You need to specify one of the parameters @Databases and @AvailabilityGroups.', 16, 2;
END;
IF (@Databases IS NOT NULL AND @AvailabilityGroups IS NOT NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'You can only specify one of the parameters @Databases and @AvailabilityGroups.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
--// Select filegroups //--
----------------------------------------------------------------------------------------------------
SET @FileGroups = REPLACE(@FileGroups, CHAR(10), '');
SET @FileGroups = REPLACE(@FileGroups, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @FileGroups) > 0 SET @FileGroups = REPLACE(@FileGroups, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @FileGroups) > 0 SET @FileGroups = REPLACE(@FileGroups, ' ' + @StringDelimiter, @StringDelimiter);
SET @FileGroups = LTRIM(RTRIM(@FileGroups));
WITH FileGroups1 (StartPosition, EndPosition, FileGroupItem) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FileGroups, 1), 0), LEN(@FileGroups) + 1) AS EndPosition,
SUBSTRING(@FileGroups, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FileGroups, 1), 0), LEN(@FileGroups) + 1) - 1) AS FileGroupItem
WHERE @FileGroups IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FileGroups, EndPosition + 1), 0), LEN(@FileGroups) + 1) AS EndPosition,
SUBSTRING(@FileGroups, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FileGroups, EndPosition + 1), 0), LEN(@FileGroups) + 1) - EndPosition - 1) AS FileGroupItem
FROM FileGroups1
WHERE EndPosition < LEN(@FileGroups) + 1
),
FileGroups2 (FileGroupItem, StartPosition, Selected) AS
(
SELECT CASE WHEN FileGroupItem LIKE '-%' THEN RIGHT(FileGroupItem,LEN(FileGroupItem) - 1) ELSE FileGroupItem END AS FileGroupItem,
StartPosition,
CASE WHEN FileGroupItem LIKE '-%' THEN 0 ELSE 1 END AS Selected
FROM FileGroups1
),
FileGroups3 (FileGroupItem, StartPosition, Selected) AS
(
SELECT CASE WHEN FileGroupItem = 'ALL_FILEGROUPS' THEN '%.%' ELSE FileGroupItem END AS FileGroupItem,
StartPosition,
Selected
FROM FileGroups2
),
FileGroups4 (DatabaseName, FileGroupName, StartPosition, Selected) AS
(
SELECT CASE WHEN PARSENAME(FileGroupItem,4) IS NULL AND PARSENAME(FileGroupItem,3) IS NULL THEN PARSENAME(FileGroupItem,2) ELSE NULL END AS DatabaseName,
CASE WHEN PARSENAME(FileGroupItem,4) IS NULL AND PARSENAME(FileGroupItem,3) IS NULL THEN PARSENAME(FileGroupItem,1) ELSE NULL END AS FileGroupName,
StartPosition,
Selected
FROM FileGroups3
)
INSERT INTO @SelectedFileGroups (DatabaseName, FileGroupName, StartPosition, Selected)
SELECT DatabaseName, FileGroupName, StartPosition, Selected
FROM FileGroups4
OPTION (MAXRECURSION 0);
----------------------------------------------------------------------------------------------------
--// Select objects //--
----------------------------------------------------------------------------------------------------
SET @Objects = REPLACE(@Objects, CHAR(10), '');
SET @Objects = REPLACE(@Objects, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @Objects) > 0 SET @Objects = REPLACE(@Objects, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @Objects) > 0 SET @Objects = REPLACE(@Objects, ' ' + @StringDelimiter, @StringDelimiter);
SET @Objects = LTRIM(RTRIM(@Objects));
WITH Objects1 (StartPosition, EndPosition, ObjectItem) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Objects, 1), 0), LEN(@Objects) + 1) AS EndPosition,
SUBSTRING(@Objects, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Objects, 1), 0), LEN(@Objects) + 1) - 1) AS ObjectItem
WHERE @Objects IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Objects, EndPosition + 1), 0), LEN(@Objects) + 1) AS EndPosition,
SUBSTRING(@Objects, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Objects, EndPosition + 1), 0), LEN(@Objects) + 1) - EndPosition - 1) AS ObjectItem
FROM Objects1
WHERE EndPosition < LEN(@Objects) + 1
),
Objects2 (ObjectItem, StartPosition, Selected) AS
(
SELECT CASE WHEN ObjectItem LIKE '-%' THEN RIGHT(ObjectItem,LEN(ObjectItem) - 1) ELSE ObjectItem END AS ObjectItem,
StartPosition,
CASE WHEN ObjectItem LIKE '-%' THEN 0 ELSE 1 END AS Selected
FROM Objects1
),
Objects3 (ObjectItem, StartPosition, Selected) AS
(
SELECT CASE WHEN ObjectItem = 'ALL_OBJECTS' THEN '%.%.%' ELSE ObjectItem END AS ObjectItem,
StartPosition,
Selected
FROM Objects2
),
Objects4 (DatabaseName, SchemaName, ObjectName, StartPosition, Selected) AS
(
SELECT CASE WHEN PARSENAME(ObjectItem,4) IS NULL THEN PARSENAME(ObjectItem,3) ELSE NULL END AS DatabaseName,
CASE WHEN PARSENAME(ObjectItem,4) IS NULL THEN PARSENAME(ObjectItem,2) ELSE NULL END AS SchemaName,
CASE WHEN PARSENAME(ObjectItem,4) IS NULL THEN PARSENAME(ObjectItem,1) ELSE NULL END AS ObjectName,
StartPosition,
Selected
FROM Objects3
)
INSERT INTO @SelectedObjects (DatabaseName, SchemaName, ObjectName, StartPosition, Selected)
SELECT DatabaseName, SchemaName, ObjectName, StartPosition, Selected
FROM Objects4
OPTION (MAXRECURSION 0);
----------------------------------------------------------------------------------------------------
--// Select check commands //--
----------------------------------------------------------------------------------------------------
SET @CheckCommands = REPLACE(@CheckCommands, @StringDelimiter + ' ', @StringDelimiter);
WITH CheckCommands (StartPosition, EndPosition, CheckCommand) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @CheckCommands, 1), 0), LEN(@CheckCommands) + 1) AS EndPosition,
SUBSTRING(@CheckCommands, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @CheckCommands, 1), 0), LEN(@CheckCommands) + 1) - 1) AS CheckCommand
WHERE @CheckCommands IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @CheckCommands, EndPosition + 1), 0), LEN(@CheckCommands) + 1) AS EndPosition,
SUBSTRING(@CheckCommands, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @CheckCommands, EndPosition + 1), 0), LEN(@CheckCommands) + 1) - EndPosition - 1) AS CheckCommand
FROM CheckCommands
WHERE EndPosition < LEN(@CheckCommands) + 1
)
INSERT INTO @SelectedCheckCommands (CheckCommand)
SELECT CheckCommand
FROM CheckCommands
OPTION (MAXRECURSION 0);
----------------------------------------------------------------------------------------------------
--// Check input parameters //--
----------------------------------------------------------------------------------------------------
IF EXISTS (SELECT * FROM @SelectedCheckCommands WHERE CheckCommand NOT IN('CHECKDB','CHECKFILEGROUP','CHECKALLOC','CHECKTABLE','CHECKCATALOG'))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CheckCommands is not supported.', 16, 1;
END;
IF EXISTS (SELECT * FROM @SelectedCheckCommands GROUP BY CheckCommand HAVING COUNT(*) > 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CheckCommands is not supported.', 16, 2;
END;
IF NOT EXISTS (SELECT * FROM @SelectedCheckCommands)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CheckCommands is not supported.' , 16, 3;
END;
IF EXISTS (SELECT * FROM @SelectedCheckCommands WHERE CheckCommand IN('CHECKDB')) AND EXISTS (SELECT CheckCommand FROM @SelectedCheckCommands WHERE CheckCommand IN('CHECKFILEGROUP','CHECKALLOC','CHECKTABLE','CHECKCATALOG'))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CheckCommands is not supported.', 16, 4;
END;
IF EXISTS (SELECT * FROM @SelectedCheckCommands WHERE CheckCommand IN('CHECKFILEGROUP')) AND EXISTS (SELECT CheckCommand FROM @SelectedCheckCommands WHERE CheckCommand IN('CHECKALLOC','CHECKTABLE'))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @CheckCommands is not supported.', 16, 5;
END;
----------------------------------------------------------------------------------------------------
IF @PhysicalOnly NOT IN ('Y','N') OR @PhysicalOnly IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @PhysicalOnly is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @DataPurity NOT IN ('Y','N') OR @DataPurity IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DataPurity is not supported.', 16, 1;
END;
IF @PhysicalOnly = 'Y' AND @DataPurity = 'Y'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameters @PhysicalOnly and @DataPurity cannot be used together.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @NoIndex NOT IN ('Y','N') OR @NoIndex IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NoIndex is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @ExtendedLogicalChecks NOT IN ('Y','N') OR @ExtendedLogicalChecks IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ExtendedLogicalChecks is not supported.', 16, 1;
END;
IF @PhysicalOnly = 'Y' AND @ExtendedLogicalChecks = 'Y'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameters @PhysicalOnly and @ExtendedLogicalChecks cannot be used together.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @NoInformationalMessages NOT IN ('Y','N') OR @NoInformationalMessages IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @NoInformationalMessages is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @TabLock NOT IN ('Y','N') OR @TabLock IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @TabLock is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS(SELECT * FROM @SelectedFileGroups WHERE DatabaseName IS NULL OR FileGroupName IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileGroups is not supported.', 16, 1;
END;
IF @FileGroups IS NOT NULL AND NOT EXISTS(SELECT * FROM @SelectedFileGroups)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileGroups is not supported.', 16, 2;
END;
IF @FileGroups IS NOT NULL AND NOT EXISTS (SELECT * FROM @SelectedCheckCommands WHERE CheckCommand = 'CHECKFILEGROUP')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FileGroups is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS(SELECT * FROM @SelectedObjects WHERE DatabaseName IS NULL OR SchemaName IS NULL OR ObjectName IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Objects is not supported.', 16, 1;
END;
IF (@Objects IS NOT NULL AND NOT EXISTS(SELECT * FROM @SelectedObjects))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Objects is not supported.', 16, 2;
END;
IF (@Objects IS NOT NULL AND NOT EXISTS (SELECT * FROM @SelectedCheckCommands WHERE CheckCommand = 'CHECKTABLE'))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Objects is not supported.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF @MaxDOP < 0 OR @MaxDOP > 64
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxDOP is not supported.', 16, 1;
END;
IF @MaxDOP IS NOT NULL AND NOT (@Version >= 12.050000 OR SERVERPROPERTY('EngineEdition') IN (5, 8))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxDOP is not supported. MAXDOP is not available in this version of SQL Server.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @AvailabilityGroupReplicas NOT IN('ALL','PRIMARY','SECONDARY','PREFERRED_BACKUP_REPLICA') OR @AvailabilityGroupReplicas IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroupReplicas is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Updateability NOT IN('READ_ONLY','READ_WRITE','ALL') OR @Updateability IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Updateability is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @TimeLimit < 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @TimeLimit is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @LockTimeout < 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LockTimeout is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @LockMessageSeverity NOT IN(10, 16)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LockMessageSeverity is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @StringDelimiter IS NULL OR LEN(@StringDelimiter) > 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @StringDelimiter is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @DatabaseOrder NOT IN('DATABASE_NAME_ASC','DATABASE_NAME_DESC','DATABASE_SIZE_ASC','DATABASE_SIZE_DESC','DATABASE_LAST_GOOD_CHECK_ASC','DATABASE_LAST_GOOD_CHECK_DESC','REPLICA_LAST_GOOD_CHECK_ASC','REPLICA_LAST_GOOD_CHECK_DESC')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseOrder is not supported.', 16, 1;
END;
IF @DatabaseOrder IN('DATABASE_LAST_GOOD_CHECK_ASC','DATABASE_LAST_GOOD_CHECK_DESC') AND NOT ((@Version >= 12.06024 AND @Version < 13) OR (@Version >= 13.05026 AND @Version < 14) OR @Version >= 14.0302916 OR SERVERPROPERTY('EngineEdition') = 8)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseOrder is not supported. DATABASEPROPERTYEX(''DatabaseName'', ''LastGoodCheckDbTime'') is not available in this version of SQL Server.', 16, 2;
END;
IF @DatabaseOrder IN('REPLICA_LAST_GOOD_CHECK_ASC','REPLICA_LAST_GOOD_CHECK_DESC') AND @LogToTable = 'N'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseOrder is not supported. You need to provide the parameter @LogToTable = ''Y''.', 16, 3;
END;
IF @DatabaseOrder IN('DATABASE_LAST_GOOD_CHECK_ASC','DATABASE_LAST_GOOD_CHECK_DESC','REPLICA_LAST_GOOD_CHECK_ASC','REPLICA_LAST_GOOD_CHECK_DESC') AND @CheckCommands <> 'CHECKDB'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseOrder is not supported. You need to provide the parameter @CheckCommands = ''CHECKDB''.', 16, 4;
END;
IF @DatabaseOrder IS NOT NULL AND SERVERPROPERTY('EngineEdition') = 5
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseOrder is not supported. This parameter is not supported in Azure SQL Database.', 16, 5;
END;
----------------------------------------------------------------------------------------------------
IF @DatabasesInParallel NOT IN('Y','N') OR @DatabasesInParallel IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabasesInParallel is not supported.', 16, 1;
END;
IF @DatabasesInParallel = 'Y' AND SERVERPROPERTY('EngineEdition') = 5
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabasesInParallel is not supported. This parameter is not supported in Azure SQL Database.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @LogToTable NOT IN('Y','N') OR @LogToTable IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LogToTable is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Execute NOT IN('Y','N') OR @Execute IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Execute is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS(SELECT * FROM @Errors)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The documentation is available at https://ola.hallengren.com/sql-server-integrity-check.html.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Check that selected databases and availability groups exist //--
----------------------------------------------------------------------------------------------------
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @SelectedDatabases
WHERE DatabaseName NOT LIKE '%[%]%'
AND DatabaseName NOT IN (SELECT DatabaseName FROM @tmpDatabases);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following databases in the @Databases parameter do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @SelectedFileGroups
WHERE DatabaseName NOT LIKE '%[%]%'
AND DatabaseName NOT IN (SELECT DatabaseName FROM @tmpDatabases);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following databases in the @FileGroups parameter do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @SelectedObjects
WHERE DatabaseName NOT LIKE '%[%]%'
AND DatabaseName NOT IN (SELECT DatabaseName FROM @tmpDatabases);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following databases in the @Objects parameter do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(AvailabilityGroupName) + ', '
FROM @SelectedAvailabilityGroups
WHERE AvailabilityGroupName NOT LIKE '%[%]%'
AND AvailabilityGroupName NOT IN (SELECT AvailabilityGroupName FROM @tmpAvailabilityGroups);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following availability groups do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @SelectedFileGroups
WHERE DatabaseName NOT LIKE '%[%]%'
AND DatabaseName IN (SELECT DatabaseName FROM @tmpDatabases)
AND DatabaseName NOT IN (SELECT DatabaseName FROM @tmpDatabases WHERE Selected = 1);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following databases have been selected in the @FileGroups parameter, but not in the @Databases or @AvailabilityGroups parameters: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @SelectedObjects
WHERE DatabaseName NOT LIKE '%[%]%'
AND DatabaseName IN (SELECT DatabaseName FROM @tmpDatabases)
AND DatabaseName NOT IN (SELECT DatabaseName FROM @tmpDatabases WHERE Selected = 1);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following databases have been selected in the @Objects parameter, but not in the @Databases or @AvailabilityGroups parameters: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
----------------------------------------------------------------------------------------------------
--// Check @@SERVERNAME //--
----------------------------------------------------------------------------------------------------
IF UPPER(@@SERVERNAME) <> UPPER(CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(MAX))) AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The @@SERVERNAME does not match SERVERPROPERTY(''ServerName''). See ' + CASE WHEN SERVERPROPERTY('IsClustered') = 0 THEN 'https://docs.microsoft.com/en-us/sql/database-engine/install-windows/rename-a-computer-that-hosts-a-stand-alone-instance-of-sql-server' WHEN SERVERPROPERTY('IsClustered') = 1 THEN 'https://docs.microsoft.com/en-us/sql/sql-server/failover-clusters/install/rename-a-sql-server-failover-cluster-instance' END + '.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Raise errors //--
----------------------------------------------------------------------------------------------------
DECLARE ErrorCursor CURSOR FAST_FORWARD FOR SELECT [Message], [severity], [State] FROM @Errors ORDER BY [ID] ASC;
OPEN ErrorCursor;
FETCH ErrorCursor INTO @CurrentMessage, @CurrentSeverity, @CurrentState;
WHILE @@FETCH_STATUS = 0
BEGIN
RAISERROR('%s', @CurrentSeverity, @CurrentState, @CurrentMessage) WITH NOWAIT;
RAISERROR(@EmptyLine, 10, 1) WITH NOWAIT;
FETCH NEXT FROM ErrorCursor INTO @CurrentMessage, @CurrentSeverity, @CurrentState;
END;
CLOSE ErrorCursor;
DEALLOCATE ErrorCursor;
IF EXISTS (SELECT * FROM @Errors WHERE [severity] >= 16)
BEGIN
SET @ReturnCode = 50000;
GOTO Logging;
END;
----------------------------------------------------------------------------------------------------
--// Update database order //--
----------------------------------------------------------------------------------------------------
IF @DatabaseOrder IN('DATABASE_SIZE_ASC','DATABASE_SIZE_DESC')
BEGIN
UPDATE tmpDatabases
SET DatabaseSize = (SELECT SUM(CAST(SIZE AS BIGINT)) FROM [sys].[master_files] WHERE [type] = 0 AND [database_id] = DB_ID(tmpDatabases.DatabaseName))
FROM @tmpDatabases tmpDatabases;
END;
IF @DatabaseOrder IN('DATABASE_LAST_GOOD_CHECK_ASC','DATABASE_LAST_GOOD_CHECK_DESC')
BEGIN
UPDATE tmpDatabases
SET LastGoodCheckDbTime = NULLIF(CAST(DATABASEPROPERTYEX (DatabaseName,'LastGoodCheckDbTime') AS DATETIME2),'1900-01-01 00:00:00.000')
FROM @tmpDatabases tmpDatabases;
END;
IF @DatabaseOrder IN('REPLICA_LAST_GOOD_CHECK_ASC','REPLICA_LAST_GOOD_CHECK_DESC')
BEGIN
UPDATE tmpDatabases
SET LastCommandTime = MaxStartTime
FROM @tmpDatabases tmpDatabases
INNER JOIN (SELECT DatabaseName, MAX([starttime]) AS MaxStartTime
FROM [dbo].CommandLog
WHERE CommandType = 'DBCC_CHECKDB'
AND ErrorNumber = 0
GROUP BY DatabaseName) CommandLog
ON tmpDatabases.DatabaseName = CommandLog.DatabaseName COLLATE DATABASE_DEFAULT;
END;
IF @DatabaseOrder IS NULL
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY StartPosition ASC, DatabaseName ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_NAME_ASC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseName ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_NAME_DESC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseName DESC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_SIZE_ASC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseSize ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_SIZE_DESC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseSize DESC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_LAST_GOOD_CHECK_ASC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY LastGoodCheckDbTime ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_LAST_GOOD_CHECK_DESC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY LastGoodCheckDbTime DESC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'REPLICA_LAST_GOOD_CHECK_ASC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY LastCommandTime ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'REPLICA_LAST_GOOD_CHECK_DESC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY LastCommandTime DESC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
----------------------------------------------------------------------------------------------------
--// Update the queue //--
----------------------------------------------------------------------------------------------------
IF @DatabasesInParallel = 'Y'
BEGIN
BEGIN TRY
SELECT @QueueID = QueueID
FROM [dbo].[Queue]
WHERE SchemaName = @SchemaName
AND ObjectName = @ObjectName
AND [Parameters] = @Parameters;
IF @QueueID IS NULL
BEGIN
BEGIN TRANSACTION;
SELECT @QueueID = QueueID
FROM [dbo].[Queue] WITH (UPDLOCK, HOLDLOCK)
WHERE SchemaName = @SchemaName
AND ObjectName = @ObjectName
AND [Parameters] = @Parameters;
IF @QueueID IS NULL
BEGIN
INSERT INTO [dbo].[Queue] (SchemaName, ObjectName, [Parameters])
SELECT @SchemaName, @ObjectName, @Parameters;
SET @QueueID = SCOPE_IDENTITY();
END;
COMMIT TRANSACTION;
END;
BEGIN TRANSACTION;
UPDATE [Queue]
SET QueueStartTime = SYSDATETIME(),
SessionID = @@SPID,
RequestID = (SELECT [request_id] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID),
RequestStartTime = (SELECT [start_time] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID)
FROM [dbo].[Queue] [Queue]
WHERE QueueID = @QueueID
AND NOT EXISTS (SELECT *
FROM [sys].[dm_exec_requests]
WHERE [session_id] = [Queue].SessionID
AND [request_id] = [Queue].RequestID
AND [start_time] = [Queue].RequestStartTime)
AND NOT EXISTS (SELECT *
FROM [dbo].QueueDatabase QueueDatabase
INNER JOIN [sys].[dm_exec_requests] ON QueueDatabase.SessionID = [session_id] AND QueueDatabase.RequestID = [request_id] AND QueueDatabase.RequestStartTime = [start_time]
WHERE QueueDatabase.QueueID = @QueueID);
IF @@ROWCOUNT = 1
BEGIN
INSERT INTO [dbo].QueueDatabase (QueueID, DatabaseName)
SELECT @QueueID AS QueueID,
DatabaseName
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
AND NOT EXISTS (SELECT * FROM [dbo].QueueDatabase WHERE DatabaseName = tmpDatabases.DatabaseName AND QueueID = @QueueID);
DELETE QueueDatabase
FROM [dbo].QueueDatabase QueueDatabase
WHERE QueueID = @QueueID
AND NOT EXISTS (SELECT * FROM @tmpDatabases tmpDatabases WHERE DatabaseName = QueueDatabase.DatabaseName AND Selected = 1);
UPDATE QueueDatabase
SET DatabaseOrder = tmpDatabases.[Order]
FROM [dbo].QueueDatabase QueueDatabase
INNER JOIN @tmpDatabases tmpDatabases ON QueueDatabase.DatabaseName = tmpDatabases.DatabaseName
WHERE QueueID = @QueueID;
END;
COMMIT TRANSACTION;
SELECT @QueueStartTime = QueueStartTime
FROM [dbo].[Queue]
WHERE QueueID = @QueueID;
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0
BEGIN
ROLLBACK TRANSACTION;
END;
SET @ErrorMessage = 'Msg ' + CAST(ERROR_NUMBER() AS NVARCHAR) + ', ' + ISNULL(ERROR_MESSAGE(),'');
RAISERROR('%s',16,1,@ErrorMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
SET @ReturnCode = ERROR_NUMBER();
GOTO Logging;
END CATCH;
END;
----------------------------------------------------------------------------------------------------
--// Execute commands //--
----------------------------------------------------------------------------------------------------
WHILE (1 = 1)
BEGIN
IF @DatabasesInParallel = 'Y'
BEGIN
UPDATE QueueDatabase
SET DatabaseStartTime = NULL,
SessionID = NULL,
RequestID = NULL,
RequestStartTime = NULL
FROM [dbo].QueueDatabase QueueDatabase
WHERE QueueID = @QueueID
AND DatabaseStartTime IS NOT NULL
AND DatabaseEndTime IS NULL
AND NOT EXISTS (SELECT * FROM [sys].[dm_exec_requests] WHERE [session_id] = QueueDatabase.SessionID AND [request_id] = QueueDatabase.RequestID AND [start_time] = QueueDatabase.RequestStartTime);
UPDATE QueueDatabase
SET DatabaseStartTime = SYSDATETIME(),
DatabaseEndTime = NULL,
SessionID = @@SPID,
RequestID = (SELECT [request_id] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID),
RequestStartTime = (SELECT [start_time] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID),
@CurrentDatabaseName = DatabaseName
FROM (SELECT TOP 1 DatabaseStartTime,
DatabaseEndTime,
SessionID,
RequestID,
RequestStartTime,
DatabaseName
FROM [dbo].QueueDatabase
WHERE QueueID = @QueueID
AND (DatabaseStartTime < @QueueStartTime OR DatabaseStartTime IS NULL)
AND NOT (DatabaseStartTime IS NOT NULL AND DatabaseEndTime IS NULL)
ORDER BY DatabaseOrder ASC
) QueueDatabase;
END;
ELSE
BEGIN
SELECT TOP 1 @CurrentDBID = [Id],
@CurrentDatabaseName = DatabaseName
FROM @tmpDatabases
WHERE Selected = 1
AND Completed = 0
ORDER BY [Order] ASC;
END;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
SET @CurrentDatabase_sp_executesql = QUOTENAME(@CurrentDatabaseName) + '.sys.sp_executesql';
BEGIN
SET @DatabaseMessage = 'Date and time: ' + CONVERT(NVARCHAR,SYSDATETIME(),120);
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Database: ' + QUOTENAME(@CurrentDatabaseName);
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
SELECT @CurrentUserAccess = [user_access_desc],
@CurrentIsReadOnly = [is_read_only],
@CurrentDatabaseState = [state_desc],
@CurrentInStandby = [is_in_standby],
@CurrentRecoveryModel = [recovery_model_desc]
FROM [sys].[databases]
WHERE [name] = @CurrentDatabaseName;
BEGIN
SET @DatabaseMessage = 'State: ' + @CurrentDatabaseState;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Standby: ' + CASE WHEN @CurrentInStandby = 1 THEN 'Yes' ELSE 'No' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Updateability: ' + CASE WHEN @CurrentIsReadOnly = 1 THEN 'READ_ONLY' WHEN @CurrentIsReadOnly = 0 THEN 'READ_WRITE' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'User access: ' + @CurrentUserAccess;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Recovery model: ' + @CurrentRecoveryModel;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
IF @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
SELECT @CurrentReplicaID = [databases].[replica_id]
FROM [sys].[databases] [databases]
INNER JOIN [sys].[availability_replicas] [availability_replicas] ON [databases].[replica_id] = [availability_replicas].[replica_id]
WHERE [databases].[name] = @CurrentDatabaseName;
SELECT @CurrentAvailabilityGroupID = [group_id],
@CurrentSecondaryRoleAllowConnections = [secondary_role_allow_connections_desc]
FROM [sys].[availability_replicas]
WHERE [replica_id] = @CurrentReplicaID;
SELECT @CurrentAvailabilityGroupRole = [role_desc]
FROM [sys].[dm_hadr_availability_replica_states]
WHERE [replica_id] = @CurrentReplicaID;
SELECT @CurrentAvailabilityGroup = [name],
@CurrentAvailabilityGroupBackupPreference = UPPER([automated_backup_preference_desc])
FROM [sys].[availability_groups]
WHERE [group_id] = @CurrentAvailabilityGroupID;
END;
IF @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1 AND @CurrentAvailabilityGroup IS NOT NULL AND @AvailabilityGroupReplicas = 'PREFERRED_BACKUP_REPLICA'
BEGIN
SELECT @CurrentIsPreferredBackupReplica = [sys].fn_hadr_backup_is_preferred_replica(@CurrentDatabaseName);
END;
IF SERVERPROPERTY('EngineEdition') <> 5
BEGIN
SELECT @CurrentDatabaseMirroringRole = UPPER([mirroring_role_desc])
FROM [sys].[database_mirroring] [database_mirroring]
INNER JOIN [sys].[databases] [databases] ON [database_mirroring].[database_id] = [databases].[database_id]
WHERE [databases].[name] = @CurrentDatabaseName;
END;
IF @CurrentAvailabilityGroup IS NOT NULL
BEGIN
SET @DatabaseMessage = 'Availability group: ' + ISNULL(@CurrentAvailabilityGroup,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Availability group role: ' + ISNULL(@CurrentAvailabilityGroupRole,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
IF @CurrentAvailabilityGroupRole = 'SECONDARY'
BEGIN
SET @DatabaseMessage = 'Readable Secondary: ' + ISNULL(@CurrentSecondaryRoleAllowConnections,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
IF @AvailabilityGroupReplicas = 'PREFERRED_BACKUP_REPLICA'
BEGIN
SET @DatabaseMessage = 'Availability group backup preference: ' + ISNULL(@CurrentAvailabilityGroupBackupPreference,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Is preferred backup replica: ' + CASE WHEN @CurrentIsPreferredBackupReplica = 1 THEN 'Yes' WHEN @CurrentIsPreferredBackupReplica = 0 THEN 'No' ELSE 'N/A' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
END;
IF @CurrentDatabaseMirroringRole IS NOT NULL
BEGIN
SET @DatabaseMessage = 'Database mirroring role: ' + @CurrentDatabaseMirroringRole;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF @CurrentDatabaseState IN('ONLINE','EMERGENCY')
AND NOT (@CurrentUserAccess = 'SINGLE_USER')
AND (@CurrentAvailabilityGroupRole = 'PRIMARY' OR @CurrentAvailabilityGroupRole IS NULL OR SERVERPROPERTY('EngineEdition') = 3)
AND ((@AvailabilityGroupReplicas = 'PRIMARY' AND @CurrentAvailabilityGroupRole = 'PRIMARY') OR (@AvailabilityGroupReplicas = 'SECONDARY' AND @CurrentAvailabilityGroupRole = 'SECONDARY') OR (@AvailabilityGroupReplicas = 'PREFERRED_BACKUP_REPLICA' AND @CurrentIsPreferredBackupReplica = 1) OR @AvailabilityGroupReplicas = 'ALL' OR @CurrentAvailabilityGroupRole IS NULL)
AND NOT (@CurrentIsReadOnly = 1 AND @Updateability = 'READ_WRITE')
AND NOT (@CurrentIsReadOnly = 0 AND @Updateability = 'READ_ONLY')
AND NOT (@AmazonRDS = 1 AND @CurrentDatabaseName = 'rdsadmin')
BEGIN
-- Check database
IF EXISTS(SELECT * FROM @SelectedCheckCommands WHERE CheckCommand = 'CHECKDB') AND (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SET @CurrentDatabaseContext = CASE WHEN SERVERPROPERTY('EngineEdition') = 5 THEN @CurrentDatabaseName ELSE 'master' END;
SET @CurrentCommandType = 'DBCC_CHECKDB';
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'DBCC CHECKDB (' + QUOTENAME(@CurrentDatabaseName);
IF @NoIndex = 'Y' SET @CurrentCommand += ', NOINDEX';
SET @CurrentCommand += ') WITH ALL_ERRORMSGS';
IF @DataPurity = 'Y' SET @CurrentCommand += ', DATA_PURITY';
IF @PhysicalOnly = 'Y' SET @CurrentCommand += ', PHYSICAL_ONLY';
IF @ExtendedLogicalChecks = 'Y' SET @CurrentCommand += ', EXTENDED_LOGICAL_CHECKS';
IF @NoInformationalMessages = 'Y' SET @CurrentCommand += ', NO_INFOMSGS';
IF @TabLock = 'Y' SET @CurrentCommand += ', TABLOCK';
IF @MaxDOP IS NOT NULL SET @CurrentCommand += ', MAXDOP = ' + CAST(@MaxDOP AS NVARCHAR);
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseContext, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 1, @DatabaseName = @CurrentDatabaseName, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
END;
-- Check filegroups
IF EXISTS(SELECT * FROM @SelectedCheckCommands WHERE CheckCommand = 'CHECKFILEGROUP')
AND (@CurrentAvailabilityGroupRole = 'PRIMARY' OR (@CurrentAvailabilityGroupRole = 'SECONDARY' AND @CurrentSecondaryRoleAllowConnections = 'ALL') OR @CurrentAvailabilityGroupRole IS NULL)
AND (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SET @CurrentCommand = 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SELECT data_space_id AS FileGroupID, name AS FileGroupName, 0 AS [Order], 0 AS Selected, 0 AS Completed FROM sys.filegroups filegroups WHERE [type] <> ''FX'' ORDER BY CASE WHEN filegroups.name = ''PRIMARY'' THEN 1 ELSE 0 END DESC, filegroups.name ASC';
INSERT INTO @tmpFileGroups (FileGroupID, FileGroupName, [Order], Selected, Completed)
EXECUTE @CurrentDatabase_sp_executesql @stmt = @CurrentCommand;
SET @Error = @@ERROR;
IF @Error <> 0 SET @ReturnCode = @Error;
IF @FileGroups IS NULL
BEGIN
UPDATE tmpFileGroups
SET tmpFileGroups.Selected = 1
FROM @tmpFileGroups tmpFileGroups;
END;
ELSE
BEGIN
UPDATE tmpFileGroups
SET tmpFileGroups.Selected = SelectedFileGroups.Selected
FROM @tmpFileGroups tmpFileGroups
INNER JOIN @SelectedFileGroups SelectedFileGroups
ON @CurrentDatabaseName LIKE REPLACE(SelectedFileGroups.DatabaseName,'_','[_]') AND tmpFileGroups.FileGroupName LIKE REPLACE(SelectedFileGroups.FileGroupName,'_','[_]')
WHERE SelectedFileGroups.Selected = 1;
UPDATE tmpFileGroups
SET tmpFileGroups.Selected = SelectedFileGroups.Selected
FROM @tmpFileGroups tmpFileGroups
INNER JOIN @SelectedFileGroups SelectedFileGroups
ON @CurrentDatabaseName LIKE REPLACE(SelectedFileGroups.DatabaseName,'_','[_]') AND tmpFileGroups.FileGroupName LIKE REPLACE(SelectedFileGroups.FileGroupName,'_','[_]')
WHERE SelectedFileGroups.Selected = 0;
UPDATE tmpFileGroups
SET tmpFileGroups.StartPosition = SelectedFileGroups2.StartPosition
FROM @tmpFileGroups tmpFileGroups
INNER JOIN (SELECT tmpFileGroups.FileGroupName, MIN(SelectedFileGroups.StartPosition) AS StartPosition
FROM @tmpFileGroups tmpFileGroups
INNER JOIN @SelectedFileGroups SelectedFileGroups
ON @CurrentDatabaseName LIKE REPLACE(SelectedFileGroups.DatabaseName,'_','[_]') AND tmpFileGroups.FileGroupName LIKE REPLACE(SelectedFileGroups.FileGroupName,'_','[_]')
WHERE SelectedFileGroups.Selected = 1
GROUP BY tmpFileGroups.FileGroupName) SelectedFileGroups2
ON tmpFileGroups.FileGroupName = SelectedFileGroups2.FileGroupName;
END;
WITH tmpFileGroups AS (
SELECT FileGroupName, [Order], ROW_NUMBER() OVER (ORDER BY StartPosition ASC, FileGroupName ASC) AS RowNumber
FROM @tmpFileGroups tmpFileGroups
WHERE Selected = 1
)
UPDATE tmpFileGroups
SET [Order] = RowNumber;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + '.' + QUOTENAME(FileGroupName) + ', '
FROM @SelectedFileGroups SelectedFileGroups
WHERE DatabaseName = @CurrentDatabaseName
AND FileGroupName NOT LIKE '%[%]%'
AND NOT EXISTS (SELECT * FROM @tmpFileGroups WHERE FileGroupName = SelectedFileGroups.FileGroupName);
IF @@ROWCOUNT > 0
BEGIN
SET @ErrorMessage = 'The following file groups do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.';
RAISERROR('%s',10,1,@ErrorMessage) WITH NOWAIT;
SET @Error = @@ERROR;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
END;
WHILE (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SELECT TOP 1 @CurrentFGID = [Id],
@CurrentFileGroupID = FileGroupID,
@CurrentFileGroupName = FileGroupName
FROM @tmpFileGroups
WHERE Selected = 1
AND Completed = 0
ORDER BY [Order] ASC;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
-- Does the filegroup exist?
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'IF EXISTS(SELECT * FROM sys.filegroups filegroups WHERE [type] <> ''FX'' AND filegroups.data_space_id = @ParamFileGroupID AND filegroups.[name] = @ParamFileGroupName) BEGIN SET @ParamFileGroupExists = 1 END';
BEGIN TRY
EXECUTE @CurrentDatabase_sp_executesql @stmt = @CurrentCommand, @params = N'@ParamFileGroupID int, @ParamFileGroupName sysname, @ParamFileGroupExists bit OUTPUT', @ParamFileGroupID = @CurrentFileGroupID, @ParamFileGroupName = @CurrentFileGroupName, @ParamFileGroupExists = @CurrentFileGroupExists OUTPUT;
IF @CurrentFileGroupExists IS NULL SET @CurrentFileGroupExists = 0;
END TRY
BEGIN CATCH
SET @ErrorMessage = 'Msg ' + CAST(ERROR_NUMBER() AS NVARCHAR) + ', ' + ISNULL(ERROR_MESSAGE(),'') + CASE WHEN ERROR_NUMBER() = 1222 THEN ', ' + ' The file group ' + QUOTENAME(@CurrentFileGroupName) + ' in the database ' + QUOTENAME(@CurrentDatabaseName) + ' is locked. It could not be checked if the filegroup exists.' ELSE '' END;
SET @Severity = CASE WHEN ERROR_NUMBER() IN(1205,1222) THEN @LockMessageSeverity ELSE 16 END;
RAISERROR('%s',@Severity,1,@ErrorMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF NOT (ERROR_NUMBER() IN(1205,1222) AND @LockMessageSeverity = 10)
BEGIN
SET @ReturnCode = ERROR_NUMBER();
END;
END CATCH;
IF @CurrentFileGroupExists = 1
BEGIN
SET @CurrentDatabaseContext = @CurrentDatabaseName;
SET @CurrentCommandType = 'DBCC_CHECKFILEGROUP';
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'DBCC CHECKFILEGROUP (' + QUOTENAME(@CurrentFileGroupName);
IF @NoIndex = 'Y' SET @CurrentCommand += ', NOINDEX';
SET @CurrentCommand += ') WITH ALL_ERRORMSGS';
IF @PhysicalOnly = 'Y' SET @CurrentCommand += ', PHYSICAL_ONLY';
IF @NoInformationalMessages = 'Y' SET @CurrentCommand += ', NO_INFOMSGS';
IF @TabLock = 'Y' SET @CurrentCommand += ', TABLOCK';
IF @MaxDOP IS NOT NULL SET @CurrentCommand += ', MAXDOP = ' + CAST(@MaxDOP AS NVARCHAR);
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseContext, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 1, @DatabaseName = @CurrentDatabaseName, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
END;
UPDATE @tmpFileGroups
SET Completed = 1
WHERE Selected = 1
AND Completed = 0
AND [Id] = @CurrentFGID;
SET @CurrentFGID = NULL;
SET @CurrentFileGroupID = NULL;
SET @CurrentFileGroupName = NULL;
SET @CurrentFileGroupExists = NULL;
SET @CurrentDatabaseContext = NULL;
SET @CurrentCommand = NULL;
SET @CurrentCommandOutput = NULL;
SET @CurrentCommandType = NULL;
END;
END;
-- Check disk space allocation structures
IF EXISTS(SELECT * FROM @SelectedCheckCommands WHERE CheckCommand = 'CHECKALLOC') AND (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SET @CurrentDatabaseContext = CASE WHEN SERVERPROPERTY('EngineEdition') = 5 THEN @CurrentDatabaseName ELSE 'master' END;
SET @CurrentCommandType = 'DBCC_CHECKALLOC';
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'DBCC CHECKALLOC (' + QUOTENAME(@CurrentDatabaseName);
SET @CurrentCommand += ') WITH ALL_ERRORMSGS';
IF @NoInformationalMessages = 'Y' SET @CurrentCommand += ', NO_INFOMSGS';
IF @TabLock = 'Y' SET @CurrentCommand += ', TABLOCK';
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseContext, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 1, @DatabaseName = @CurrentDatabaseName, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
END;
-- Check objects
IF EXISTS(SELECT * FROM @SelectedCheckCommands WHERE CheckCommand = 'CHECKTABLE')
AND (@CurrentAvailabilityGroupRole = 'PRIMARY' OR (@CurrentAvailabilityGroupRole = 'SECONDARY' AND @CurrentSecondaryRoleAllowConnections = 'ALL') OR @CurrentAvailabilityGroupRole IS NULL)
AND (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SET @CurrentCommand = 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SELECT schemas.[schema_id] AS SchemaID, schemas.[name] AS SchemaName, objects.[object_id] AS ObjectID, objects.[name] AS ObjectName, RTRIM(objects.[type]) AS ObjectType, 0 AS [Order], 0 AS Selected, 0 AS Completed FROM sys.objects objects INNER JOIN sys.schemas schemas ON objects.schema_id = schemas.schema_id LEFT OUTER JOIN sys.tables tables ON objects.object_id = tables.object_id WHERE objects.[type] IN(''U'',''V'') AND EXISTS(SELECT * FROM sys.indexes indexes WHERE indexes.object_id = objects.object_id)' + CASE WHEN @Version >= 12 THEN ' AND (tables.is_memory_optimized = 0 OR is_memory_optimized IS NULL)' ELSE '' END + ' ORDER BY schemas.name ASC, objects.name ASC';
INSERT INTO @tmpObjects (SchemaID, SchemaName, [objectid], ObjectName, ObjectType, [Order], Selected, Completed)
EXECUTE @CurrentDatabase_sp_executesql @stmt = @CurrentCommand;
SET @Error = @@ERROR;
IF @Error <> 0 SET @ReturnCode = @Error;
IF @Objects IS NULL
BEGIN
UPDATE tmpObjects
SET tmpObjects.Selected = 1
FROM @tmpObjects tmpObjects;
END;
ELSE
BEGIN
UPDATE tmpObjects
SET tmpObjects.Selected = SelectedObjects.Selected
FROM @tmpObjects tmpObjects
INNER JOIN @SelectedObjects SelectedObjects
ON @CurrentDatabaseName LIKE REPLACE(SelectedObjects.DatabaseName,'_','[_]') AND tmpObjects.SchemaName LIKE REPLACE(SelectedObjects.SchemaName,'_','[_]') AND tmpObjects.ObjectName LIKE REPLACE(SelectedObjects.ObjectName,'_','[_]')
WHERE SelectedObjects.Selected = 1;
UPDATE tmpObjects
SET tmpObjects.Selected = SelectedObjects.Selected
FROM @tmpObjects tmpObjects
INNER JOIN @SelectedObjects SelectedObjects
ON @CurrentDatabaseName LIKE REPLACE(SelectedObjects.DatabaseName,'_','[_]') AND tmpObjects.SchemaName LIKE REPLACE(SelectedObjects.SchemaName,'_','[_]') AND tmpObjects.ObjectName LIKE REPLACE(SelectedObjects.ObjectName,'_','[_]')
WHERE SelectedObjects.Selected = 0;
UPDATE tmpObjects
SET tmpObjects.StartPosition = SelectedObjects2.StartPosition
FROM @tmpObjects tmpObjects
INNER JOIN (SELECT tmpObjects.SchemaName, tmpObjects.ObjectName, MIN(SelectedObjects.StartPosition) AS StartPosition
FROM @tmpObjects tmpObjects
INNER JOIN @SelectedObjects SelectedObjects
ON @CurrentDatabaseName LIKE REPLACE(SelectedObjects.DatabaseName,'_','[_]') AND tmpObjects.SchemaName LIKE REPLACE(SelectedObjects.SchemaName,'_','[_]') AND tmpObjects.ObjectName LIKE REPLACE(SelectedObjects.ObjectName,'_','[_]')
WHERE SelectedObjects.Selected = 1
GROUP BY tmpObjects.SchemaName, tmpObjects.ObjectName) SelectedObjects2
ON tmpObjects.SchemaName = SelectedObjects2.SchemaName AND tmpObjects.ObjectName = SelectedObjects2.ObjectName;
END;
WITH tmpObjects AS (
SELECT SchemaName, ObjectName, [Order], ROW_NUMBER() OVER (ORDER BY StartPosition ASC, SchemaName ASC, ObjectName ASC) AS RowNumber
FROM @tmpObjects tmpObjects
WHERE Selected = 1
)
UPDATE tmpObjects
SET [Order] = RowNumber;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + '.' + QUOTENAME(SchemaName) + '.' + QUOTENAME(ObjectName) + ', '
FROM @SelectedObjects SelectedObjects
WHERE DatabaseName = @CurrentDatabaseName
AND SchemaName NOT LIKE '%[%]%'
AND ObjectName NOT LIKE '%[%]%'
AND NOT EXISTS (SELECT * FROM @tmpObjects WHERE SchemaName = SelectedObjects.SchemaName AND ObjectName = SelectedObjects.ObjectName);
IF @@ROWCOUNT > 0
BEGIN
SET @ErrorMessage = 'The following objects do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.';
RAISERROR('%s',10,1,@ErrorMessage) WITH NOWAIT;
SET @Error = @@ERROR;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
END;
WHILE (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SELECT TOP 1 @CurrentOID = [Id],
@CurrentSchemaID = SchemaID,
@CurrentSchemaName = SchemaName,
@CurrentObjectID = [objectid],
@CurrentObjectName = ObjectName,
@CurrentObjectType = ObjectType
FROM @tmpObjects
WHERE Selected = 1
AND Completed = 0
ORDER BY [Order] ASC;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
-- Does the object exist?
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'IF EXISTS(SELECT * FROM sys.objects objects INNER JOIN sys.schemas schemas ON objects.schema_id = schemas.schema_id LEFT OUTER JOIN sys.tables tables ON objects.object_id = tables.object_id WHERE objects.[type] IN(''U'',''V'') AND EXISTS(SELECT * FROM sys.indexes indexes WHERE indexes.object_id = objects.object_id)' + CASE WHEN @Version >= 12 THEN ' AND (tables.is_memory_optimized = 0 OR is_memory_optimized IS NULL)' ELSE '' END + ' AND schemas.[schema_id] = @ParamSchemaID AND schemas.[name] = @ParamSchemaName AND objects.[object_id] = @ParamObjectID AND objects.[name] = @ParamObjectName AND objects.[type] = @ParamObjectType) BEGIN SET @ParamObjectExists = 1 END';
BEGIN TRY
EXECUTE @CurrentDatabase_sp_executesql @stmt = @CurrentCommand, @params = N'@ParamSchemaID int, @ParamSchemaName sysname, @ParamObjectID int, @ParamObjectName sysname, @ParamObjectType sysname, @ParamObjectExists bit OUTPUT', @ParamSchemaID = @CurrentSchemaID, @ParamSchemaName = @CurrentSchemaName, @ParamObjectID = @CurrentObjectID, @ParamObjectName = @CurrentObjectName, @ParamObjectType = @CurrentObjectType, @ParamObjectExists = @CurrentObjectExists OUTPUT;
IF @CurrentObjectExists IS NULL SET @CurrentObjectExists = 0;
END TRY
BEGIN CATCH
SET @ErrorMessage = 'Msg ' + CAST(ERROR_NUMBER() AS NVARCHAR) + ', ' + ISNULL(ERROR_MESSAGE(),'') + CASE WHEN ERROR_NUMBER() = 1222 THEN ', ' + 'The object ' + QUOTENAME(@CurrentDatabaseName) + '.' + QUOTENAME(@CurrentSchemaName) + '.' + QUOTENAME(@CurrentObjectName) + ' is locked. It could not be checked if the object exists.' ELSE '' END;
SET @Severity = CASE WHEN ERROR_NUMBER() IN(1205,1222) THEN @LockMessageSeverity ELSE 16 END;
RAISERROR('%s',@Severity,1,@ErrorMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF NOT (ERROR_NUMBER() IN(1205,1222) AND @LockMessageSeverity = 10)
BEGIN
SET @ReturnCode = ERROR_NUMBER();
END;
END CATCH;
IF @CurrentObjectExists = 1
BEGIN
SET @CurrentDatabaseContext = @CurrentDatabaseName;
SET @CurrentCommandType = 'DBCC_CHECKTABLE';
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'DBCC CHECKTABLE (' + QUOTENAME(QUOTENAME(@CurrentSchemaName) + '.' + QUOTENAME(@CurrentObjectName),'''');
IF @NoIndex = 'Y' SET @CurrentCommand += ', NOINDEX';
SET @CurrentCommand += ') WITH ALL_ERRORMSGS';
IF @DataPurity = 'Y' SET @CurrentCommand += ', DATA_PURITY';
IF @PhysicalOnly = 'Y' SET @CurrentCommand += ', PHYSICAL_ONLY';
IF @ExtendedLogicalChecks = 'Y' SET @CurrentCommand += ', EXTENDED_LOGICAL_CHECKS';
IF @NoInformationalMessages = 'Y' SET @CurrentCommand += ', NO_INFOMSGS';
IF @TabLock = 'Y' SET @CurrentCommand += ', TABLOCK';
IF @MaxDOP IS NOT NULL SET @CurrentCommand += ', MAXDOP = ' + CAST(@MaxDOP AS NVARCHAR);
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseContext, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 1, @DatabaseName = @CurrentDatabaseName, @SchemaName = @CurrentSchemaName, @ObjectName = @CurrentObjectName, @ObjectType = @CurrentObjectType, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
END;
UPDATE @tmpObjects
SET Completed = 1
WHERE Selected = 1
AND Completed = 0
AND [Id] = @CurrentOID;
SET @CurrentOID = NULL;
SET @CurrentSchemaID = NULL;
SET @CurrentSchemaName = NULL;
SET @CurrentObjectID = NULL;
SET @CurrentObjectName = NULL;
SET @CurrentObjectType = NULL;
SET @CurrentObjectExists = NULL;
SET @CurrentDatabaseContext = NULL;
SET @CurrentCommand = NULL;
SET @CurrentCommandOutput = NULL;
SET @CurrentCommandType = NULL;
END;
END;
-- Check catalog
IF EXISTS(SELECT * FROM @SelectedCheckCommands WHERE CheckCommand = 'CHECKCATALOG') AND (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SET @CurrentDatabaseContext = CASE WHEN SERVERPROPERTY('EngineEdition') = 5 THEN @CurrentDatabaseName ELSE 'master' END;
SET @CurrentCommandType = 'DBCC_CHECKCATALOG';
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'DBCC CHECKCATALOG (' + QUOTENAME(@CurrentDatabaseName);
SET @CurrentCommand += ')';
IF @NoInformationalMessages = 'Y' SET @CurrentCommand += ' WITH NO_INFOMSGS';
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseContext, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 1, @DatabaseName = @CurrentDatabaseName, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
END;
END;
IF @CurrentDatabaseState = 'SUSPECT'
BEGIN
SET @ErrorMessage = 'The database ' + QUOTENAME(@CurrentDatabaseName) + ' is in a SUSPECT state.';
RAISERROR('%s',16,1,@ErrorMessage) WITH NOWAIT;
SET @Error = @@ERROR;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
END;
-- Update that the database is completed
IF @DatabasesInParallel = 'Y'
BEGIN
UPDATE [dbo].QueueDatabase
SET DatabaseEndTime = SYSDATETIME()
WHERE QueueID = @QueueID
AND DatabaseName = @CurrentDatabaseName;
END;
ELSE
BEGIN
UPDATE @tmpDatabases
SET Completed = 1
WHERE Selected = 1
AND Completed = 0
AND [Id] = @CurrentDBID;
END;
-- Clear variables
SET @CurrentDBID = NULL;
SET @CurrentDatabaseName = NULL;
SET @CurrentDatabase_sp_executesql = NULL;
SET @CurrentUserAccess = NULL;
SET @CurrentIsReadOnly = NULL;
SET @CurrentDatabaseState = NULL;
SET @CurrentInStandby = NULL;
SET @CurrentRecoveryModel = NULL;
SET @CurrentReplicaID = NULL;
SET @CurrentAvailabilityGroupID = NULL;
SET @CurrentAvailabilityGroup = NULL;
SET @CurrentAvailabilityGroupRole = NULL;
SET @CurrentAvailabilityGroupBackupPreference = NULL;
SET @CurrentSecondaryRoleAllowConnections = NULL;
SET @CurrentIsPreferredBackupReplica = NULL;
SET @CurrentDatabaseMirroringRole = NULL;
SET @CurrentDatabaseContext = NULL;
SET @CurrentCommand = NULL;
SET @CurrentCommandOutput = NULL;
SET @CurrentCommandType = NULL;
DELETE FROM @tmpFileGroups;
DELETE FROM @tmpObjects;
END;
----------------------------------------------------------------------------------------------------
--// Log completing information //--
----------------------------------------------------------------------------------------------------
Logging:;
SET @EndMessage = 'Date and time: ' + CONVERT(NVARCHAR,SYSDATETIME(),120);
RAISERROR('%s',10,1,@EndMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF @ReturnCode <> 0
BEGIN
RETURN @ReturnCode;
END;
----------------------------------------------------------------------------------------------------
END;
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
IF NOT EXISTS (SELECT * FROM [sys].[objects] WHERE OBJECT_ID = OBJECT_ID(N'[dbo].[IndexOptimize]') AND TYPE IN (N'P', N'PC'))
BEGIN
EXECUTE [dbo].sp_executesql @statement = N'CREATE PROCEDURE [dbo].[IndexOptimize] AS';
END;
GO
ALTER PROCEDURE [dbo].[IndexOptimize]
@Databases NVARCHAR(MAX) = NULL,
@FragmentationLow NVARCHAR(MAX) = NULL,
@FragmentationMedium NVARCHAR(MAX) = 'INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationHigh NVARCHAR(MAX) = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationLevel1 INT = 5,
@FragmentationLevel2 INT = 30,
@MinNumberOfPages INT = 1000,
@MaxNumberOfPages INT = NULL,
@SortInTempdb NVARCHAR(MAX) = 'N',
@MaxDOP INT = NULL,
@FillFactor INT = NULL,
@PadIndex NVARCHAR(MAX) = NULL,
@LOBCompaction NVARCHAR(MAX) = 'Y',
@UpdateStatistics NVARCHAR(MAX) = NULL,
@OnlyModifiedStatistics NVARCHAR(MAX) = 'N',
@StatisticsModificationLevel INT = NULL,
@StatisticsSample INT = NULL,
@StatisticsResample NVARCHAR(MAX) = 'N',
@PartitionLevel NVARCHAR(MAX) = 'Y',
@MSShippedObjects NVARCHAR(MAX) = 'N',
@Indexes NVARCHAR(MAX) = NULL,
@TimeLimit INT = NULL,
@Delay INT = NULL,
@WaitAtLowPriorityMaxDuration INT = NULL,
@WaitAtLowPriorityAbortAfterWait NVARCHAR(MAX) = NULL,
@Resumable NVARCHAR(MAX) = 'N',
@AvailabilityGroups NVARCHAR(MAX) = NULL,
@LockTimeout INT = NULL,
@LockMessageSeverity INT = 16,
@StringDelimiter NVARCHAR(MAX) = ',',
@DatabaseOrder NVARCHAR(MAX) = NULL,
@DatabasesInParallel NVARCHAR(MAX) = 'N',
@ExecuteAsUser NVARCHAR(MAX) = NULL,
@LogToTable NVARCHAR(MAX) = 'N',
@Execute NVARCHAR(MAX) = 'Y'
AS
BEGIN
----------------------------------------------------------------------------------------------------
--// Source: https://ola.hallengren.com //--
--// License: https://ola.hallengren.com/license.html //--
--// GitHub: https://github.com/olahallengren/sql-server-maintenance-solution //--
--// Version: 2025-07-22 16:49:16 //--
----------------------------------------------------------------------------------------------------
SET NOCOUNT ON;
SET ARITHABORT ON;
SET NUMERIC_ROUNDABORT OFF;
DECLARE @StartMessage NVARCHAR(MAX);
DECLARE @EndMessage NVARCHAR(MAX);
DECLARE @DatabaseMessage NVARCHAR(MAX);
DECLARE @ErrorMessage NVARCHAR(MAX);
DECLARE @Severity INT;
DECLARE @StartTime DATETIME2 = SYSDATETIME();
DECLARE @SchemaName NVARCHAR(MAX) = OBJECT_SCHEMA_NAME(@@PROCID);
DECLARE @ObjectName NVARCHAR(MAX) = OBJECT_NAME(@@PROCID);
DECLARE @VersionTimestamp NVARCHAR(MAX) = SUBSTRING(OBJECT_DEFINITION(@@PROCID),CHARINDEX('--// Version: ',OBJECT_DEFINITION(@@PROCID)) + LEN('--// Version: ') + 1, 19);
DECLARE @Parameters NVARCHAR(MAX);
DECLARE @HostPlatform NVARCHAR(MAX);
DECLARE @PartitionLevelStatistics BIT;
DECLARE @QueueID INT;
DECLARE @QueueStartTime DATETIME2;
DECLARE @CurrentDBID INT;
DECLARE @CurrentDatabaseName NVARCHAR(MAX);
DECLARE @CurrentDatabase_sp_executesql NVARCHAR(MAX);
DECLARE @CurrentExecuteAsUserExists BIT;
DECLARE @CurrentUserAccess NVARCHAR(MAX);
DECLARE @CurrentIsReadOnly BIT;
DECLARE @CurrentDatabaseState NVARCHAR(MAX);
DECLARE @CurrentInStandby BIT;
DECLARE @CurrentRecoveryModel NVARCHAR(MAX);
DECLARE @CurrentReplicaID UNIQUEIDENTIFIER;
DECLARE @CurrentAvailabilityGroupID UNIQUEIDENTIFIER;
DECLARE @CurrentAvailabilityGroup NVARCHAR(MAX);
DECLARE @CurrentAvailabilityGroupRole NVARCHAR(MAX);
DECLARE @CurrentDatabaseMirroringRole NVARCHAR(MAX);
DECLARE @CurrentDatabaseContext NVARCHAR(MAX);
DECLARE @CurrentCommand NVARCHAR(MAX);
DECLARE @CurrentCommandOutput INT;
DECLARE @CurrentCommandType NVARCHAR(MAX);
DECLARE @CurrentComment NVARCHAR(MAX);
DECLARE @CurrentExtendedInfo XML;
DECLARE @Errors TABLE ([Id] INT IDENTITY PRIMARY KEY,
[Message] NVARCHAR(MAX) NOT NULL,
[severity] INT NOT NULL,
[State] INT);
DECLARE @CurrentMessage NVARCHAR(MAX);
DECLARE @CurrentSeverity INT;
DECLARE @CurrentState INT;
DECLARE @CurrentIxID INT;
DECLARE @CurrentIxOrder INT;
DECLARE @CurrentSchemaID INT;
DECLARE @CurrentSchemaName NVARCHAR(MAX);
DECLARE @CurrentObjectID INT;
DECLARE @CurrentObjectName NVARCHAR(MAX);
DECLARE @CurrentObjectType NVARCHAR(MAX);
DECLARE @CurrentIsMemoryOptimized BIT;
DECLARE @CurrentIndexID INT;
DECLARE @CurrentIndexName NVARCHAR(MAX);
DECLARE @CurrentIndexType INT;
DECLARE @CurrentStatisticsID INT;
DECLARE @CurrentStatisticsName NVARCHAR(MAX);
DECLARE @CurrentPartitionID BIGINT;
DECLARE @CurrentPartitionNumber INT;
DECLARE @CurrentPartitionCount INT;
DECLARE @CurrentIsPartition BIT;
DECLARE @CurrentIndexExists BIT;
DECLARE @CurrentStatisticsExists BIT;
DECLARE @CurrentIsImageText BIT;
DECLARE @CurrentIsNewLOB BIT;
DECLARE @CurrentIsFileStream BIT;
DECLARE @CurrentHasClusteredColumnstore BIT;
DECLARE @CurrentHasNonClusteredColumnstore BIT;
DECLARE @CurrentIsComputed BIT;
DECLARE @CurrentIsClusteredIndexComputed BIT;
DECLARE @CurrentIsTimestamp BIT;
DECLARE @CurrentAllowPageLocks BIT;
DECLARE @CurrentHasFilter BIT;
DECLARE @CurrentNoRecompute BIT;
DECLARE @CurrentIsIncremental BIT;
DECLARE @CurrentRowCount BIGINT;
DECLARE @CurrentModificationCounter BIGINT;
DECLARE @CurrentOnReadOnlyFileGroup BIT;
DECLARE @CurrentResumableIndexOperation BIT;
DECLARE @CurrentFragmentationLevel FLOAT;
DECLARE @CurrentPageCount BIGINT;
DECLARE @CurrentFragmentationGroup NVARCHAR(MAX);
DECLARE @CurrentAction NVARCHAR(MAX);
DECLARE @CurrentMaxDOP INT;
DECLARE @CurrentUpdateStatistics NVARCHAR(MAX);
DECLARE @CurrentStatisticsSample INT;
DECLARE @CurrentStatisticsResample NVARCHAR(MAX);
DECLARE @CurrentDelay DATETIME;
DECLARE @tmpDatabases TABLE ([Id] INT IDENTITY,
DatabaseName NVARCHAR(MAX),
DatabaseType NVARCHAR(MAX),
AvailabilityGroup BIT,
StartPosition INT,
DatabaseSize BIGINT,
[Order] INT,
Selected BIT,
Completed BIT,
PRIMARY KEY(Selected, Completed, [Order], [Id]));
DECLARE @tmpAvailabilityGroups TABLE ([Id] INT IDENTITY PRIMARY KEY,
AvailabilityGroupName NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @tmpDatabasesAvailabilityGroups TABLE (DatabaseName NVARCHAR(MAX),
AvailabilityGroupName NVARCHAR(MAX));
DECLARE @tmpIndexesStatistics TABLE ([Id] INT IDENTITY,
SchemaID INT,
SchemaName NVARCHAR(MAX),
[objectid] INT,
ObjectName NVARCHAR(MAX),
ObjectType NVARCHAR(MAX),
IsMemoryOptimized BIT,
[indexid] INT,
IndexName NVARCHAR(MAX),
IndexType INT,
AllowPageLocks BIT,
HasFilter BIT,
IsImageText BIT,
IsNewLOB BIT,
IsFileStream BIT,
HasClusteredColumnstore BIT,
HasNonClusteredColumnstore BIT,
[iscomputed] BIT,
IsClusteredIndexComputed BIT,
IsTimestamp BIT,
OnReadOnlyFileGroup BIT,
ResumableIndexOperation BIT,
StatisticsID INT,
StatisticsName NVARCHAR(MAX),
[NoRecompute] BIT,
IsIncremental BIT,
PartitionID BIGINT,
PartitionNumber INT,
PartitionCount INT,
StartPosition INT,
[Order] INT,
Selected BIT,
Completed BIT,
PRIMARY KEY(Selected, Completed, [Order], [Id]));
DECLARE @SelectedDatabases TABLE (DatabaseName NVARCHAR(MAX),
DatabaseType NVARCHAR(MAX),
AvailabilityGroup NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @SelectedAvailabilityGroups TABLE (AvailabilityGroupName NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @SelectedIndexes TABLE (DatabaseName NVARCHAR(MAX),
SchemaName NVARCHAR(MAX),
ObjectName NVARCHAR(MAX),
IndexName NVARCHAR(MAX),
StartPosition INT,
Selected BIT);
DECLARE @Actions TABLE ([Action] NVARCHAR(MAX));
INSERT INTO @Actions([Action]) VALUES('INDEX_REBUILD_ONLINE');
INSERT INTO @Actions([Action]) VALUES('INDEX_REBUILD_OFFLINE');
INSERT INTO @Actions([Action]) VALUES('INDEX_REORGANIZE');
DECLARE @ActionsPreferred TABLE (FragmentationGroup NVARCHAR(MAX),
[Priority] INT,
[Action] NVARCHAR(MAX));
DECLARE @CurrentActionsAllowed TABLE ([Action] NVARCHAR(MAX));
DECLARE @CurrentAlterIndexWithClauseArguments TABLE ([Id] INT IDENTITY,
Argument NVARCHAR(MAX),
Added BIT DEFAULT 0);
DECLARE @CurrentAlterIndexArgumentID INT;
DECLARE @CurrentAlterIndexArgument NVARCHAR(MAX);
DECLARE @CurrentAlterIndexWithClause NVARCHAR(MAX);
DECLARE @CurrentUpdateStatisticsWithClauseArguments TABLE ([Id] INT IDENTITY,
Argument NVARCHAR(MAX),
Added BIT DEFAULT 0);
DECLARE @CurrentUpdateStatisticsArgumentID INT;
DECLARE @CurrentUpdateStatisticsArgument NVARCHAR(MAX);
DECLARE @CurrentUpdateStatisticsWithClause NVARCHAR(MAX);
DECLARE @Error INT = 0;
DECLARE @ReturnCode INT = 0;
DECLARE @EmptyLine NVARCHAR(MAX) = CHAR(9);
DECLARE @Version NUMERIC(18,10) = CAST(LEFT(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)),CHARINDEX('.',CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX))) - 1) + '.' + REPLACE(RIGHT(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)), LEN(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX))) - CHARINDEX('.',CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)))),'.','') AS NUMERIC(18,10));
IF @Version >= 14
BEGIN
SELECT @HostPlatform = [host_platform]
FROM [sys].[dm_os_host_info];
END;
ELSE
BEGIN
SET @HostPlatform = 'Windows';
END;
DECLARE @AmazonRDS BIT = CASE WHEN SERVERPROPERTY('EngineEdition') IN (5, 8) THEN 0 WHEN EXISTS (SELECT * FROM [sys].[databases] WHERE [name] = 'rdsadmin') AND SUSER_SNAME(0x01) = 'rdsa' THEN 1 ELSE 0 END;
----------------------------------------------------------------------------------------------------
--// Log initial information //--
----------------------------------------------------------------------------------------------------
SET @Parameters = '@Databases = ' + ISNULL('''' + REPLACE(@Databases,'''','''''') + '''','NULL');
SET @Parameters += ', @FragmentationLow = ' + ISNULL('''' + REPLACE(@FragmentationLow,'''','''''') + '''','NULL');
SET @Parameters += ', @FragmentationMedium = ' + ISNULL('''' + REPLACE(@FragmentationMedium,'''','''''') + '''','NULL');
SET @Parameters += ', @FragmentationHigh = ' + ISNULL('''' + REPLACE(@FragmentationHigh,'''','''''') + '''','NULL');
SET @Parameters += ', @FragmentationLevel1 = ' + ISNULL(CAST(@FragmentationLevel1 AS NVARCHAR),'NULL');
SET @Parameters += ', @FragmentationLevel2 = ' + ISNULL(CAST(@FragmentationLevel2 AS NVARCHAR),'NULL');
SET @Parameters += ', @MinNumberOfPages = ' + ISNULL(CAST(@MinNumberOfPages AS NVARCHAR),'NULL');
SET @Parameters += ', @MaxNumberOfPages = ' + ISNULL(CAST(@MaxNumberOfPages AS NVARCHAR),'NULL');
SET @Parameters += ', @SortInTempdb = ' + ISNULL('''' + REPLACE(@SortInTempdb,'''','''''') + '''','NULL');
SET @Parameters += ', @MaxDOP = ' + ISNULL(CAST(@MaxDOP AS NVARCHAR),'NULL');
SET @Parameters += ', @FillFactor = ' + ISNULL(CAST(@FillFactor AS NVARCHAR),'NULL');
SET @Parameters += ', @PadIndex = ' + ISNULL('''' + REPLACE(@PadIndex,'''','''''') + '''','NULL');
SET @Parameters += ', @LOBCompaction = ' + ISNULL('''' + REPLACE(@LOBCompaction,'''','''''') + '''','NULL');
SET @Parameters += ', @UpdateStatistics = ' + ISNULL('''' + REPLACE(@UpdateStatistics,'''','''''') + '''','NULL');
SET @Parameters += ', @OnlyModifiedStatistics = ' + ISNULL('''' + REPLACE(@OnlyModifiedStatistics,'''','''''') + '''','NULL');
SET @Parameters += ', @StatisticsModificationLevel = ' + ISNULL(CAST(@StatisticsModificationLevel AS NVARCHAR),'NULL');
SET @Parameters += ', @StatisticsSample = ' + ISNULL(CAST(@StatisticsSample AS NVARCHAR),'NULL');
SET @Parameters += ', @StatisticsResample = ' + ISNULL('''' + REPLACE(@StatisticsResample,'''','''''') + '''','NULL');
SET @Parameters += ', @PartitionLevel = ' + ISNULL('''' + REPLACE(@PartitionLevel,'''','''''') + '''','NULL');
SET @Parameters += ', @MSShippedObjects = ' + ISNULL('''' + REPLACE(@MSShippedObjects,'''','''''') + '''','NULL');
SET @Parameters += ', @Indexes = ' + ISNULL('''' + REPLACE(@Indexes,'''','''''') + '''','NULL');
SET @Parameters += ', @TimeLimit = ' + ISNULL(CAST(@TimeLimit AS NVARCHAR),'NULL');
SET @Parameters += ', @Delay = ' + ISNULL(CAST(@Delay AS NVARCHAR),'NULL');
SET @Parameters += ', @WaitAtLowPriorityMaxDuration = ' + ISNULL(CAST(@WaitAtLowPriorityMaxDuration AS NVARCHAR),'NULL');
SET @Parameters += ', @WaitAtLowPriorityAbortAfterWait = ' + ISNULL('''' + REPLACE(@WaitAtLowPriorityAbortAfterWait,'''','''''') + '''','NULL');
SET @Parameters += ', @Resumable = ' + ISNULL('''' + REPLACE(@Resumable,'''','''''') + '''','NULL');
SET @Parameters += ', @AvailabilityGroups = ' + ISNULL('''' + REPLACE(@AvailabilityGroups,'''','''''') + '''','NULL');
SET @Parameters += ', @LockTimeout = ' + ISNULL(CAST(@LockTimeout AS NVARCHAR),'NULL');
SET @Parameters += ', @LockMessageSeverity = ' + ISNULL(CAST(@LockMessageSeverity AS NVARCHAR),'NULL');
SET @Parameters += ', @StringDelimiter = ' + ISNULL('''' + REPLACE(@StringDelimiter,'''','''''') + '''','NULL');
SET @Parameters += ', @DatabaseOrder = ' + ISNULL('''' + REPLACE(@DatabaseOrder,'''','''''') + '''','NULL');
SET @Parameters += ', @DatabasesInParallel = ' + ISNULL('''' + REPLACE(@DatabasesInParallel,'''','''''') + '''','NULL');
SET @Parameters += ', @ExecuteAsUser = ' + ISNULL('''' + REPLACE(@ExecuteAsUser,'''','''''') + '''','NULL');
SET @Parameters += ', @LogToTable = ' + ISNULL('''' + REPLACE(@LogToTable,'''','''''') + '''','NULL');
SET @Parameters += ', @Execute = ' + ISNULL('''' + REPLACE(@Execute,'''','''''') + '''','NULL');
SET @StartMessage = 'Date and time: ' + CONVERT(NVARCHAR,@StartTime,120);
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Server: ' + CAST(SERVERPROPERTY('ServerName') AS NVARCHAR(MAX));
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Version: ' + CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX));
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Edition: ' + CAST(SERVERPROPERTY('Edition') AS NVARCHAR(MAX));
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Platform: ' + @HostPlatform;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Procedure: ' + QUOTENAME(DB_NAME()) + '.' + QUOTENAME(@SchemaName) + '.' + QUOTENAME(@ObjectName);
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Parameters: ' + @Parameters;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Version: ' + @VersionTimestamp;
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
SET @StartMessage = 'Source: https://ola.hallengren.com';
RAISERROR('%s',10,1,@StartMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
----------------------------------------------------------------------------------------------------
--// Check core requirements //--
----------------------------------------------------------------------------------------------------
IF NOT (SELECT [compatibility_level] FROM [sys].[databases] WHERE [name] = DB_NAME()) >= 90
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The database ' + QUOTENAME(DB_NAME()) + ' has to be in compatibility level 90 or higher.', 16, 1;
END;
IF NOT (SELECT [uses_ansi_nulls] FROM [sys].[sql_modules] WHERE [object_id] = @@PROCID) = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'ANSI_NULLS has to be set to ON for the stored procedure.', 16, 1;
END;
IF NOT (SELECT [uses_quoted_identifier] FROM [sys].[sql_modules] WHERE [object_id] = @@PROCID) = 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'QUOTED_IDENTIFIER has to be set to ON for the stored procedure.', 16, 1;
END;
IF NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'P' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'CommandExecute')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The stored procedure CommandExecute is missing. Download https://ola.hallengren.com/scripts/CommandExecute.sql.', 16, 1;
END;
IF EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'P' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'CommandExecute' AND OBJECT_DEFINITION([objects].[object_id]) NOT LIKE '%@DatabaseContext%')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The stored procedure CommandExecute needs to be updated. Download https://ola.hallengren.com/scripts/CommandExecute.sql.', 16, 1;
END;
IF @LogToTable = 'Y' AND NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'U' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'CommandLog')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The table CommandLog is missing. Download https://ola.hallengren.com/scripts/CommandLog.sql.', 16, 1;
END;
IF @DatabasesInParallel = 'Y' AND NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'U' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'Queue')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The table Queue is missing. Download https://ola.hallengren.com/scripts/Queue.sql.', 16, 1;
END;
IF @DatabasesInParallel = 'Y' AND NOT EXISTS (SELECT * FROM [sys].[objects] [objects] INNER JOIN [sys].[schemas] [schemas] ON [objects].[schema_id] = [schemas].[schema_id] WHERE [objects].[type] = 'U' AND [schemas].[name] = 'dbo' AND [objects].[name] = 'QueueDatabase')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The table QueueDatabase is missing. Download https://ola.hallengren.com/scripts/QueueDatabase.sql.', 16, 1;
END;
IF @@TRANCOUNT <> 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The transaction count is not 0.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Select databases //--
----------------------------------------------------------------------------------------------------
SET @Databases = REPLACE(@Databases, CHAR(10), '');
SET @Databases = REPLACE(@Databases, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @Databases) > 0 SET @Databases = REPLACE(@Databases, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @Databases) > 0 SET @Databases = REPLACE(@Databases, ' ' + @StringDelimiter, @StringDelimiter);
SET @Databases = LTRIM(RTRIM(@Databases));
WITH Databases1 (StartPosition, EndPosition, DatabaseItem) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, 1), 0), LEN(@Databases) + 1) AS EndPosition,
SUBSTRING(@Databases, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, 1), 0), LEN(@Databases) + 1) - 1) AS DatabaseItem
WHERE @Databases IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, EndPosition + 1), 0), LEN(@Databases) + 1) AS EndPosition,
SUBSTRING(@Databases, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Databases, EndPosition + 1), 0), LEN(@Databases) + 1) - EndPosition - 1) AS DatabaseItem
FROM Databases1
WHERE EndPosition < LEN(@Databases) + 1
),
Databases2 (DatabaseItem, StartPosition, Selected) AS
(
SELECT CASE WHEN DatabaseItem LIKE '-%' THEN RIGHT(DatabaseItem,LEN(DatabaseItem) - 1) ELSE DatabaseItem END AS DatabaseItem,
StartPosition,
CASE WHEN DatabaseItem LIKE '-%' THEN 0 ELSE 1 END AS Selected
FROM Databases1
),
Databases3 (DatabaseItem, DatabaseType, AvailabilityGroup, StartPosition, Selected) AS
(
SELECT CASE WHEN DatabaseItem IN('ALL_DATABASES','SYSTEM_DATABASES','USER_DATABASES','AVAILABILITY_GROUP_DATABASES') THEN '%' ELSE DatabaseItem END AS DatabaseItem,
CASE WHEN DatabaseItem = 'SYSTEM_DATABASES' THEN 'S' WHEN DatabaseItem = 'USER_DATABASES' THEN 'U' ELSE NULL END AS DatabaseType,
CASE WHEN DatabaseItem = 'AVAILABILITY_GROUP_DATABASES' THEN 1 ELSE NULL END AvailabilityGroup,
StartPosition,
Selected
FROM Databases2
),
Databases4 (DatabaseName, DatabaseType, AvailabilityGroup, StartPosition, Selected) AS
(
SELECT CASE WHEN LEFT(DatabaseItem,1) = '[' AND RIGHT(DatabaseItem,1) = ']' THEN PARSENAME(DatabaseItem,1) ELSE DatabaseItem END AS DatabaseItem,
DatabaseType,
AvailabilityGroup,
StartPosition,
Selected
FROM Databases3
)
INSERT INTO @SelectedDatabases (DatabaseName, DatabaseType, AvailabilityGroup, StartPosition, Selected)
SELECT DatabaseName,
DatabaseType,
AvailabilityGroup,
StartPosition,
Selected
FROM Databases4
OPTION (MAXRECURSION 0);
IF @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
INSERT INTO @tmpAvailabilityGroups (AvailabilityGroupName, Selected)
SELECT [name] AS AvailabilityGroupName,
0 AS Selected
FROM [sys].[availability_groups];
INSERT INTO @tmpDatabasesAvailabilityGroups (DatabaseName, AvailabilityGroupName)
SELECT [databases].[name],
[availability_groups].[name]
FROM [sys].[databases] [databases]
INNER JOIN [sys].[availability_replicas] [availability_replicas] ON [databases].[replica_id] = [availability_replicas].[replica_id]
INNER JOIN [sys].[availability_groups] [availability_groups] ON [availability_replicas].[group_id] = [availability_groups].[group_id];
END;
INSERT INTO @tmpDatabases (DatabaseName, DatabaseType, AvailabilityGroup, [Order], Selected, Completed)
SELECT [name] AS DatabaseName,
CASE WHEN [name] IN('master','msdb','model') OR [is_distributor] = 1 THEN 'S' ELSE 'U' END AS DatabaseType,
NULL AS AvailabilityGroup,
0 AS [Order],
0 AS Selected,
0 AS Completed
FROM [sys].[databases]
WHERE [name] <> 'tempdb'
AND [source_database_id] IS NULL
ORDER BY [name] ASC;
UPDATE tmpDatabases
SET AvailabilityGroup = CASE WHEN EXISTS (SELECT * FROM @tmpDatabasesAvailabilityGroups WHERE DatabaseName = tmpDatabases.DatabaseName) THEN 1 ELSE 0 END
FROM @tmpDatabases tmpDatabases;
UPDATE tmpDatabases
SET tmpDatabases.Selected = SelectedDatabases.Selected
FROM @tmpDatabases tmpDatabases
INNER JOIN @SelectedDatabases SelectedDatabases
ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]')
AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL)
AND (tmpDatabases.AvailabilityGroup = SelectedDatabases.AvailabilityGroup OR SelectedDatabases.AvailabilityGroup IS NULL)
WHERE SelectedDatabases.Selected = 1;
UPDATE tmpDatabases
SET tmpDatabases.Selected = SelectedDatabases.Selected
FROM @tmpDatabases tmpDatabases
INNER JOIN @SelectedDatabases SelectedDatabases
ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]')
AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL)
AND (tmpDatabases.AvailabilityGroup = SelectedDatabases.AvailabilityGroup OR SelectedDatabases.AvailabilityGroup IS NULL)
WHERE SelectedDatabases.Selected = 0;
UPDATE tmpDatabases
SET tmpDatabases.StartPosition = SelectedDatabases2.StartPosition
FROM @tmpDatabases tmpDatabases
INNER JOIN (SELECT tmpDatabases.DatabaseName, MIN(SelectedDatabases.StartPosition) AS StartPosition
FROM @tmpDatabases tmpDatabases
INNER JOIN @SelectedDatabases SelectedDatabases
ON tmpDatabases.DatabaseName LIKE REPLACE(SelectedDatabases.DatabaseName,'_','[_]')
AND (tmpDatabases.DatabaseType = SelectedDatabases.DatabaseType OR SelectedDatabases.DatabaseType IS NULL)
AND (tmpDatabases.AvailabilityGroup = SelectedDatabases.AvailabilityGroup OR SelectedDatabases.AvailabilityGroup IS NULL)
WHERE SelectedDatabases.Selected = 1
GROUP BY tmpDatabases.DatabaseName) SelectedDatabases2
ON tmpDatabases.DatabaseName = SelectedDatabases2.DatabaseName;
IF @Databases IS NOT NULL AND (NOT EXISTS(SELECT * FROM @SelectedDatabases) OR EXISTS(SELECT * FROM @SelectedDatabases WHERE DatabaseName IS NULL OR DATALENGTH(DatabaseName) = 0))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Databases is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Select availability groups //--
----------------------------------------------------------------------------------------------------
IF @AvailabilityGroups IS NOT NULL AND @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, CHAR(10), '');
SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @AvailabilityGroups) > 0 SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @AvailabilityGroups) > 0 SET @AvailabilityGroups = REPLACE(@AvailabilityGroups, ' ' + @StringDelimiter, @StringDelimiter);
SET @AvailabilityGroups = LTRIM(RTRIM(@AvailabilityGroups));
WITH AvailabilityGroups1 (StartPosition, EndPosition, AvailabilityGroupItem) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, 1), 0), LEN(@AvailabilityGroups) + 1) AS EndPosition,
SUBSTRING(@AvailabilityGroups, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, 1), 0), LEN(@AvailabilityGroups) + 1) - 1) AS AvailabilityGroupItem
WHERE @AvailabilityGroups IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, EndPosition + 1), 0), LEN(@AvailabilityGroups) + 1) AS EndPosition,
SUBSTRING(@AvailabilityGroups, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @AvailabilityGroups, EndPosition + 1), 0), LEN(@AvailabilityGroups) + 1) - EndPosition - 1) AS AvailabilityGroupItem
FROM AvailabilityGroups1
WHERE EndPosition < LEN(@AvailabilityGroups) + 1
),
AvailabilityGroups2 (AvailabilityGroupItem, StartPosition, Selected) AS
(
SELECT CASE WHEN AvailabilityGroupItem LIKE '-%' THEN RIGHT(AvailabilityGroupItem,LEN(AvailabilityGroupItem) - 1) ELSE AvailabilityGroupItem END AS AvailabilityGroupItem,
StartPosition,
CASE WHEN AvailabilityGroupItem LIKE '-%' THEN 0 ELSE 1 END AS Selected
FROM AvailabilityGroups1
),
AvailabilityGroups3 (AvailabilityGroupItem, StartPosition, Selected) AS
(
SELECT CASE WHEN AvailabilityGroupItem = 'ALL_AVAILABILITY_GROUPS' THEN '%' ELSE AvailabilityGroupItem END AS AvailabilityGroupItem,
StartPosition,
Selected
FROM AvailabilityGroups2
),
AvailabilityGroups4 (AvailabilityGroupName, StartPosition, Selected) AS
(
SELECT CASE WHEN LEFT(AvailabilityGroupItem,1) = '[' AND RIGHT(AvailabilityGroupItem,1) = ']' THEN PARSENAME(AvailabilityGroupItem,1) ELSE AvailabilityGroupItem END AS AvailabilityGroupItem,
StartPosition,
Selected
FROM AvailabilityGroups3
)
INSERT INTO @SelectedAvailabilityGroups (AvailabilityGroupName, StartPosition, Selected)
SELECT AvailabilityGroupName, StartPosition, Selected
FROM AvailabilityGroups4
OPTION (MAXRECURSION 0);
UPDATE tmpAvailabilityGroups
SET tmpAvailabilityGroups.Selected = SelectedAvailabilityGroups.Selected
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN @SelectedAvailabilityGroups SelectedAvailabilityGroups
ON tmpAvailabilityGroups.AvailabilityGroupName LIKE REPLACE(SelectedAvailabilityGroups.AvailabilityGroupName,'_','[_]')
WHERE SelectedAvailabilityGroups.Selected = 1;
UPDATE tmpAvailabilityGroups
SET tmpAvailabilityGroups.Selected = SelectedAvailabilityGroups.Selected
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN @SelectedAvailabilityGroups SelectedAvailabilityGroups
ON tmpAvailabilityGroups.AvailabilityGroupName LIKE REPLACE(SelectedAvailabilityGroups.AvailabilityGroupName,'_','[_]')
WHERE SelectedAvailabilityGroups.Selected = 0;
UPDATE tmpAvailabilityGroups
SET tmpAvailabilityGroups.StartPosition = SelectedAvailabilityGroups2.StartPosition
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN (SELECT tmpAvailabilityGroups.AvailabilityGroupName, MIN(SelectedAvailabilityGroups.StartPosition) AS StartPosition
FROM @tmpAvailabilityGroups tmpAvailabilityGroups
INNER JOIN @SelectedAvailabilityGroups SelectedAvailabilityGroups
ON tmpAvailabilityGroups.AvailabilityGroupName LIKE REPLACE(SelectedAvailabilityGroups.AvailabilityGroupName,'_','[_]')
WHERE SelectedAvailabilityGroups.Selected = 1
GROUP BY tmpAvailabilityGroups.AvailabilityGroupName) SelectedAvailabilityGroups2
ON tmpAvailabilityGroups.AvailabilityGroupName = SelectedAvailabilityGroups2.AvailabilityGroupName;
UPDATE tmpDatabases
SET tmpDatabases.StartPosition = tmpAvailabilityGroups.StartPosition,
tmpDatabases.Selected = 1
FROM @tmpDatabases tmpDatabases
INNER JOIN @tmpDatabasesAvailabilityGroups tmpDatabasesAvailabilityGroups ON tmpDatabases.DatabaseName = tmpDatabasesAvailabilityGroups.DatabaseName
INNER JOIN @tmpAvailabilityGroups tmpAvailabilityGroups ON tmpDatabasesAvailabilityGroups.AvailabilityGroupName = tmpAvailabilityGroups.AvailabilityGroupName
WHERE tmpAvailabilityGroups.Selected = 1;
END;
IF @AvailabilityGroups IS NOT NULL AND (NOT EXISTS(SELECT * FROM @SelectedAvailabilityGroups) OR EXISTS(SELECT * FROM @SelectedAvailabilityGroups WHERE AvailabilityGroupName IS NULL OR AvailabilityGroupName = '') OR @Version < 11 OR SERVERPROPERTY('IsHadrEnabled') = 0)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @AvailabilityGroups is not supported.', 16, 1;
END;
IF (@Databases IS NULL AND @AvailabilityGroups IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'You need to specify one of the parameters @Databases and @AvailabilityGroups.', 16, 2;
END;
IF (@Databases IS NOT NULL AND @AvailabilityGroups IS NOT NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'You can only specify one of the parameters @Databases and @AvailabilityGroups.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
--// Select indexes //--
----------------------------------------------------------------------------------------------------
SET @Indexes = REPLACE(@Indexes, CHAR(10), '');
SET @Indexes = REPLACE(@Indexes, CHAR(13), '');
WHILE CHARINDEX(@StringDelimiter + ' ', @Indexes) > 0 SET @Indexes = REPLACE(@Indexes, @StringDelimiter + ' ', @StringDelimiter);
WHILE CHARINDEX(' ' + @StringDelimiter, @Indexes) > 0 SET @Indexes = REPLACE(@Indexes, ' ' + @StringDelimiter, @StringDelimiter);
SET @Indexes = LTRIM(RTRIM(@Indexes));
WITH Indexes1 (StartPosition, EndPosition, IndexItem) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Indexes, 1), 0), LEN(@Indexes) + 1) AS EndPosition,
SUBSTRING(@Indexes, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Indexes, 1), 0), LEN(@Indexes) + 1) - 1) AS IndexItem
WHERE @Indexes IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Indexes, EndPosition + 1), 0), LEN(@Indexes) + 1) AS EndPosition,
SUBSTRING(@Indexes, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @Indexes, EndPosition + 1), 0), LEN(@Indexes) + 1) - EndPosition - 1) AS IndexItem
FROM Indexes1
WHERE EndPosition < LEN(@Indexes) + 1
),
Indexes2 (IndexItem, StartPosition, Selected) AS
(
SELECT CASE WHEN IndexItem LIKE '-%' THEN RIGHT(IndexItem,LEN(IndexItem) - 1) ELSE IndexItem END AS IndexItem,
StartPosition,
CASE WHEN IndexItem LIKE '-%' THEN 0 ELSE 1 END AS Selected
FROM Indexes1
),
Indexes3 (IndexItem, StartPosition, Selected) AS
(
SELECT CASE WHEN IndexItem = 'ALL_INDEXES' THEN '%.%.%.%' ELSE IndexItem END AS IndexItem,
StartPosition,
Selected
FROM Indexes2
),
Indexes4 (DatabaseName, SchemaName, ObjectName, IndexName, StartPosition, Selected) AS
(
SELECT CASE WHEN PARSENAME(IndexItem,4) IS NULL THEN PARSENAME(IndexItem,3) ELSE PARSENAME(IndexItem,4) END AS DatabaseName,
CASE WHEN PARSENAME(IndexItem,4) IS NULL THEN PARSENAME(IndexItem,2) ELSE PARSENAME(IndexItem,3) END AS SchemaName,
CASE WHEN PARSENAME(IndexItem,4) IS NULL THEN PARSENAME(IndexItem,1) ELSE PARSENAME(IndexItem,2) END AS ObjectName,
CASE WHEN PARSENAME(IndexItem,4) IS NULL THEN '%' ELSE PARSENAME(IndexItem,1) END AS IndexName,
StartPosition,
Selected
FROM Indexes3
)
INSERT INTO @SelectedIndexes (DatabaseName, SchemaName, ObjectName, IndexName, StartPosition, Selected)
SELECT DatabaseName, SchemaName, ObjectName, IndexName, StartPosition, Selected
FROM Indexes4
OPTION (MAXRECURSION 0);
----------------------------------------------------------------------------------------------------
--// Select actions //--
----------------------------------------------------------------------------------------------------
SET @FragmentationLow = REPLACE(@FragmentationLow, @StringDelimiter + ' ', @StringDelimiter);
WITH FragmentationLow (StartPosition, EndPosition, [Action]) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationLow, 1), 0), LEN(@FragmentationLow) + 1) AS EndPosition,
SUBSTRING(@FragmentationLow, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationLow, 1), 0), LEN(@FragmentationLow) + 1) - 1) AS [Action]
WHERE @FragmentationLow IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationLow, EndPosition + 1), 0), LEN(@FragmentationLow) + 1) AS EndPosition,
SUBSTRING(@FragmentationLow, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationLow, EndPosition + 1), 0), LEN(@FragmentationLow) + 1) - EndPosition - 1) AS [Action]
FROM FragmentationLow
WHERE EndPosition < LEN(@FragmentationLow) + 1
)
INSERT INTO @ActionsPreferred(FragmentationGroup, [Priority], [Action])
SELECT 'Low' AS FragmentationGroup,
ROW_NUMBER() OVER(ORDER BY StartPosition ASC) AS [Priority],
[Action]
FROM FragmentationLow
OPTION (MAXRECURSION 0);
SET @FragmentationMedium = REPLACE(@FragmentationMedium, @StringDelimiter + ' ', @StringDelimiter);
WITH FragmentationMedium (StartPosition, EndPosition, [Action]) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationMedium, 1), 0), LEN(@FragmentationMedium) + 1) AS EndPosition,
SUBSTRING(@FragmentationMedium, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationMedium, 1), 0), LEN(@FragmentationMedium) + 1) - 1) AS [Action]
WHERE @FragmentationMedium IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationMedium, EndPosition + 1), 0), LEN(@FragmentationMedium) + 1) AS EndPosition,
SUBSTRING(@FragmentationMedium, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationMedium, EndPosition + 1), 0), LEN(@FragmentationMedium) + 1) - EndPosition - 1) AS [Action]
FROM FragmentationMedium
WHERE EndPosition < LEN(@FragmentationMedium) + 1
)
INSERT INTO @ActionsPreferred(FragmentationGroup, [Priority], [Action])
SELECT 'Medium' AS FragmentationGroup,
ROW_NUMBER() OVER(ORDER BY StartPosition ASC) AS [Priority],
[Action]
FROM FragmentationMedium
OPTION (MAXRECURSION 0);
SET @FragmentationHigh = REPLACE(@FragmentationHigh, @StringDelimiter + ' ', @StringDelimiter);
WITH FragmentationHigh (StartPosition, EndPosition, [Action]) AS
(
SELECT 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationHigh, 1), 0), LEN(@FragmentationHigh) + 1) AS EndPosition,
SUBSTRING(@FragmentationHigh, 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationHigh, 1), 0), LEN(@FragmentationHigh) + 1) - 1) AS [Action]
WHERE @FragmentationHigh IS NOT NULL
UNION ALL
SELECT CAST(EndPosition AS INT) + 1 AS StartPosition,
ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationHigh, EndPosition + 1), 0), LEN(@FragmentationHigh) + 1) AS EndPosition,
SUBSTRING(@FragmentationHigh, EndPosition + 1, ISNULL(NULLIF(CHARINDEX(@StringDelimiter, @FragmentationHigh, EndPosition + 1), 0), LEN(@FragmentationHigh) + 1) - EndPosition - 1) AS [Action]
FROM FragmentationHigh
WHERE EndPosition < LEN(@FragmentationHigh) + 1
)
INSERT INTO @ActionsPreferred(FragmentationGroup, [Priority], [Action])
SELECT 'High' AS FragmentationGroup,
ROW_NUMBER() OVER(ORDER BY StartPosition ASC) AS [Priority],
[Action]
FROM FragmentationHigh
OPTION (MAXRECURSION 0);
----------------------------------------------------------------------------------------------------
--// Check input parameters //--
----------------------------------------------------------------------------------------------------
IF EXISTS (SELECT [Action] FROM @ActionsPreferred WHERE FragmentationGroup = 'Low' AND [Action] NOT IN(SELECT * FROM @Actions))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FragmentationLow is not supported.', 16, 1;
END;
IF EXISTS (SELECT * FROM @ActionsPreferred WHERE FragmentationGroup = 'Low' GROUP BY [Action] HAVING COUNT(*) > 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FragmentationLow is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS (SELECT [Action] FROM @ActionsPreferred WHERE FragmentationGroup = 'Medium' AND [Action] NOT IN(SELECT * FROM @Actions))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FragmentationMedium is not supported.', 16, 1;
END;
IF EXISTS (SELECT * FROM @ActionsPreferred WHERE FragmentationGroup = 'Medium' GROUP BY [Action] HAVING COUNT(*) > 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FragmentationMedium is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS (SELECT [Action] FROM @ActionsPreferred WHERE FragmentationGroup = 'High' AND [Action] NOT IN(SELECT * FROM @Actions))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FragmentationHigh is not supported.', 16, 1;
END;
IF EXISTS (SELECT * FROM @ActionsPreferred WHERE FragmentationGroup = 'High' GROUP BY [Action] HAVING COUNT(*) > 1)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FragmentationHigh is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @FragmentationLevel1 <= 0 OR @FragmentationLevel1 >= 100 OR @FragmentationLevel1 IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FragmentationLevel1 is not supported.', 16, 1;
END;
IF @FragmentationLevel1 >= @FragmentationLevel2
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FragmentationLevel1 is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @FragmentationLevel2 <= 0 OR @FragmentationLevel2 >= 100 OR @FragmentationLevel2 IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FragmentationLevel2 is not supported.', 16, 1;
END;
IF @FragmentationLevel2 <= @FragmentationLevel1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FragmentationLevel2 is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @MinNumberOfPages < 0 OR @MinNumberOfPages IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MinNumberOfPages is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @MaxNumberOfPages < 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxNumberOfPages is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @SortInTempdb NOT IN('Y','N') OR @SortInTempdb IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @SortInTempdb is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @MaxDOP < 0 OR @MaxDOP > 64
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MaxDOP is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @FillFactor <= 0 OR @FillFactor > 100
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @FillFactor is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @PadIndex NOT IN('Y','N')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @PadIndex is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @LOBCompaction NOT IN('Y','N') OR @LOBCompaction IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LOBCompaction is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @UpdateStatistics NOT IN('ALL','COLUMNS','INDEX')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @UpdateStatistics is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @OnlyModifiedStatistics NOT IN('Y','N') OR @OnlyModifiedStatistics IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @OnlyModifiedStatistics is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @StatisticsModificationLevel <= 0 OR @StatisticsModificationLevel > 100
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @StatisticsModificationLevel is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @OnlyModifiedStatistics = 'Y' AND @StatisticsModificationLevel IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'You can only specify one of the parameters @OnlyModifiedStatistics and @StatisticsModificationLevel.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @StatisticsSample <= 0 OR @StatisticsSample > 100
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @StatisticsSample is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @StatisticsResample NOT IN('Y','N') OR @StatisticsResample IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @StatisticsResample is not supported.', 16, 1;
END;
IF @StatisticsResample = 'Y' AND @StatisticsSample IS NOT NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @StatisticsResample is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @PartitionLevel NOT IN('Y','N') OR @PartitionLevel IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @PartitionLevel is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @MSShippedObjects NOT IN('Y','N') OR @MSShippedObjects IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @MSShippedObjects is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS(SELECT * FROM @SelectedIndexes WHERE DatabaseName IS NULL OR SchemaName IS NULL OR ObjectName IS NULL OR IndexName IS NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Indexes is not supported.', 16, 1;
END;
IF @Indexes IS NOT NULL AND NOT EXISTS(SELECT * FROM @SelectedIndexes)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Indexes is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @TimeLimit < 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @TimeLimit is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Delay < 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Delay is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @WaitAtLowPriorityMaxDuration < 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @WaitAtLowPriorityMaxDuration is not supported.', 16, 1;
END;
IF @WaitAtLowPriorityMaxDuration IS NOT NULL AND @Version < 12
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @WaitAtLowPriorityMaxDuration is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @WaitAtLowPriorityAbortAfterWait NOT IN('NONE','SELF','BLOCKERS')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @WaitAtLowPriorityAbortAfterWait is not supported.', 16, 1;
END;
IF @WaitAtLowPriorityAbortAfterWait IS NOT NULL AND @Version < 12
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @WaitAtLowPriorityAbortAfterWait is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF (@WaitAtLowPriorityAbortAfterWait IS NOT NULL AND @WaitAtLowPriorityMaxDuration IS NULL) OR (@WaitAtLowPriorityAbortAfterWait IS NULL AND @WaitAtLowPriorityMaxDuration IS NOT NULL)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The parameters @WaitAtLowPriorityMaxDuration and @WaitAtLowPriorityAbortAfterWait can only be used together.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Resumable NOT IN('Y','N') OR @Resumable IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Resumable is not supported.', 16, 1;
END;
IF @Resumable = 'Y' AND NOT (@Version >= 14 OR SERVERPROPERTY('EngineEdition') IN (5, 8))
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Resumable is not supported.', 16, 2;
END;
IF @Resumable = 'Y' AND @SortInTempdb = 'Y'
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'You can only specify one of the parameters @Resumable and @SortInTempdb.', 16, 3;
END;
----------------------------------------------------------------------------------------------------
IF @LockTimeout < 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LockTimeout is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @LockMessageSeverity NOT IN(10, 16)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LockMessageSeverity is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @StringDelimiter IS NULL OR LEN(@StringDelimiter) > 1
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @StringDelimiter is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @DatabaseOrder NOT IN('DATABASE_NAME_ASC','DATABASE_NAME_DESC','DATABASE_SIZE_ASC','DATABASE_SIZE_DESC')
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseOrder is not supported.', 16, 1;
END;
IF @DatabaseOrder IS NOT NULL AND SERVERPROPERTY('EngineEdition') = 5
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabaseOrder is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF @DatabasesInParallel NOT IN('Y','N') OR @DatabasesInParallel IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabasesInParallel is not supported.', 16, 1;
END;
IF @DatabasesInParallel = 'Y' AND SERVERPROPERTY('EngineEdition') = 5
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @DatabasesInParallel is not supported.', 16, 2;
END;
----------------------------------------------------------------------------------------------------
IF LEN(@ExecuteAsUser) > 128
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @ExecuteAsUser is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @LogToTable NOT IN('Y','N') OR @LogToTable IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @LogToTable is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF @Execute NOT IN('Y','N') OR @Execute IS NULL
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The value for the parameter @Execute is not supported.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
IF EXISTS(SELECT * FROM @Errors)
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The documentation is available at https://ola.hallengren.com/sql-server-index-and-statistics-maintenance.html.', 16, 1;
END;
----------------------------------------------------------------------------------------------------
--// Check that selected databases and availability groups exist //--
----------------------------------------------------------------------------------------------------
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @SelectedDatabases
WHERE DatabaseName NOT LIKE '%[%]%'
AND DatabaseName NOT IN (SELECT DatabaseName FROM @tmpDatabases);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following databases in the @Databases parameter do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @SelectedIndexes
WHERE DatabaseName NOT LIKE '%[%]%'
AND DatabaseName NOT IN (SELECT DatabaseName FROM @tmpDatabases);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following databases in the @Indexes parameter do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(AvailabilityGroupName) + ', '
FROM @SelectedAvailabilityGroups
WHERE AvailabilityGroupName NOT LIKE '%[%]%'
AND AvailabilityGroupName NOT IN (SELECT AvailabilityGroupName FROM @tmpAvailabilityGroups);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following availability groups do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + ', '
FROM @SelectedIndexes
WHERE DatabaseName NOT LIKE '%[%]%'
AND DatabaseName IN (SELECT DatabaseName FROM @tmpDatabases)
AND DatabaseName NOT IN (SELECT DatabaseName FROM @tmpDatabases WHERE Selected = 1);
IF @@ROWCOUNT > 0
BEGIN
INSERT INTO @Errors ([Message], [severity], [State])
SELECT 'The following databases have been selected in the @Indexes parameter, but not in the @Databases or @AvailabilityGroups parameters: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.', 10, 1;
END;
----------------------------------------------------------------------------------------------------
--// Raise errors //--
----------------------------------------------------------------------------------------------------
DECLARE ErrorCursor CURSOR FAST_FORWARD FOR SELECT [Message], [severity], [State] FROM @Errors ORDER BY [ID] ASC;
OPEN ErrorCursor;
FETCH ErrorCursor INTO @CurrentMessage, @CurrentSeverity, @CurrentState;
WHILE @@FETCH_STATUS = 0
BEGIN
RAISERROR('%s', @CurrentSeverity, @CurrentState, @CurrentMessage) WITH NOWAIT;
RAISERROR(@EmptyLine, 10, 1) WITH NOWAIT;
FETCH NEXT FROM ErrorCursor INTO @CurrentMessage, @CurrentSeverity, @CurrentState;
END;
CLOSE ErrorCursor;
DEALLOCATE ErrorCursor;
IF EXISTS (SELECT * FROM @Errors WHERE [severity] >= 16)
BEGIN
SET @ReturnCode = 50000;
GOTO Logging;
END;
----------------------------------------------------------------------------------------------------
--// Should statistics be updated on the partition level? //--
----------------------------------------------------------------------------------------------------
SET @PartitionLevelStatistics = CASE WHEN @PartitionLevel = 'Y' AND ((@Version >= 12.05 AND @Version < 13) OR @Version >= 13.04422 OR SERVERPROPERTY('EngineEdition') IN (5,8)) THEN 1 ELSE 0 END;
----------------------------------------------------------------------------------------------------
--// Update database order //--
----------------------------------------------------------------------------------------------------
IF @DatabaseOrder IN('DATABASE_SIZE_ASC','DATABASE_SIZE_DESC')
BEGIN
UPDATE tmpDatabases
SET DatabaseSize = (SELECT SUM(CAST(SIZE AS BIGINT)) FROM [sys].[master_files] WHERE [type] = 0 AND [database_id] = DB_ID(tmpDatabases.DatabaseName))
FROM @tmpDatabases tmpDatabases;
END;
IF @DatabaseOrder IS NULL
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY StartPosition ASC, DatabaseName ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_NAME_ASC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseName ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_NAME_DESC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseName DESC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_SIZE_ASC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseSize ASC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
ELSE
IF @DatabaseOrder = 'DATABASE_SIZE_DESC'
BEGIN
WITH tmpDatabases AS (
SELECT DatabaseName, [Order], ROW_NUMBER() OVER (ORDER BY DatabaseSize DESC) AS RowNumber
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
)
UPDATE tmpDatabases
SET [Order] = RowNumber;
END;
----------------------------------------------------------------------------------------------------
--// Update the queue //--
----------------------------------------------------------------------------------------------------
IF @DatabasesInParallel = 'Y'
BEGIN
BEGIN TRY
SELECT @QueueID = QueueID
FROM [dbo].[Queue]
WHERE SchemaName = @SchemaName
AND ObjectName = @ObjectName
AND [Parameters] = @Parameters;
IF @QueueID IS NULL
BEGIN
BEGIN TRANSACTION;
SELECT @QueueID = QueueID
FROM [dbo].[Queue] WITH (UPDLOCK, HOLDLOCK)
WHERE SchemaName = @SchemaName
AND ObjectName = @ObjectName
AND [Parameters] = @Parameters;
IF @QueueID IS NULL
BEGIN
INSERT INTO [dbo].[Queue] (SchemaName, ObjectName, [Parameters])
SELECT @SchemaName, @ObjectName, @Parameters;
SET @QueueID = SCOPE_IDENTITY();
END;
COMMIT TRANSACTION;
END;
BEGIN TRANSACTION;
UPDATE [Queue]
SET QueueStartTime = SYSDATETIME(),
SessionID = @@SPID,
RequestID = (SELECT [request_id] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID),
RequestStartTime = (SELECT [start_time] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID)
FROM [dbo].[Queue] [Queue]
WHERE QueueID = @QueueID
AND NOT EXISTS (SELECT *
FROM [sys].[dm_exec_requests]
WHERE [session_id] = [Queue].SessionID
AND [request_id] = [Queue].RequestID
AND [start_time] = [Queue].RequestStartTime)
AND NOT EXISTS (SELECT *
FROM [dbo].QueueDatabase QueueDatabase
INNER JOIN [sys].[dm_exec_requests] ON QueueDatabase.SessionID = [session_id] AND QueueDatabase.RequestID = [request_id] AND QueueDatabase.RequestStartTime = [start_time]
WHERE QueueDatabase.QueueID = @QueueID);
IF @@ROWCOUNT = 1
BEGIN
INSERT INTO [dbo].QueueDatabase (QueueID, DatabaseName)
SELECT @QueueID AS QueueID,
DatabaseName
FROM @tmpDatabases tmpDatabases
WHERE Selected = 1
AND NOT EXISTS (SELECT * FROM [dbo].QueueDatabase WHERE DatabaseName = tmpDatabases.DatabaseName AND QueueID = @QueueID);
DELETE QueueDatabase
FROM [dbo].QueueDatabase QueueDatabase
WHERE QueueID = @QueueID
AND NOT EXISTS (SELECT * FROM @tmpDatabases tmpDatabases WHERE DatabaseName = QueueDatabase.DatabaseName AND Selected = 1);
UPDATE QueueDatabase
SET DatabaseOrder = tmpDatabases.[Order]
FROM [dbo].QueueDatabase QueueDatabase
INNER JOIN @tmpDatabases tmpDatabases ON QueueDatabase.DatabaseName = tmpDatabases.DatabaseName
WHERE QueueID = @QueueID;
END;
COMMIT TRANSACTION;
SELECT @QueueStartTime = QueueStartTime
FROM [dbo].[Queue]
WHERE QueueID = @QueueID;
END TRY
BEGIN CATCH
IF XACT_STATE() <> 0
BEGIN
ROLLBACK TRANSACTION;
END;
SET @ErrorMessage = 'Msg ' + CAST(ERROR_NUMBER() AS NVARCHAR) + ', ' + ISNULL(ERROR_MESSAGE(),'');
RAISERROR('%s',16,1,@ErrorMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
SET @ReturnCode = ERROR_NUMBER();
GOTO Logging;
END CATCH;
END;
----------------------------------------------------------------------------------------------------
--// Execute commands //--
----------------------------------------------------------------------------------------------------
WHILE (1 = 1)
BEGIN
IF @DatabasesInParallel = 'Y'
BEGIN
UPDATE QueueDatabase
SET DatabaseStartTime = NULL,
SessionID = NULL,
RequestID = NULL,
RequestStartTime = NULL
FROM [dbo].QueueDatabase QueueDatabase
WHERE QueueID = @QueueID
AND DatabaseStartTime IS NOT NULL
AND DatabaseEndTime IS NULL
AND NOT EXISTS (SELECT * FROM [sys].[dm_exec_requests] WHERE [session_id] = QueueDatabase.SessionID AND [request_id] = QueueDatabase.RequestID AND [start_time] = QueueDatabase.RequestStartTime);
UPDATE QueueDatabase
SET DatabaseStartTime = SYSDATETIME(),
DatabaseEndTime = NULL,
SessionID = @@SPID,
RequestID = (SELECT [request_id] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID),
RequestStartTime = (SELECT [start_time] FROM [sys].[dm_exec_requests] WHERE [session_id] = @@SPID),
@CurrentDatabaseName = DatabaseName
FROM (SELECT TOP 1 DatabaseStartTime,
DatabaseEndTime,
SessionID,
RequestID,
RequestStartTime,
DatabaseName
FROM [dbo].QueueDatabase
WHERE QueueID = @QueueID
AND (DatabaseStartTime < @QueueStartTime OR DatabaseStartTime IS NULL)
AND NOT (DatabaseStartTime IS NOT NULL AND DatabaseEndTime IS NULL)
ORDER BY DatabaseOrder ASC
) QueueDatabase;
END;
ELSE
BEGIN
SELECT TOP 1 @CurrentDBID = [Id],
@CurrentDatabaseName = DatabaseName
FROM @tmpDatabases
WHERE Selected = 1
AND Completed = 0
ORDER BY [Order] ASC;
END;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
SET @CurrentDatabase_sp_executesql = QUOTENAME(@CurrentDatabaseName) + '.sys.sp_executesql';
BEGIN
SET @DatabaseMessage = 'Date and time: ' + CONVERT(NVARCHAR,SYSDATETIME(),120);
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Database: ' + QUOTENAME(@CurrentDatabaseName);
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
SELECT @CurrentUserAccess = [user_access_desc],
@CurrentIsReadOnly = [is_read_only],
@CurrentDatabaseState = [state_desc],
@CurrentInStandby = [is_in_standby],
@CurrentRecoveryModel = [recovery_model_desc]
FROM [sys].[databases]
WHERE [name] = @CurrentDatabaseName;
BEGIN
SET @DatabaseMessage = 'State: ' + @CurrentDatabaseState;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Standby: ' + CASE WHEN @CurrentInStandby = 1 THEN 'Yes' ELSE 'No' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Updateability: ' + CASE WHEN @CurrentIsReadOnly = 1 THEN 'READ_ONLY' WHEN @CurrentIsReadOnly = 0 THEN 'READ_WRITE' END;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'User access: ' + @CurrentUserAccess;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Recovery model: ' + @CurrentRecoveryModel;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
IF @Version >= 11 AND SERVERPROPERTY('IsHadrEnabled') = 1
BEGIN
SELECT @CurrentReplicaID = [databases].[replica_id]
FROM [sys].[databases] [databases]
INNER JOIN [sys].[availability_replicas] [availability_replicas] ON [databases].[replica_id] = [availability_replicas].[replica_id]
WHERE [databases].[name] = @CurrentDatabaseName;
SELECT @CurrentAvailabilityGroupID = [group_id]
FROM [sys].[availability_replicas]
WHERE [replica_id] = @CurrentReplicaID;
SELECT @CurrentAvailabilityGroupRole = [role_desc]
FROM [sys].[dm_hadr_availability_replica_states]
WHERE [replica_id] = @CurrentReplicaID;
SELECT @CurrentAvailabilityGroup = [name]
FROM [sys].[availability_groups]
WHERE [group_id] = @CurrentAvailabilityGroupID;
END;
IF SERVERPROPERTY('EngineEdition') <> 5
BEGIN
SELECT @CurrentDatabaseMirroringRole = UPPER([mirroring_role_desc])
FROM [sys].[database_mirroring] [database_mirroring]
INNER JOIN [sys].[databases] [databases] ON [database_mirroring].[database_id] = [databases].[database_id]
WHERE [databases].[name] = @CurrentDatabaseName;
END;
IF @CurrentAvailabilityGroup IS NOT NULL
BEGIN
SET @DatabaseMessage = 'Availability group: ' + ISNULL(@CurrentAvailabilityGroup,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
SET @DatabaseMessage = 'Availability group role: ' + ISNULL(@CurrentAvailabilityGroupRole,'N/A');
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
IF @CurrentDatabaseMirroringRole IS NOT NULL
BEGIN
SET @DatabaseMessage = 'Database mirroring role: ' + @CurrentDatabaseMirroringRole;
RAISERROR('%s',10,1,@DatabaseMessage) WITH NOWAIT;
END;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF @ExecuteAsUser IS NOT NULL
AND @CurrentDatabaseState = 'ONLINE'
AND NOT (@CurrentUserAccess = 'SINGLE_USER')
AND NOT (@CurrentAvailabilityGroup IS NOT NULL AND (@CurrentAvailabilityGroupRole <> 'PRIMARY' OR @CurrentAvailabilityGroupRole IS NULL))
AND NOT (@AmazonRDS = 1 AND @CurrentDatabaseName = 'rdsadmin')
BEGIN
SET @CurrentCommand = '';
SET @CurrentCommand += 'IF EXISTS(SELECT * FROM sys.database_principals database_principals WHERE database_principals.[name] = @ParamExecuteAsUser) BEGIN SET @ParamExecuteAsUserExists = 1 END ELSE BEGIN SET @ParamExecuteAsUserExists = 0 END';
EXECUTE @CurrentDatabase_sp_executesql @stmt = @CurrentCommand, @params = N'@ParamExecuteAsUser sysname, @ParamExecuteAsUserExists bit OUTPUT', @ParamExecuteAsUser = @ExecuteAsUser, @ParamExecuteAsUserExists = @CurrentExecuteAsUserExists OUTPUT;
END;
IF @CurrentExecuteAsUserExists = 0
BEGIN
SET @DatabaseMessage = 'The user ' + QUOTENAME(@ExecuteAsUser) + ' does not exist in the database ' + QUOTENAME(@CurrentDatabaseName) + '.';
RAISERROR('%s',16,1,@DatabaseMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
END;
IF @CurrentDatabaseState = 'ONLINE'
AND NOT (@CurrentUserAccess = 'SINGLE_USER')
AND NOT (@CurrentAvailabilityGroup IS NOT NULL AND (@CurrentAvailabilityGroupRole <> 'PRIMARY' OR @CurrentAvailabilityGroupRole IS NULL))
AND NOT (@AmazonRDS = 1 AND @CurrentDatabaseName = 'rdsadmin')
AND NOT (@CurrentIsReadOnly = 1)
AND (@CurrentExecuteAsUserExists = 1 OR @CurrentExecuteAsUserExists IS NULL)
BEGIN
-- Select indexes in the current database
IF (EXISTS(SELECT * FROM @ActionsPreferred) OR @UpdateStatistics IS NOT NULL) AND (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SET @CurrentCommand = 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;'
+ ' SELECT SchemaID, SchemaName, ObjectID, ObjectName, ObjectType, IsMemoryOptimized, IndexID, IndexName, IndexType, AllowPageLocks, HasFilter, IsImageText, IsNewLOB, IsFileStream, HasClusteredColumnstore, HasNonClusteredColumnstore, IsComputed, IsClusteredIndexComputed, IsTimestamp, OnReadOnlyFileGroup, ResumableIndexOperation, StatisticsID, StatisticsName, NoRecompute, IsIncremental, PartitionID, PartitionNumber, PartitionCount, [Order], Selected, Completed'
+ ' FROM (';
IF EXISTS(SELECT * FROM @ActionsPreferred) OR @UpdateStatistics IN('ALL','INDEX')
BEGIN
SET @CurrentCommand = @CurrentCommand + 'SELECT schemas.[schema_id] AS SchemaID'
+ ', schemas.[name] AS SchemaName'
+ ', objects.[object_id] AS ObjectID'
+ ', objects.[name] AS ObjectName'
+ ', RTRIM(objects.[type]) AS ObjectType'
+ ', ' + CASE WHEN @Version >= 12 THEN 'tables.is_memory_optimized' ELSE '0' END + ' AS IsMemoryOptimized'
+ ', indexes.index_id AS IndexID'
+ ', indexes.[name] AS IndexName'
+ ', indexes.[type] AS IndexType'
+ ', indexes.allow_page_locks AS AllowPageLocks'
+ ', indexes.has_filter AS HasFilter'
+ ', CASE WHEN indexes.[type] = 1 AND EXISTS(SELECT * FROM sys.columns columns INNER JOIN sys.types types ON columns.system_type_id = types.user_type_id WHERE columns.[object_id] = objects.object_id AND types.name IN(''image'',''text'',''ntext'')) THEN 1 ELSE 0 END AS IsImageText'
+ ', CASE WHEN indexes.[type] = 1 AND EXISTS(SELECT * FROM sys.columns columns INNER JOIN sys.types types ON columns.system_type_id = types.user_type_id OR (columns.user_type_id = types.user_type_id AND types.is_assembly_type = 1) WHERE columns.[object_id] = objects.object_id AND (types.name IN(''xml'') OR (types.name IN(''varchar'',''nvarchar'',''varbinary'') AND columns.max_length = -1) OR (types.is_assembly_type = 1 AND columns.max_length = -1))) THEN 1'
+ ' WHEN indexes.[type] = 2 AND EXISTS(SELECT * FROM sys.index_columns index_columns INNER JOIN sys.columns columns ON index_columns.[object_id] = columns.[object_id] AND index_columns.column_id = columns.column_id INNER JOIN sys.types types ON columns.system_type_id = types.user_type_id OR (columns.user_type_id = types.user_type_id AND types.is_assembly_type = 1) WHERE index_columns.[object_id] = objects.object_id AND index_columns.index_id = indexes.index_id AND (types.[name] IN(''xml'') OR (types.[name] IN(''varchar'',''nvarchar'',''varbinary'') AND columns.max_length = -1) OR (types.is_assembly_type = 1 AND columns.max_length = -1))) THEN 1 ELSE 0 END AS IsNewLOB'
+ ', CASE WHEN indexes.[type] = 1 AND EXISTS(SELECT * FROM sys.columns columns WHERE columns.[object_id] = objects.object_id AND columns.is_filestream = 1) THEN 1 ELSE 0 END AS IsFileStream'
+ ', CASE WHEN EXISTS(SELECT * FROM sys.indexes indexes WHERE indexes.[object_id] = objects.object_id AND [type] = 5) THEN 1 ELSE 0 END AS HasClusteredColumnstore'
+ ', CASE WHEN EXISTS(SELECT * FROM sys.indexes indexes WHERE indexes.[object_id] = objects.object_id AND [type] = 6) THEN 1 ELSE 0 END AS HasNonClusteredColumnstore'
+ ', CASE WHEN EXISTS(SELECT * FROM sys.index_columns index_columns INNER JOIN sys.columns columns ON index_columns.object_id = columns.object_id AND index_columns.column_id = columns.column_id WHERE (index_columns.key_ordinal > 0 OR index_columns.partition_ordinal > 0) AND columns.is_computed = 1 AND index_columns.object_id = indexes.object_id AND index_columns.index_id = indexes.index_id) THEN 1 ELSE 0 END AS IsComputed'
+ ', CASE WHEN EXISTS(SELECT * FROM sys.index_columns index_columns INNER JOIN sys.columns columns ON index_columns.object_id = columns.object_id AND index_columns.column_id = columns.column_id INNER JOIN sys.indexes indexes2 ON index_columns.object_id = indexes2.object_id AND index_columns.index_id = indexes2.index_id WHERE (index_columns.key_ordinal > 0 OR index_columns.partition_ordinal > 0) AND columns.is_computed = 1 AND indexes2.[type] = 1 AND index_columns.object_id = indexes.object_id) THEN 1 ELSE 0 END AS IsClusteredIndexComputed'
+ ', CASE WHEN EXISTS(SELECT * FROM sys.index_columns index_columns INNER JOIN sys.columns columns ON index_columns.[object_id] = columns.[object_id] AND index_columns.column_id = columns.column_id INNER JOIN sys.types types ON columns.system_type_id = types.system_type_id WHERE index_columns.[object_id] = objects.object_id AND index_columns.index_id = indexes.index_id AND types.[name] = ''timestamp'') THEN 1 ELSE 0 END AS IsTimestamp'
+ ', CASE WHEN EXISTS (SELECT * FROM sys.indexes indexes2 INNER JOIN sys.destination_data_spaces destination_data_spaces ON indexes.data_space_id = destination_data_spaces.partition_scheme_id INNER JOIN sys.filegroups filegroups ON destination_data_spaces.data_space_id = filegroups.data_space_id WHERE filegroups.is_read_only = 1 AND indexes2.[object_id] = indexes.[object_id] AND indexes2.[index_id] = indexes.index_id' + CASE WHEN @PartitionLevel = 'Y' THEN ' AND destination_data_spaces.destination_id = partitions.partition_number' ELSE '' END + ') THEN 1'
+ ' WHEN EXISTS (SELECT * FROM sys.indexes indexes2 INNER JOIN sys.filegroups filegroups ON indexes.data_space_id = filegroups.data_space_id WHERE filegroups.is_read_only = 1 AND indexes.[object_id] = indexes2.[object_id] AND indexes.[index_id] = indexes2.index_id) THEN 1'
+ ' WHEN indexes.[type] = 1 AND EXISTS (SELECT * FROM sys.tables tables INNER JOIN sys.filegroups filegroups ON tables.lob_data_space_id = filegroups.data_space_id WHERE filegroups.is_read_only = 1 AND tables.[object_id] = objects.[object_id]) THEN 1 ELSE 0 END AS OnReadOnlyFileGroup'
+ ', ' + CASE WHEN @Version >= 14 OR SERVERPROPERTY('EngineEdition') IN (5, 8) THEN 'CASE WHEN EXISTS(SELECT * FROM sys.index_resumable_operations index_resumable_operations WHERE state_desc = ''PAUSED'' AND index_resumable_operations.object_id = indexes.object_id AND index_resumable_operations.index_id = indexes.index_id' + CASE WHEN @PartitionLevel = 'Y' THEN ' AND (index_resumable_operations.partition_number = partitions.partition_number OR index_resumable_operations.partition_number IS NULL)' ELSE '' END + ') THEN 1 ELSE 0 END' ELSE '0' END + ' AS ResumableIndexOperation'
+ ', stats.stats_id AS StatisticsID'
+ ', stats.name AS StatisticsName'
+ ', stats.no_recompute AS NoRecompute'
+ ', ' + CASE WHEN @Version >= 12 THEN 'stats.is_incremental' ELSE '0' END + ' AS IsIncremental'
+ ', ' + CASE WHEN @PartitionLevel = 'Y' THEN 'partitions.partition_id AS PartitionID' WHEN @PartitionLevel = 'N' THEN 'NULL AS PartitionID' END
+ ', ' + CASE WHEN @PartitionLevel = 'Y' THEN 'partitions.partition_number AS PartitionNumber' WHEN @PartitionLevel = 'N' THEN 'NULL AS PartitionNumber' END
+ ', ' + CASE WHEN @PartitionLevel = 'Y' THEN 'IndexPartitions.partition_count AS PartitionCount' WHEN @PartitionLevel = 'N' THEN 'NULL AS PartitionCount' END
+ ', 0 AS [Order]'
+ ', 0 AS Selected'
+ ', 0 AS Completed'
+ ' FROM sys.indexes indexes'
+ ' INNER JOIN sys.objects objects ON indexes.[object_id] = objects.[object_id]'
+ ' INNER JOIN sys.schemas schemas ON objects.[schema_id] = schemas.[schema_id]'
+ ' LEFT OUTER JOIN sys.tables tables ON objects.[object_id] = tables.[object_id]'
+ ' LEFT OUTER JOIN sys.stats stats ON indexes.[object_id] = stats.[object_id] AND indexes.[index_id] = stats.[stats_id]';
IF @PartitionLevel = 'Y'
BEGIN
SET @CurrentCommand = @CurrentCommand + ' LEFT OUTER JOIN sys.partitions partitions ON indexes.[object_id] = partitions.[object_id] AND indexes.index_id = partitions.index_id'
+ ' LEFT OUTER JOIN (SELECT partitions.[object_id], partitions.index_id, COUNT(DISTINCT partitions.partition_number) AS partition_count FROM sys.partitions partitions GROUP BY partitions.[object_id], partitions.index_id) IndexPartitions ON partitions.[object_id] = IndexPartitions.[object_id] AND partitions.[index_id] = IndexPartitions.[index_id]';
END;
SET @CurrentCommand = @CurrentCommand + ' WHERE objects.[type] IN(''U'',''V'')'
+ CASE WHEN @MSShippedObjects = 'N' THEN ' AND objects.is_ms_shipped = 0' ELSE '' END
+ ' AND indexes.[type] IN(1,2,3,4,5,6,7)'
+ ' AND indexes.is_disabled = 0 AND indexes.is_hypothetical = 0';
END;
IF (EXISTS(SELECT * FROM @ActionsPreferred) AND @UpdateStatistics = 'COLUMNS') OR @UpdateStatistics = 'ALL'
BEGIN
SET @CurrentCommand = @CurrentCommand + ' UNION ';
END;
IF @UpdateStatistics IN('ALL','COLUMNS')
BEGIN
SET @CurrentCommand = @CurrentCommand + 'SELECT schemas.[schema_id] AS SchemaID'
+ ', schemas.[name] AS SchemaName'
+ ', objects.[object_id] AS ObjectID'
+ ', objects.[name] AS ObjectName'
+ ', RTRIM(objects.[type]) AS ObjectType'
+ ', ' + CASE WHEN @Version >= 12 THEN 'tables.is_memory_optimized' ELSE '0' END + ' AS IsMemoryOptimized'
+ ', NULL AS IndexID, NULL AS IndexName'
+ ', NULL AS IndexType'
+ ', NULL AS AllowPageLocks'
+ ', NULL AS HasFilter'
+ ', NULL AS IsImageText'
+ ', NULL AS IsNewLOB'
+ ', NULL AS IsFileStream'
+ ', NULL AS HasClusteredColumnstore'
+ ', NULL AS HasNonClusteredColumnstore'
+ ', NULL AS IsComputed'
+ ', NULL AS IsClusteredIndexComputed'
+ ', NULL AS IsTimestamp'
+ ', NULL AS OnReadOnlyFileGroup'
+ ', NULL AS ResumableIndexOperation'
+ ', stats.stats_id AS StatisticsID'
+ ', stats.name AS StatisticsName'
+ ', stats.no_recompute AS NoRecompute'
+ ', ' + CASE WHEN @Version >= 12 THEN 'stats.is_incremental' ELSE '0' END + ' AS IsIncremental'
+ ', NULL AS PartitionID'
+ ', ' + CASE WHEN @PartitionLevelStatistics = 1 THEN 'dm_db_incremental_stats_properties.partition_number' ELSE 'NULL' END + ' AS PartitionNumber'
+ ', NULL AS PartitionCount'
+ ', 0 AS [Order]'
+ ', 0 AS Selected'
+ ', 0 AS Completed'
+ ' FROM sys.stats stats'
+ ' INNER JOIN sys.objects objects ON stats.[object_id] = objects.[object_id]'
+ ' INNER JOIN sys.schemas schemas ON objects.[schema_id] = schemas.[schema_id]'
+ ' LEFT OUTER JOIN sys.tables tables ON objects.[object_id] = tables.[object_id]';
IF @PartitionLevelStatistics = 1
BEGIN
SET @CurrentCommand = @CurrentCommand + ' OUTER APPLY sys.dm_db_incremental_stats_properties(stats.object_id, stats.stats_id) dm_db_incremental_stats_properties';
END;
SET @CurrentCommand = @CurrentCommand + ' WHERE objects.[type] IN(''U'',''V'')'
+ CASE WHEN @Version >= 12 THEN ' AND (tables.is_memory_optimized = 0 OR tables.is_memory_optimized IS NULL)' ELSE '' END
+ CASE WHEN @MSShippedObjects = 'N' THEN ' AND objects.is_ms_shipped = 0' ELSE '' END
+ ' AND NOT EXISTS(SELECT * FROM sys.indexes indexes WHERE indexes.[object_id] = stats.[object_id] AND indexes.index_id = stats.stats_id)'
+ ' AND NOT EXISTS(SELECT * FROM sys.indexes indexes2 WHERE indexes2.[object_id] = stats.[object_id] AND indexes2.type = 1 AND indexes2.is_disabled = 1)';
IF @Version >= 12
BEGIN
SET @CurrentCommand = @CurrentCommand + ' UNION ';
SET @CurrentCommand = @CurrentCommand + 'SELECT schemas.[schema_id] AS SchemaID'
+ ', schemas.[name] AS SchemaName'
+ ', objects.[object_id] AS ObjectID'
+ ', objects.[name] AS ObjectName'
+ ', RTRIM(objects.[type]) AS ObjectType'
+ ', tables.is_memory_optimized AS IsMemoryOptimized'
+ ', NULL AS IndexID, NULL AS IndexName'
+ ', NULL AS IndexType'
+ ', NULL AS AllowPageLocks'
+ ', NULL AS HasFilter'
+ ', NULL AS IsImageText'
+ ', NULL AS IsNewLOB'
+ ', NULL AS IsFileStream'
+ ', NULL AS HasClusteredColumnstore'
+ ', NULL AS HasNonClusteredColumnstore'
+ ', NULL AS IsComputed'
+ ', NULL AS IsClusteredIndexComputed'
+ ', NULL AS IsTimestamp'
+ ', NULL AS OnReadOnlyFileGroup'
+ ', NULL AS ResumableIndexOperation'
+ ', stats.stats_id AS StatisticsID'
+ ', stats.name AS StatisticsName'
+ ', stats.no_recompute AS NoRecompute'
+ ', ' + CASE WHEN @Version >= 12 THEN 'stats.is_incremental' ELSE '0' END + ' AS IsIncremental'
+ ', NULL AS PartitionID'
+ ', NULL AS PartitionNumber'
+ ', NULL AS PartitionCount'
+ ', 0 AS [Order]'
+ ', 0 AS Selected'
+ ', 0 AS Completed'
+ ' FROM sys.stats stats'
+ ' INNER JOIN sys.objects objects ON stats.[object_id] = objects.[object_id]'
+ ' INNER JOIN sys.schemas schemas ON objects.[schema_id] = schemas.[schema_id]'
+ ' INNER JOIN sys.tables tables ON objects.[object_id] = tables.[object_id]';
SET @CurrentCommand = @CurrentCommand + ' WHERE objects.[type] = ''U'''
+ ' AND tables.is_memory_optimized = 1'
+ CASE WHEN @MSShippedObjects = 'N' THEN ' AND objects.is_ms_shipped = 0' ELSE '' END
+ ' AND NOT EXISTS(SELECT * FROM sys.indexes indexes WHERE indexes.[object_id] = stats.[object_id] AND indexes.index_id = stats.stats_id)';
END;
END;
SET @CurrentCommand = @CurrentCommand + ') IndexesStatistics';
INSERT INTO @tmpIndexesStatistics (SchemaID, SchemaName, [objectid], ObjectName, ObjectType, IsMemoryOptimized, [indexid], IndexName, IndexType, AllowPageLocks, HasFilter, IsImageText, IsNewLOB, IsFileStream, HasClusteredColumnstore, HasNonClusteredColumnstore, [iscomputed], IsClusteredIndexComputed, IsTimestamp, OnReadOnlyFileGroup, ResumableIndexOperation, StatisticsID, StatisticsName, [NoRecompute], IsIncremental, PartitionID, PartitionNumber, PartitionCount, [Order], Selected, Completed)
EXECUTE @CurrentDatabase_sp_executesql @stmt = @CurrentCommand;
SET @Error = @@ERROR;
IF @Error <> 0
BEGIN
SET @ReturnCode = @Error;
END;
END;
IF @Indexes IS NULL
BEGIN
UPDATE tmpIndexesStatistics
SET tmpIndexesStatistics.Selected = 1
FROM @tmpIndexesStatistics tmpIndexesStatistics;
END;
ELSE
BEGIN
UPDATE tmpIndexesStatistics
SET tmpIndexesStatistics.Selected = SelectedIndexes.Selected
FROM @tmpIndexesStatistics tmpIndexesStatistics
INNER JOIN @SelectedIndexes SelectedIndexes
ON @CurrentDatabaseName LIKE REPLACE(SelectedIndexes.DatabaseName,'_','[_]') AND tmpIndexesStatistics.SchemaName LIKE REPLACE(SelectedIndexes.SchemaName,'_','[_]') AND tmpIndexesStatistics.ObjectName LIKE REPLACE(SelectedIndexes.ObjectName,'_','[_]') AND COALESCE(tmpIndexesStatistics.IndexName,tmpIndexesStatistics.StatisticsName) LIKE REPLACE(SelectedIndexes.IndexName,'_','[_]')
WHERE SelectedIndexes.Selected = 1;
UPDATE tmpIndexesStatistics
SET tmpIndexesStatistics.Selected = SelectedIndexes.Selected
FROM @tmpIndexesStatistics tmpIndexesStatistics
INNER JOIN @SelectedIndexes SelectedIndexes
ON @CurrentDatabaseName LIKE REPLACE(SelectedIndexes.DatabaseName,'_','[_]') AND tmpIndexesStatistics.SchemaName LIKE REPLACE(SelectedIndexes.SchemaName,'_','[_]') AND tmpIndexesStatistics.ObjectName LIKE REPLACE(SelectedIndexes.ObjectName,'_','[_]') AND COALESCE(tmpIndexesStatistics.IndexName,tmpIndexesStatistics.StatisticsName) LIKE REPLACE(SelectedIndexes.IndexName,'_','[_]')
WHERE SelectedIndexes.Selected = 0;
UPDATE tmpIndexesStatistics
SET tmpIndexesStatistics.StartPosition = SelectedIndexes2.StartPosition
FROM @tmpIndexesStatistics tmpIndexesStatistics
INNER JOIN (SELECT tmpIndexesStatistics.SchemaName, tmpIndexesStatistics.ObjectName, tmpIndexesStatistics.IndexName, tmpIndexesStatistics.StatisticsName, MIN(SelectedIndexes.StartPosition) AS StartPosition
FROM @tmpIndexesStatistics tmpIndexesStatistics
INNER JOIN @SelectedIndexes SelectedIndexes
ON @CurrentDatabaseName LIKE REPLACE(SelectedIndexes.DatabaseName,'_','[_]') AND tmpIndexesStatistics.SchemaName LIKE REPLACE(SelectedIndexes.SchemaName,'_','[_]') AND tmpIndexesStatistics.ObjectName LIKE REPLACE(SelectedIndexes.ObjectName,'_','[_]') AND COALESCE(tmpIndexesStatistics.IndexName,tmpIndexesStatistics.StatisticsName) LIKE REPLACE(SelectedIndexes.IndexName,'_','[_]')
WHERE SelectedIndexes.Selected = 1
GROUP BY tmpIndexesStatistics.SchemaName, tmpIndexesStatistics.ObjectName, tmpIndexesStatistics.IndexName, tmpIndexesStatistics.StatisticsName) SelectedIndexes2
ON tmpIndexesStatistics.SchemaName = SelectedIndexes2.SchemaName
AND tmpIndexesStatistics.ObjectName = SelectedIndexes2.ObjectName
AND (tmpIndexesStatistics.IndexName = SelectedIndexes2.IndexName OR tmpIndexesStatistics.IndexName IS NULL)
AND (tmpIndexesStatistics.StatisticsName = SelectedIndexes2.StatisticsName OR tmpIndexesStatistics.StatisticsName IS NULL);
END;
WITH tmpIndexesStatistics AS (
SELECT SchemaName, ObjectName, [Order], ROW_NUMBER() OVER (ORDER BY ISNULL(ResumableIndexOperation,0) DESC, StartPosition ASC, SchemaName ASC, ObjectName ASC, CASE WHEN IndexType IS NULL THEN 1 ELSE 0 END ASC, IndexType ASC, IndexName ASC, StatisticsName ASC, PartitionNumber ASC) AS RowNumber
FROM @tmpIndexesStatistics tmpIndexesStatistics
WHERE Selected = 1
)
UPDATE tmpIndexesStatistics
SET [Order] = RowNumber;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + '.' + QUOTENAME(SchemaName) + '.' + QUOTENAME(ObjectName) + ', '
FROM @SelectedIndexes SelectedIndexes
WHERE DatabaseName = @CurrentDatabaseName
AND SchemaName NOT LIKE '%[%]%'
AND ObjectName NOT LIKE '%[%]%'
AND IndexName LIKE '%[%]%'
AND NOT EXISTS (SELECT * FROM @tmpIndexesStatistics WHERE SchemaName = SelectedIndexes.SchemaName AND ObjectName = SelectedIndexes.ObjectName);
IF @@ROWCOUNT > 0
BEGIN
SET @ErrorMessage = 'The following objects in the @Indexes parameter do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.';
RAISERROR('%s',10,1,@ErrorMessage) WITH NOWAIT;
SET @Error = @@ERROR;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
END;
SET @ErrorMessage = '';
SELECT @ErrorMessage = @ErrorMessage + QUOTENAME(DatabaseName) + QUOTENAME(SchemaName) + '.' + QUOTENAME(ObjectName) + '.' + QUOTENAME(IndexName) + ', '
FROM @SelectedIndexes SelectedIndexes
WHERE DatabaseName = @CurrentDatabaseName
AND SchemaName NOT LIKE '%[%]%'
AND ObjectName NOT LIKE '%[%]%'
AND IndexName NOT LIKE '%[%]%'
AND NOT EXISTS (SELECT * FROM @tmpIndexesStatistics WHERE SchemaName = SelectedIndexes.SchemaName AND ObjectName = SelectedIndexes.ObjectName AND IndexName = SelectedIndexes.IndexName);
IF @@ROWCOUNT > 0
BEGIN
SET @ErrorMessage = 'The following indexes in the @Indexes parameter do not exist: ' + LEFT(@ErrorMessage,LEN(@ErrorMessage)-1) + '.';
RAISERROR('%s',10,1,@ErrorMessage) WITH NOWAIT;
SET @Error = @@ERROR;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
END;
WHILE (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SELECT TOP 1 @CurrentIxID = [Id],
@CurrentIxOrder = [Order],
@CurrentSchemaID = SchemaID,
@CurrentSchemaName = SchemaName,
@CurrentObjectID = [objectid],
@CurrentObjectName = ObjectName,
@CurrentObjectType = ObjectType,
@CurrentIsMemoryOptimized = IsMemoryOptimized,
@CurrentIndexID = [indexid],
@CurrentIndexName = IndexName,
@CurrentIndexType = IndexType,
@CurrentAllowPageLocks = AllowPageLocks,
@CurrentHasFilter = HasFilter,
@CurrentIsImageText = IsImageText,
@CurrentIsNewLOB = IsNewLOB,
@CurrentIsFileStream = IsFileStream,
@CurrentHasClusteredColumnstore = HasClusteredColumnstore,
@CurrentHasNonClusteredColumnstore = HasNonClusteredColumnstore,
@CurrentIsComputed = [iscomputed],
@CurrentIsClusteredIndexComputed = IsClusteredIndexComputed,
@CurrentIsTimestamp = IsTimestamp,
@CurrentOnReadOnlyFileGroup = OnReadOnlyFileGroup,
@CurrentResumableIndexOperation = ResumableIndexOperation,
@CurrentStatisticsID = StatisticsID,
@CurrentStatisticsName = StatisticsName,
@CurrentNoRecompute = [NoRecompute],
@CurrentIsIncremental = IsIncremental,
@CurrentPartitionID = PartitionID,
@CurrentPartitionNumber = PartitionNumber,
@CurrentPartitionCount = PartitionCount
FROM @tmpIndexesStatistics
WHERE Selected = 1
AND Completed = 0
ORDER BY [Order] ASC;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
-- Is the index a partition?
IF @CurrentPartitionNumber IS NULL OR @CurrentPartitionCount = 1 BEGIN SET @CurrentIsPartition = 0; END; ELSE BEGIN SET @CurrentIsPartition = 1; END;
-- Does the index exist?
IF @CurrentIndexID IS NOT NULL AND EXISTS(SELECT * FROM @ActionsPreferred)
BEGIN
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
IF @CurrentIsPartition = 0 SET @CurrentCommand += 'IF EXISTS(SELECT * FROM sys.indexes indexes INNER JOIN sys.objects objects ON indexes.[object_id] = objects.[object_id] INNER JOIN sys.schemas schemas ON objects.[schema_id] = schemas.[schema_id] WHERE objects.[type] IN(''U'',''V'') AND indexes.[type] IN(1,2,3,4,5,6,7) AND indexes.is_disabled = 0 AND indexes.is_hypothetical = 0 AND schemas.[schema_id] = @ParamSchemaID AND schemas.[name] = @ParamSchemaName AND objects.[object_id] = @ParamObjectID AND objects.[name] = @ParamObjectName AND objects.[type] = @ParamObjectType AND indexes.index_id = @ParamIndexID AND indexes.[name] = @ParamIndexName AND indexes.[type] = @ParamIndexType) BEGIN SET @ParamIndexExists = 1 END';
IF @CurrentIsPartition = 1 SET @CurrentCommand += 'IF EXISTS(SELECT * FROM sys.indexes indexes INNER JOIN sys.objects objects ON indexes.[object_id] = objects.[object_id] INNER JOIN sys.schemas schemas ON objects.[schema_id] = schemas.[schema_id] INNER JOIN sys.partitions partitions ON indexes.[object_id] = partitions.[object_id] AND indexes.index_id = partitions.index_id WHERE objects.[type] IN(''U'',''V'') AND indexes.[type] IN(1,2,3,4,5,6,7) AND indexes.is_disabled = 0 AND indexes.is_hypothetical = 0 AND schemas.[schema_id] = @ParamSchemaID AND schemas.[name] = @ParamSchemaName AND objects.[object_id] = @ParamObjectID AND objects.[name] = @ParamObjectName AND objects.[type] = @ParamObjectType AND indexes.index_id = @ParamIndexID AND indexes.[name] = @ParamIndexName AND indexes.[type] = @ParamIndexType AND partitions.partition_id = @ParamPartitionID AND partitions.partition_number = @ParamPartitionNumber) BEGIN SET @ParamIndexExists = 1 END';
BEGIN TRY
EXECUTE @CurrentDatabase_sp_executesql @stmt = @CurrentCommand, @params = N'@ParamSchemaID int, @ParamSchemaName sysname, @ParamObjectID int, @ParamObjectName sysname, @ParamObjectType sysname, @ParamIndexID int, @ParamIndexName sysname, @ParamIndexType int, @ParamPartitionID bigint, @ParamPartitionNumber int, @ParamIndexExists bit OUTPUT', @ParamSchemaID = @CurrentSchemaID, @ParamSchemaName = @CurrentSchemaName, @ParamObjectID = @CurrentObjectID, @ParamObjectName = @CurrentObjectName, @ParamObjectType = @CurrentObjectType, @ParamIndexID = @CurrentIndexID, @ParamIndexName = @CurrentIndexName, @ParamIndexType = @CurrentIndexType, @ParamPartitionID = @CurrentPartitionID, @ParamPartitionNumber = @CurrentPartitionNumber, @ParamIndexExists = @CurrentIndexExists OUTPUT;
IF @CurrentIndexExists IS NULL
BEGIN
SET @CurrentIndexExists = 0;
GOTO NoAction;
END;
END TRY
BEGIN CATCH
SET @ErrorMessage = 'Msg ' + CAST(ERROR_NUMBER() AS NVARCHAR) + ', ' + ISNULL(ERROR_MESSAGE(),'') + CASE WHEN ERROR_NUMBER() = 1222 THEN ' The index ' + QUOTENAME(@CurrentIndexName) + ' on the object ' + QUOTENAME(@CurrentDatabaseName) + '.' + QUOTENAME(@CurrentSchemaName) + '.' + QUOTENAME(@CurrentObjectName) + ' is locked. It could not be checked if the index exists.' ELSE '' END;
SET @Severity = CASE WHEN ERROR_NUMBER() IN(1205,1222) THEN @LockMessageSeverity ELSE 16 END;
RAISERROR('%s',@Severity,1,@ErrorMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF NOT (ERROR_NUMBER() IN(1205,1222) AND @LockMessageSeverity = 10)
BEGIN
SET @ReturnCode = ERROR_NUMBER();
END;
GOTO NoAction;
END CATCH;
END;
-- Does the statistics exist?
IF @CurrentStatisticsID IS NOT NULL AND @UpdateStatistics IS NOT NULL
BEGIN
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'IF EXISTS(SELECT * FROM sys.stats stats INNER JOIN sys.objects objects ON stats.[object_id] = objects.[object_id] INNER JOIN sys.schemas schemas ON objects.[schema_id] = schemas.[schema_id] WHERE objects.[type] IN(''U'',''V'')' + CASE WHEN @MSShippedObjects = 'N' THEN ' AND objects.is_ms_shipped = 0' ELSE '' END + ' AND schemas.[schema_id] = @ParamSchemaID AND schemas.[name] = @ParamSchemaName AND objects.[object_id] = @ParamObjectID AND objects.[name] = @ParamObjectName AND objects.[type] = @ParamObjectType AND stats.stats_id = @ParamStatisticsID AND stats.[name] = @ParamStatisticsName) BEGIN SET @ParamStatisticsExists = 1 END';
BEGIN TRY
EXECUTE @CurrentDatabase_sp_executesql @stmt = @CurrentCommand, @params = N'@ParamSchemaID int, @ParamSchemaName sysname, @ParamObjectID int, @ParamObjectName sysname, @ParamObjectType sysname, @ParamStatisticsID int, @ParamStatisticsName sysname, @ParamStatisticsExists bit OUTPUT', @ParamSchemaID = @CurrentSchemaID, @ParamSchemaName = @CurrentSchemaName, @ParamObjectID = @CurrentObjectID, @ParamObjectName = @CurrentObjectName, @ParamObjectType = @CurrentObjectType, @ParamStatisticsID = @CurrentStatisticsID, @ParamStatisticsName = @CurrentStatisticsName, @ParamStatisticsExists = @CurrentStatisticsExists OUTPUT;
IF @CurrentStatisticsExists IS NULL
BEGIN
SET @CurrentStatisticsExists = 0;
GOTO NoAction;
END;
END TRY
BEGIN CATCH
SET @ErrorMessage = 'Msg ' + CAST(ERROR_NUMBER() AS NVARCHAR) + ', ' + ISNULL(ERROR_MESSAGE(),'') + CASE WHEN ERROR_NUMBER() = 1222 THEN ' The statistics ' + QUOTENAME(@CurrentStatisticsName) + ' on the object ' + QUOTENAME(@CurrentDatabaseName) + '.' + QUOTENAME(@CurrentSchemaName) + '.' + QUOTENAME(@CurrentObjectName) + ' is locked. It could not be checked if the statistics exists.' ELSE '' END;
SET @Severity = CASE WHEN ERROR_NUMBER() IN(1205,1222) THEN @LockMessageSeverity ELSE 16 END;
RAISERROR('%s',@Severity,1,@ErrorMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF NOT (ERROR_NUMBER() IN(1205,1222) AND @LockMessageSeverity = 10)
BEGIN
SET @ReturnCode = ERROR_NUMBER();
END;
GOTO NoAction;
END CATCH;
END;
-- Has the data in the statistics been modified since the statistics was last updated?
IF @CurrentStatisticsID IS NOT NULL AND @UpdateStatistics IS NOT NULL
BEGIN
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
IF @PartitionLevelStatistics = 1 AND @CurrentIsIncremental = 1
BEGIN
SET @CurrentCommand += 'SELECT @ParamRowCount = [rows], @ParamModificationCounter = modification_counter FROM sys.dm_db_incremental_stats_properties (@ParamObjectID, @ParamStatisticsID) WHERE partition_number = @ParamPartitionNumber';
END;
ELSE
IF (@Version >= 10.504000 AND @Version < 11) OR @Version >= 11.03000
BEGIN
SET @CurrentCommand += 'SELECT @ParamRowCount = [rows], @ParamModificationCounter = modification_counter FROM sys.dm_db_stats_properties (@ParamObjectID, @ParamStatisticsID)';
END;
ELSE
BEGIN
SET @CurrentCommand += 'SELECT @ParamRowCount = rowcnt, @ParamModificationCounter = rowmodctr FROM sys.sysindexes sysindexes WHERE sysindexes.[id] = @ParamObjectID AND sysindexes.[indid] = @ParamStatisticsID';
END;
BEGIN TRY
EXECUTE @CurrentDatabase_sp_executesql @stmt = @CurrentCommand, @params = N'@ParamObjectID int, @ParamStatisticsID int, @ParamPartitionNumber int, @ParamRowCount bigint OUTPUT, @ParamModificationCounter bigint OUTPUT', @ParamObjectID = @CurrentObjectID, @ParamStatisticsID = @CurrentStatisticsID, @ParamPartitionNumber = @CurrentPartitionNumber, @ParamRowCount = @CurrentRowCount OUTPUT, @ParamModificationCounter = @CurrentModificationCounter OUTPUT;
IF @CurrentRowCount IS NULL SET @CurrentRowCount = 0;
IF @CurrentModificationCounter IS NULL SET @CurrentModificationCounter = 0;
END TRY
BEGIN CATCH
SET @ErrorMessage = 'Msg ' + CAST(ERROR_NUMBER() AS NVARCHAR) + ', ' + ISNULL(ERROR_MESSAGE(),'') + CASE WHEN ERROR_NUMBER() = 1222 THEN ' The statistics ' + QUOTENAME(@CurrentStatisticsName) + ' on the object ' + QUOTENAME(@CurrentDatabaseName) + '.' + QUOTENAME(@CurrentSchemaName) + '.' + QUOTENAME(@CurrentObjectName) + ' is locked. The rows and modification_counter could not be checked.' ELSE '' END;
SET @Severity = CASE WHEN ERROR_NUMBER() IN(1205,1222) THEN @LockMessageSeverity ELSE 16 END;
RAISERROR('%s',@Severity,1,@ErrorMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF NOT (ERROR_NUMBER() IN(1205,1222) AND @LockMessageSeverity = 10)
BEGIN
SET @ReturnCode = ERROR_NUMBER();
END;
GOTO NoAction;
END CATCH;
END;
-- Is the index fragmented?
IF @CurrentIndexID IS NOT NULL
AND @CurrentOnReadOnlyFileGroup = 0
AND EXISTS(SELECT * FROM @ActionsPreferred)
AND (EXISTS(SELECT [Priority], [Action], COUNT(*) FROM @ActionsPreferred GROUP BY [Priority], [Action] HAVING COUNT(*) <> 3) OR @MinNumberOfPages > 0 OR @MaxNumberOfPages IS NOT NULL)
AND NOT (SERVERPROPERTY('EngineEdition') = 8 AND @CurrentDatabaseName IN ('master', 'model'))
BEGIN
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'SELECT @ParamFragmentationLevel = MAX(avg_fragmentation_in_percent), @ParamPageCount = SUM(page_count) FROM sys.dm_db_index_physical_stats(DB_ID(@ParamDatabaseName), @ParamObjectID, @ParamIndexID, @ParamPartitionNumber, ''LIMITED'') WHERE alloc_unit_type_desc = ''IN_ROW_DATA'' AND index_level = 0';
BEGIN TRY
EXECUTE sp_executesql @stmt = @CurrentCommand, @params = N'@ParamDatabaseName nvarchar(max), @ParamObjectID int, @ParamIndexID int, @ParamPartitionNumber int, @ParamFragmentationLevel float OUTPUT, @ParamPageCount bigint OUTPUT', @ParamDatabaseName = @CurrentDatabaseName, @ParamObjectID = @CurrentObjectID, @ParamIndexID = @CurrentIndexID, @ParamPartitionNumber = @CurrentPartitionNumber, @ParamFragmentationLevel = @CurrentFragmentationLevel OUTPUT, @ParamPageCount = @CurrentPageCount OUTPUT;
END TRY
BEGIN CATCH
SET @ErrorMessage = 'Msg ' + CAST(ERROR_NUMBER() AS NVARCHAR) + ', ' + ISNULL(ERROR_MESSAGE(),'') + CASE WHEN ERROR_NUMBER() = 1222 THEN ' The index ' + QUOTENAME(@CurrentIndexName) + ' on the object ' + QUOTENAME(@CurrentDatabaseName) + '.' + QUOTENAME(@CurrentSchemaName) + '.' + QUOTENAME(@CurrentObjectName) + ' is locked. The page_count and avg_fragmentation_in_percent could not be checked.' ELSE '' END;
SET @Severity = CASE WHEN ERROR_NUMBER() IN(1205,1222) THEN @LockMessageSeverity ELSE 16 END;
RAISERROR('%s',@Severity,1,@ErrorMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF NOT (ERROR_NUMBER() IN(1205,1222) AND @LockMessageSeverity = 10)
BEGIN
SET @ReturnCode = ERROR_NUMBER();
END;
GOTO NoAction;
END CATCH;
END;
-- Select fragmentation group
IF @CurrentIndexID IS NOT NULL AND @CurrentOnReadOnlyFileGroup = 0 AND EXISTS(SELECT * FROM @ActionsPreferred)
BEGIN
SET @CurrentFragmentationGroup = CASE
WHEN @CurrentFragmentationLevel >= @FragmentationLevel2 THEN 'High'
WHEN @CurrentFragmentationLevel >= @FragmentationLevel1 AND @CurrentFragmentationLevel < @FragmentationLevel2 THEN 'Medium'
WHEN @CurrentFragmentationLevel < @FragmentationLevel1 THEN 'Low'
END;
END;
-- Which actions are allowed?
IF @CurrentIndexID IS NOT NULL AND EXISTS(SELECT * FROM @ActionsPreferred)
BEGIN
IF NOT (@CurrentOnReadOnlyFileGroup = 1)
AND NOT (@CurrentIsMemoryOptimized = 1)
AND NOT (@CurrentAllowPageLocks = 0)
BEGIN
INSERT INTO @CurrentActionsAllowed ([Action])
VALUES ('INDEX_REORGANIZE');
END;
IF NOT (@CurrentOnReadOnlyFileGroup = 1)
AND NOT (@CurrentIsMemoryOptimized = 1)
BEGIN
INSERT INTO @CurrentActionsAllowed ([Action])
VALUES ('INDEX_REBUILD_OFFLINE');
END;
IF SERVERPROPERTY('EngineEdition') IN (3, 5, 8)
AND NOT (@CurrentOnReadOnlyFileGroup = 1)
AND NOT (@CurrentIsMemoryOptimized = 1)
AND NOT (@CurrentIsPartition = 1 AND @Version < 12)
AND NOT (@CurrentIndexType = 1 AND @CurrentIsImageText = 1)
AND NOT (@CurrentIndexType = 1 AND @CurrentIsFileStream = 1)
AND NOT (@CurrentIndexType = 1 AND @CurrentIsNewLOB = 1 AND @Version < 11)
AND NOT (@CurrentIndexType = 2 AND @CurrentIsNewLOB = 1 AND @Version < 11)
AND NOT (@CurrentIndexType = 3)
AND NOT (@CurrentIndexType = 4)
AND NOT (@CurrentIndexType = 5 AND @Version < 15)
AND NOT (@CurrentIndexType = 6 AND @Version < 14)
AND NOT (@CurrentIndexType = 1 AND @CurrentHasNonClusteredColumnstore = 1 AND @Version < 13)
AND NOT (@CurrentIndexType = 2 AND @CurrentHasClusteredColumnstore = 1 AND @Version < 15)
AND NOT (@CurrentIndexType = 2 AND @CurrentHasNonClusteredColumnstore = 1 AND @Version < 13)
BEGIN
INSERT INTO @CurrentActionsAllowed ([Action])
VALUES ('INDEX_REBUILD_ONLINE');
END;
END;
-- Decide action
IF @CurrentIndexID IS NOT NULL
AND EXISTS(SELECT * FROM @ActionsPreferred)
AND (@CurrentPageCount >= @MinNumberOfPages OR @MinNumberOfPages = 0)
AND (@CurrentPageCount <= @MaxNumberOfPages OR @MaxNumberOfPages IS NULL)
AND @CurrentResumableIndexOperation = 0
BEGIN
IF EXISTS(SELECT [Priority], [Action], COUNT(*) FROM @ActionsPreferred GROUP BY [Priority], [Action] HAVING COUNT(*) <> 3)
BEGIN
SELECT @CurrentAction = [Action]
FROM @ActionsPreferred
WHERE FragmentationGroup = @CurrentFragmentationGroup
AND [Priority] = (SELECT MIN([Priority])
FROM @ActionsPreferred
WHERE FragmentationGroup = @CurrentFragmentationGroup
AND [Action] IN (SELECT [Action] FROM @CurrentActionsAllowed));
END;
ELSE
BEGIN
SELECT @CurrentAction = [Action]
FROM @ActionsPreferred
WHERE [Priority] = (SELECT MIN([Priority])
FROM @ActionsPreferred
WHERE [Action] IN (SELECT [Action] FROM @CurrentActionsAllowed));
END;
END;
IF @CurrentResumableIndexOperation = 1
BEGIN
SET @CurrentAction = 'INDEX_REBUILD_ONLINE';
END;
-- Workaround for limitation in SQL Server, http://support.microsoft.com/kb/2292737
IF @CurrentIndexID IS NOT NULL
BEGIN
SET @CurrentMaxDOP = @MaxDOP;
IF @CurrentAction = 'INDEX_REBUILD_ONLINE' AND @CurrentAllowPageLocks = 0
BEGIN
SET @CurrentMaxDOP = 1;
END;
END;
-- Update statistics?
IF @CurrentStatisticsID IS NOT NULL
AND ((@UpdateStatistics = 'ALL' AND (@CurrentIndexType IN (1,2,3,4,7) OR @CurrentIndexID IS NULL)) OR (@UpdateStatistics = 'INDEX' AND @CurrentIndexID IS NOT NULL AND @CurrentIndexType IN (1,2,3,4,7)) OR (@UpdateStatistics = 'COLUMNS' AND @CurrentIndexID IS NULL))
AND ((@OnlyModifiedStatistics = 'N' AND @StatisticsModificationLevel IS NULL) OR (@OnlyModifiedStatistics = 'Y' AND @CurrentModificationCounter > 0) OR ((@CurrentModificationCounter * 1. / NULLIF(@CurrentRowCount,0)) * 100 >= @StatisticsModificationLevel) OR (@StatisticsModificationLevel IS NOT NULL AND @CurrentModificationCounter > 0 AND (@CurrentModificationCounter >= SQRT(@CurrentRowCount * 1000))) OR (@CurrentIsMemoryOptimized = 1 AND NOT (@Version >= 13 OR SERVERPROPERTY('EngineEdition') IN (5,8))))
AND ((@CurrentIsPartition = 0 AND (@CurrentAction NOT IN('INDEX_REBUILD_ONLINE','INDEX_REBUILD_OFFLINE') OR @CurrentAction IS NULL)) OR (@CurrentIsPartition = 1 AND (@CurrentPartitionNumber = @CurrentPartitionCount OR (@PartitionLevelStatistics = 1 AND @CurrentIsIncremental = 1))))
BEGIN
SET @CurrentUpdateStatistics = 'Y';
END;
ELSE
BEGIN
SET @CurrentUpdateStatistics = 'N';
END;
SET @CurrentStatisticsSample = @StatisticsSample;
SET @CurrentStatisticsResample = @StatisticsResample;
-- Memory-optimized tables only supports FULLSCAN and RESAMPLE in SQL Server 2014
IF @CurrentIsMemoryOptimized = 1 AND NOT (@Version >= 13 OR SERVERPROPERTY('EngineEdition') IN (5,8)) AND (@CurrentStatisticsSample <> 100 OR @CurrentStatisticsSample IS NULL)
BEGIN
SET @CurrentStatisticsSample = NULL;
SET @CurrentStatisticsResample = 'Y';
END;
-- Incremental statistics only supports RESAMPLE
IF @PartitionLevelStatistics = 1 AND @CurrentIsIncremental = 1
BEGIN
SET @CurrentStatisticsSample = NULL;
SET @CurrentStatisticsResample = 'Y';
END;
-- Create index comment
IF @CurrentIndexID IS NOT NULL
BEGIN
SET @CurrentComment = 'ObjectType: ' + CASE WHEN @CurrentObjectType = 'U' THEN 'Table' WHEN @CurrentObjectType = 'V' THEN 'View' ELSE 'N/A' END + ', ';
SET @CurrentComment += 'IndexType: ' + CASE WHEN @CurrentIndexType = 1 THEN 'Clustered' WHEN @CurrentIndexType = 2 THEN 'NonClustered' WHEN @CurrentIndexType = 3 THEN 'XML' WHEN @CurrentIndexType = 4 THEN 'Spatial' WHEN @CurrentIndexType = 5 THEN 'Clustered Columnstore' WHEN @CurrentIndexType = 6 THEN 'NonClustered Columnstore' WHEN @CurrentIndexType = 7 THEN 'NonClustered Hash' ELSE 'N/A' END + ', ';
SET @CurrentComment += 'ImageText: ' + CASE WHEN @CurrentIsImageText = 1 THEN 'Yes' WHEN @CurrentIsImageText = 0 THEN 'No' ELSE 'N/A' END + ', ';
SET @CurrentComment += 'NewLOB: ' + CASE WHEN @CurrentIsNewLOB = 1 THEN 'Yes' WHEN @CurrentIsNewLOB = 0 THEN 'No' ELSE 'N/A' END + ', ';
SET @CurrentComment += 'FileStream: ' + CASE WHEN @CurrentIsFileStream = 1 THEN 'Yes' WHEN @CurrentIsFileStream = 0 THEN 'No' ELSE 'N/A' END + ', ';
IF @Version >= 12 AND @CurrentIndexType NOT IN(5, 6) SET @CurrentComment += 'HasClusteredColumnstore: ' + CASE WHEN @CurrentHasClusteredColumnstore = 1 THEN 'Yes' WHEN @CurrentHasClusteredColumnstore = 0 THEN 'No' ELSE 'N/A' END + ', ';
IF @Version >= 11 AND @CurrentIndexType NOT IN(5, 6) SET @CurrentComment += 'HasNonClusteredColumnstore: ' + CASE WHEN @CurrentHasNonClusteredColumnstore = 1 THEN 'Yes' WHEN @CurrentHasNonClusteredColumnstore = 0 THEN 'No' ELSE 'N/A' END + ', ';
IF @Version >= 14 AND @Resumable = 'Y' SET @CurrentComment += 'Computed: ' + CASE WHEN @CurrentIsComputed = 1 THEN 'Yes' WHEN @CurrentIsComputed = 0 THEN 'No' ELSE 'N/A' END + ', ';
IF @Version >= 14 AND @Resumable = 'Y' AND @CurrentIndexType = 2 SET @CurrentComment += 'ClusteredIndexComputed: ' + CASE WHEN @CurrentIsClusteredIndexComputed = 1 THEN 'Yes' WHEN @CurrentIsClusteredIndexComputed = 0 THEN 'No' ELSE 'N/A' END + ', ';
IF @Version >= 14 AND @Resumable = 'Y' SET @CurrentComment += 'Timestamp: ' + CASE WHEN @CurrentIsTimestamp = 1 THEN 'Yes' WHEN @CurrentIsTimestamp = 0 THEN 'No' ELSE 'N/A' END + ', ';
IF @Version >= 14 AND @Resumable = 'Y' SET @CurrentComment += 'HasFilter: ' + CASE WHEN @CurrentHasFilter = 1 THEN 'Yes' WHEN @CurrentHasFilter = 0 THEN 'No' ELSE 'N/A' END + ', ';
SET @CurrentComment += 'AllowPageLocks: ' + CASE WHEN @CurrentAllowPageLocks = 1 THEN 'Yes' WHEN @CurrentAllowPageLocks = 0 THEN 'No' ELSE 'N/A' END + ', ';
SET @CurrentComment += 'PageCount: ' + ISNULL(CAST(@CurrentPageCount AS NVARCHAR),'N/A') + ', ';
SET @CurrentComment += 'Fragmentation: ' + ISNULL(CAST(@CurrentFragmentationLevel AS NVARCHAR),'N/A');
END;
IF @CurrentIndexID IS NOT NULL AND (@CurrentPageCount IS NOT NULL OR @CurrentFragmentationLevel IS NOT NULL)
BEGIN
SET @CurrentExtendedInfo = (SELECT *
FROM (SELECT CAST(@CurrentPageCount AS NVARCHAR) AS [PageCount],
CAST(@CurrentFragmentationLevel AS NVARCHAR) AS Fragmentation
) ExtendedInfo FOR XML RAW('ExtendedInfo'), ELEMENTS);
END;
IF @CurrentIndexID IS NOT NULL AND @CurrentAction IS NOT NULL AND (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SET @CurrentDatabaseContext = @CurrentDatabaseName;
SET @CurrentCommandType = 'ALTER_INDEX';
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'ALTER INDEX ' + QUOTENAME(@CurrentIndexName) + ' ON ' + QUOTENAME(@CurrentSchemaName) + '.' + QUOTENAME(@CurrentObjectName);
IF @CurrentResumableIndexOperation = 1 SET @CurrentCommand += ' RESUME';
IF @CurrentAction IN('INDEX_REBUILD_ONLINE','INDEX_REBUILD_OFFLINE') AND @CurrentResumableIndexOperation = 0 SET @CurrentCommand += ' REBUILD';
IF @CurrentAction IN('INDEX_REORGANIZE') AND @CurrentResumableIndexOperation = 0 SET @CurrentCommand += ' REORGANIZE';
IF @CurrentIsPartition = 1 AND @CurrentResumableIndexOperation = 0 SET @CurrentCommand += ' PARTITION = ' + CAST(@CurrentPartitionNumber AS NVARCHAR);
IF @CurrentAction IN('INDEX_REBUILD_ONLINE','INDEX_REBUILD_OFFLINE') AND @SortInTempdb = 'Y' AND @CurrentIndexType IN(1,2,3,4) AND @CurrentResumableIndexOperation = 0
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT 'SORT_IN_TEMPDB = ON';
END;
IF @CurrentAction IN('INDEX_REBUILD_ONLINE','INDEX_REBUILD_OFFLINE') AND @SortInTempdb = 'N' AND @CurrentIndexType IN(1,2,3,4) AND @CurrentResumableIndexOperation = 0
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT 'SORT_IN_TEMPDB = OFF';
END;
IF @CurrentAction = 'INDEX_REBUILD_ONLINE' AND (@CurrentIsPartition = 0 OR @Version >= 12) AND @CurrentResumableIndexOperation = 0
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT 'ONLINE = ON' + CASE WHEN @WaitAtLowPriorityMaxDuration IS NOT NULL THEN ' (WAIT_AT_LOW_PRIORITY (MAX_DURATION = ' + CAST(@WaitAtLowPriorityMaxDuration AS NVARCHAR) + ', ABORT_AFTER_WAIT = ' + UPPER(@WaitAtLowPriorityAbortAfterWait) + '))' ELSE '' END;
END;
IF @CurrentAction = 'INDEX_REBUILD_OFFLINE' AND (@CurrentIsPartition = 0 OR @Version >= 12) AND @CurrentResumableIndexOperation = 0
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT 'ONLINE = OFF';
END;
IF @CurrentAction IN('INDEX_REBUILD_ONLINE','INDEX_REBUILD_OFFLINE') AND @CurrentMaxDOP IS NOT NULL
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT 'MAXDOP = ' + CAST(@CurrentMaxDOP AS NVARCHAR);
END;
IF @CurrentAction IN('INDEX_REBUILD_ONLINE','INDEX_REBUILD_OFFLINE') AND @FillFactor IS NOT NULL AND @CurrentIsPartition = 0 AND @CurrentIndexType IN(1,2,3,4) AND @CurrentResumableIndexOperation = 0
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT 'FILLFACTOR = ' + CAST(@FillFactor AS NVARCHAR);
END;
IF @CurrentAction IN('INDEX_REBUILD_ONLINE','INDEX_REBUILD_OFFLINE') AND @PadIndex = 'Y' AND @CurrentIsPartition = 0 AND @CurrentIndexType IN(1,2,3,4) AND @CurrentResumableIndexOperation = 0
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT 'PAD_INDEX = ON';
END;
IF (@Version >= 14 OR SERVERPROPERTY('EngineEdition') IN (5,8)) AND @CurrentAction = 'INDEX_REBUILD_ONLINE' AND @CurrentResumableIndexOperation = 0
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT CASE WHEN @Resumable = 'Y' AND @CurrentIndexType IN(1,2) AND @CurrentIsComputed = 0 AND @CurrentIsClusteredIndexComputed = 0 AND @CurrentIsTimestamp = 0 AND @CurrentHasFilter = 0 THEN 'RESUMABLE = ON' ELSE 'RESUMABLE = OFF' END;
END;
IF (@Version >= 14 OR SERVERPROPERTY('EngineEdition') IN (5,8)) AND @CurrentAction = 'INDEX_REBUILD_ONLINE' AND @Resumable = 'Y' AND @CurrentIndexType IN(1,2) AND @CurrentIsComputed = 0 AND @CurrentIsClusteredIndexComputed = 0 AND @CurrentIsTimestamp = 0 AND @CurrentHasFilter = 0 AND @TimeLimit IS NOT NULL
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT 'MAX_DURATION = ' + CAST(DATEDIFF(MINUTE,SYSDATETIME(),DATEADD(SECOND,@TimeLimit,@StartTime)) AS NVARCHAR(MAX));
END;
IF @CurrentAction IN('INDEX_REORGANIZE') AND @LOBCompaction = 'Y'
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT 'LOB_COMPACTION = ON';
END;
IF @CurrentAction IN('INDEX_REORGANIZE') AND @LOBCompaction = 'N'
BEGIN
INSERT INTO @CurrentAlterIndexWithClauseArguments (Argument)
SELECT 'LOB_COMPACTION = OFF';
END;
IF EXISTS (SELECT * FROM @CurrentAlterIndexWithClauseArguments)
BEGIN
SET @CurrentAlterIndexWithClause = ' WITH (';
WHILE (1 = 1)
BEGIN
SELECT TOP 1 @CurrentAlterIndexArgumentID = [Id],
@CurrentAlterIndexArgument = Argument
FROM @CurrentAlterIndexWithClauseArguments
WHERE Added = 0
ORDER BY [Id] ASC;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
SET @CurrentAlterIndexWithClause += @CurrentAlterIndexArgument + ', ';
UPDATE @CurrentAlterIndexWithClauseArguments
SET Added = 1
WHERE [ID] = @CurrentAlterIndexArgumentID;
END;
SET @CurrentAlterIndexWithClause = RTRIM(@CurrentAlterIndexWithClause);
SET @CurrentAlterIndexWithClause = LEFT(@CurrentAlterIndexWithClause,LEN(@CurrentAlterIndexWithClause) - 1);
SET @CurrentAlterIndexWithClause = @CurrentAlterIndexWithClause + ')';
END;
IF @CurrentAlterIndexWithClause IS NOT NULL SET @CurrentCommand += @CurrentAlterIndexWithClause;
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseName, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 2, @Comment = @CurrentComment, @DatabaseName = @CurrentDatabaseName, @SchemaName = @CurrentSchemaName, @ObjectName = @CurrentObjectName, @ObjectType = @CurrentObjectType, @IndexName = @CurrentIndexName, @IndexType = @CurrentIndexType, @PartitionNumber = @CurrentPartitionNumber, @ExtendedInfo = @CurrentExtendedInfo, @LockMessageSeverity = @LockMessageSeverity, @ExecuteAsUser = @ExecuteAsUser, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
IF @Delay > 0
BEGIN
SET @CurrentDelay = DATEADD(ss,@Delay,'1900-01-01');
WAITFOR DELAY @CurrentDelay;
END;
END;
SET @CurrentMaxDOP = @MaxDOP;
-- Create statistics comment
IF @CurrentStatisticsID IS NOT NULL
BEGIN
SET @CurrentComment = 'ObjectType: ' + CASE WHEN @CurrentObjectType = 'U' THEN 'Table' WHEN @CurrentObjectType = 'V' THEN 'View' ELSE 'N/A' END + ', ';
SET @CurrentComment += 'IndexType: ' + CASE WHEN @CurrentIndexID IS NOT NULL THEN 'Index' ELSE 'Column' END + ', ';
IF @CurrentIndexID IS NOT NULL SET @CurrentComment += 'IndexType: ' + CASE WHEN @CurrentIndexType = 1 THEN 'Clustered' WHEN @CurrentIndexType = 2 THEN 'NonClustered' WHEN @CurrentIndexType = 3 THEN 'XML' WHEN @CurrentIndexType = 4 THEN 'Spatial' WHEN @CurrentIndexType = 5 THEN 'Clustered Columnstore' WHEN @CurrentIndexType = 6 THEN 'NonClustered Columnstore' WHEN @CurrentIndexType = 7 THEN 'NonClustered Hash' ELSE 'N/A' END + ', ';
SET @CurrentComment += 'Incremental: ' + CASE WHEN @CurrentIsIncremental = 1 THEN 'Y' WHEN @CurrentIsIncremental = 0 THEN 'N' ELSE 'N/A' END + ', ';
SET @CurrentComment += 'RowCount: ' + ISNULL(CAST(@CurrentRowCount AS NVARCHAR),'N/A') + ', ';
SET @CurrentComment += 'ModificationCounter: ' + ISNULL(CAST(@CurrentModificationCounter AS NVARCHAR),'N/A');
END;
IF @CurrentStatisticsID IS NOT NULL AND (@CurrentRowCount IS NOT NULL OR @CurrentModificationCounter IS NOT NULL)
BEGIN
SET @CurrentExtendedInfo = (SELECT *
FROM (SELECT CAST(@CurrentRowCount AS NVARCHAR) AS [RowCount],
CAST(@CurrentModificationCounter AS NVARCHAR) AS ModificationCounter
) ExtendedInfo FOR XML RAW('ExtendedInfo'), ELEMENTS);
END;
IF @CurrentStatisticsID IS NOT NULL AND @CurrentUpdateStatistics = 'Y' AND (SYSDATETIME() < DATEADD(SECOND,@TimeLimit,@StartTime) OR @TimeLimit IS NULL)
BEGIN
SET @CurrentDatabaseContext = @CurrentDatabaseName;
SET @CurrentCommandType = 'UPDATE_STATISTICS';
SET @CurrentCommand = '';
IF @LockTimeout IS NOT NULL SET @CurrentCommand = 'SET LOCK_TIMEOUT ' + CAST(@LockTimeout * 1000 AS NVARCHAR) + '; ';
SET @CurrentCommand += 'UPDATE STATISTICS ' + QUOTENAME(@CurrentSchemaName) + '.' + QUOTENAME(@CurrentObjectName) + ' ' + QUOTENAME(@CurrentStatisticsName);
IF @CurrentMaxDOP IS NOT NULL AND ((@Version >= 12.06024 AND @Version < 13) OR (@Version >= 13.05026 AND @Version < 14) OR @Version >= 14.030154)
BEGIN
INSERT INTO @CurrentUpdateStatisticsWithClauseArguments (Argument)
SELECT 'MAXDOP = ' + CAST(@CurrentMaxDOP AS NVARCHAR);
END;
IF @CurrentStatisticsSample = 100
BEGIN
INSERT INTO @CurrentUpdateStatisticsWithClauseArguments (Argument)
SELECT 'FULLSCAN';
END;
IF @CurrentStatisticsSample IS NOT NULL AND @CurrentStatisticsSample <> 100
BEGIN
INSERT INTO @CurrentUpdateStatisticsWithClauseArguments (Argument)
SELECT 'SAMPLE ' + CAST(@CurrentStatisticsSample AS NVARCHAR) + ' PERCENT';
END;
IF @CurrentNoRecompute = 1
BEGIN
INSERT INTO @CurrentUpdateStatisticsWithClauseArguments (Argument)
SELECT 'NORECOMPUTE';
END;
IF @CurrentStatisticsResample = 'Y'
BEGIN
INSERT INTO @CurrentUpdateStatisticsWithClauseArguments (Argument)
SELECT 'RESAMPLE';
END;
IF EXISTS (SELECT * FROM @CurrentUpdateStatisticsWithClauseArguments)
BEGIN
SET @CurrentUpdateStatisticsWithClause = ' WITH';
WHILE (1 = 1)
BEGIN
SELECT TOP 1 @CurrentUpdateStatisticsArgumentID = [Id],
@CurrentUpdateStatisticsArgument = Argument
FROM @CurrentUpdateStatisticsWithClauseArguments
WHERE Added = 0
ORDER BY [Id] ASC;
IF @@ROWCOUNT = 0
BEGIN
BREAK;
END;
SET @CurrentUpdateStatisticsWithClause = @CurrentUpdateStatisticsWithClause + ' ' + @CurrentUpdateStatisticsArgument + ',';
UPDATE @CurrentUpdateStatisticsWithClauseArguments
SET Added = 1
WHERE [ID] = @CurrentUpdateStatisticsArgumentID;
END;
SET @CurrentUpdateStatisticsWithClause = LEFT(@CurrentUpdateStatisticsWithClause,LEN(@CurrentUpdateStatisticsWithClause) - 1);
END;
IF @CurrentUpdateStatisticsWithClause IS NOT NULL SET @CurrentCommand += @CurrentUpdateStatisticsWithClause;
IF @PartitionLevelStatistics = 1 AND @CurrentIsIncremental = 1 AND @CurrentPartitionNumber IS NOT NULL SET @CurrentCommand += ' ON PARTITIONS(' + CAST(@CurrentPartitionNumber AS NVARCHAR(MAX)) + ')';
EXECUTE @CurrentCommandOutput = [dbo].CommandExecute @DatabaseContext = @CurrentDatabaseName, @Command = @CurrentCommand, @CommandType = @CurrentCommandType, @Mode = 2, @Comment = @CurrentComment, @DatabaseName = @CurrentDatabaseName, @SchemaName = @CurrentSchemaName, @ObjectName = @CurrentObjectName, @ObjectType = @CurrentObjectType, @IndexName = @CurrentIndexName, @IndexType = @CurrentIndexType, @StatisticsName = @CurrentStatisticsName, @ExtendedInfo = @CurrentExtendedInfo, @LockMessageSeverity = @LockMessageSeverity, @ExecuteAsUser = @ExecuteAsUser, @LogToTable = @LogToTable, @Execute = @Execute;
SET @Error = @@ERROR;
IF @Error <> 0 SET @CurrentCommandOutput = @Error;
IF @CurrentCommandOutput <> 0 SET @ReturnCode = @CurrentCommandOutput;
END;
NoAction:;
-- Update that the index or statistics is completed
UPDATE @tmpIndexesStatistics
SET Completed = 1
WHERE Selected = 1
AND Completed = 0
AND [Order] = @CurrentIxOrder
AND [Id] = @CurrentIxID;
-- Clear variables
SET @CurrentDatabaseContext = NULL;
SET @CurrentCommand = NULL;
SET @CurrentCommandOutput = NULL;
SET @CurrentCommandType = NULL;
SET @CurrentComment = NULL;
SET @CurrentExtendedInfo = NULL;
SET @CurrentIxID = NULL;
SET @CurrentIxOrder = NULL;
SET @CurrentSchemaID = NULL;
SET @CurrentSchemaName = NULL;
SET @CurrentObjectID = NULL;
SET @CurrentObjectName = NULL;
SET @CurrentObjectType = NULL;
SET @CurrentIsMemoryOptimized = NULL;
SET @CurrentIndexID = NULL;
SET @CurrentIndexName = NULL;
SET @CurrentIndexType = NULL;
SET @CurrentStatisticsID = NULL;
SET @CurrentStatisticsName = NULL;
SET @CurrentPartitionID = NULL;
SET @CurrentPartitionNumber = NULL;
SET @CurrentPartitionCount = NULL;
SET @CurrentIsPartition = NULL;
SET @CurrentIndexExists = NULL;
SET @CurrentStatisticsExists = NULL;
SET @CurrentIsImageText = NULL;
SET @CurrentIsNewLOB = NULL;
SET @CurrentIsFileStream = NULL;
SET @CurrentHasClusteredColumnstore = NULL;
SET @CurrentHasNonClusteredColumnstore = NULL;
SET @CurrentIsComputed = NULL;
SET @CurrentIsClusteredIndexComputed = NULL;
SET @CurrentIsTimestamp = NULL;
SET @CurrentAllowPageLocks = NULL;
SET @CurrentHasFilter = NULL;
SET @CurrentNoRecompute = NULL;
SET @CurrentIsIncremental = NULL;
SET @CurrentRowCount = NULL;
SET @CurrentModificationCounter = NULL;
SET @CurrentOnReadOnlyFileGroup = NULL;
SET @CurrentResumableIndexOperation = NULL;
SET @CurrentFragmentationLevel = NULL;
SET @CurrentPageCount = NULL;
SET @CurrentFragmentationGroup = NULL;
SET @CurrentAction = NULL;
SET @CurrentMaxDOP = NULL;
SET @CurrentUpdateStatistics = NULL;
SET @CurrentStatisticsSample = NULL;
SET @CurrentStatisticsResample = NULL;
SET @CurrentAlterIndexArgumentID = NULL;
SET @CurrentAlterIndexArgument = NULL;
SET @CurrentAlterIndexWithClause = NULL;
SET @CurrentUpdateStatisticsArgumentID = NULL;
SET @CurrentUpdateStatisticsArgument = NULL;
SET @CurrentUpdateStatisticsWithClause = NULL;
DELETE FROM @CurrentActionsAllowed;
DELETE FROM @CurrentAlterIndexWithClauseArguments;
DELETE FROM @CurrentUpdateStatisticsWithClauseArguments;
END;
END;
IF @CurrentDatabaseState = 'SUSPECT'
BEGIN
SET @ErrorMessage = 'The database ' + QUOTENAME(@CurrentDatabaseName) + ' is in a SUSPECT state.';
RAISERROR('%s',16,1,@ErrorMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
SET @Error = @@ERROR;
END;
-- Update that the database is completed
IF @DatabasesInParallel = 'Y'
BEGIN
UPDATE [dbo].QueueDatabase
SET DatabaseEndTime = SYSDATETIME()
WHERE QueueID = @QueueID
AND DatabaseName = @CurrentDatabaseName;
END;
ELSE
BEGIN
UPDATE @tmpDatabases
SET Completed = 1
WHERE Selected = 1
AND Completed = 0
AND [Id] = @CurrentDBID;
END;
-- Clear variables
SET @CurrentDBID = NULL;
SET @CurrentDatabaseName = NULL;
SET @CurrentDatabase_sp_executesql = NULL;
SET @CurrentExecuteAsUserExists = NULL;
SET @CurrentUserAccess = NULL;
SET @CurrentIsReadOnly = NULL;
SET @CurrentDatabaseState = NULL;
SET @CurrentInStandby = NULL;
SET @CurrentRecoveryModel = NULL;
SET @CurrentReplicaID = NULL;
SET @CurrentAvailabilityGroupID = NULL;
SET @CurrentAvailabilityGroup = NULL;
SET @CurrentAvailabilityGroupRole = NULL;
SET @CurrentDatabaseMirroringRole = NULL;
SET @CurrentCommand = NULL;
DELETE FROM @tmpIndexesStatistics;
END;
----------------------------------------------------------------------------------------------------
--// Log completing information //--
----------------------------------------------------------------------------------------------------
Logging:;
SET @EndMessage = 'Date and time: ' + CONVERT(NVARCHAR,SYSDATETIME(),120);
RAISERROR('%s',10,1,@EndMessage) WITH NOWAIT;
RAISERROR(@EmptyLine,10,1) WITH NOWAIT;
IF @ReturnCode <> 0
BEGIN
RETURN @ReturnCode;
END;
----------------------------------------------------------------------------------------------------
END;
GO
IF (SELECT [Value] FROM #Config WHERE [name] = 'CreateJobs') = 'Y'
AND SERVERPROPERTY('EngineEdition') NOT IN(4, 5)
AND (IS_SRVROLEMEMBER('sysadmin') = 1 OR (EXISTS (SELECT * FROM [sys].[databases] WHERE [name] = 'rdsadmin') AND SUSER_SNAME(0x01) = 'rdsa'))
AND (SELECT [compatibility_level] FROM [sys].[databases] WHERE [name] = DB_NAME()) >= 90
AND NOT (EXISTS (SELECT * FROM #Config WHERE [name] = 'BackupDirectory' AND [Value] IS NOT NULL) AND EXISTS (SELECT * FROM #Config WHERE [name] = 'BackupURL' AND [Value] IS NOT NULL))
AND NOT (EXISTS (SELECT * FROM #Config WHERE [name] = 'BackupURL' AND [Value] IS NOT NULL) AND EXISTS (SELECT * FROM #Config WHERE [name] = 'CleanupTime' AND [Value] IS NOT NULL))
BEGIN
DECLARE @BackupDirectory NVARCHAR(MAX);
DECLARE @BackupURL NVARCHAR(MAX);
DECLARE @CleanupTime INT;
DECLARE @OutputFileDirectory NVARCHAR(MAX);
DECLARE @LogToTable NVARCHAR(MAX);
DECLARE @DatabaseName NVARCHAR(MAX);
DECLARE @HostPlatform NVARCHAR(MAX);
DECLARE @DirectorySeparator NVARCHAR(MAX);
DECLARE @LogDirectory NVARCHAR(MAX);
DECLARE @TokenServer NVARCHAR(MAX);
DECLARE @TokenJobID NVARCHAR(MAX);
DECLARE @TokenJobName NVARCHAR(MAX);
DECLARE @TokenStepID NVARCHAR(MAX);
DECLARE @TokenStepName NVARCHAR(MAX);
DECLARE @TokenDate NVARCHAR(MAX);
DECLARE @TokenTime NVARCHAR(MAX);
DECLARE @TokenLogDirectory NVARCHAR(MAX);
DECLARE @JobDescription NVARCHAR(MAX);
DECLARE @JobCategory NVARCHAR(MAX);
DECLARE @JobOwner NVARCHAR(MAX);
DECLARE @Jobs TABLE ([JobId] INT IDENTITY,
[Name] NVARCHAR(MAX),
CommandTSQL NVARCHAR(MAX),
CommandCmdExec NVARCHAR(MAX),
DatabaseName VARCHAR(MAX),
OutputFileNamePart01 NVARCHAR(MAX),
OutputFileNamePart02 NVARCHAR(MAX),
Selected BIT DEFAULT 0,
Completed BIT DEFAULT 0);
DECLARE @CurrentJobID INT;
DECLARE @CurrentJobName NVARCHAR(MAX);
DECLARE @CurrentCommandTSQL NVARCHAR(MAX);
DECLARE @CurrentCommandCmdExec NVARCHAR(MAX);
DECLARE @CurrentDatabaseName NVARCHAR(MAX);
DECLARE @CurrentOutputFileNamePart01 NVARCHAR(MAX);
DECLARE @CurrentOutputFileNamePart02 NVARCHAR(MAX);
DECLARE @CurrentJobStepCommand NVARCHAR(MAX);
DECLARE @CurrentJobStepSubSystem NVARCHAR(MAX);
DECLARE @CurrentJobStepDatabaseName NVARCHAR(MAX);
DECLARE @CurrentOutputFileName NVARCHAR(MAX);
DECLARE @Version NUMERIC(18,10) = CAST(LEFT(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)),CHARINDEX('.',CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX))) - 1) + '.' + REPLACE(RIGHT(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)), LEN(CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX))) - CHARINDEX('.',CAST(SERVERPROPERTY('ProductVersion') AS NVARCHAR(MAX)))),'.','') AS NUMERIC(18,10));
DECLARE @AmazonRDS BIT = CASE WHEN SERVERPROPERTY('EngineEdition') IN (5, 8) THEN 0 WHEN EXISTS (SELECT * FROM [sys].[databases] WHERE [name] = 'rdsadmin') AND SUSER_SNAME(0x01) = 'rdsa' THEN 1 ELSE 0 END;
IF @Version >= 14
BEGIN
SELECT @HostPlatform = [host_platform]
FROM [sys].[dm_os_host_info];
END;
ELSE
BEGIN
SET @HostPlatform = 'Windows';
END;
SELECT @DirectorySeparator = CASE
WHEN @HostPlatform = 'Windows' THEN '\'
WHEN @HostPlatform = 'Linux' THEN '/'
END;
SET @TokenServer = '$' + '(ESCAPE_SQUOTE(SRVR))';
SET @TokenJobID = '$' + '(ESCAPE_SQUOTE(JOBID))';
SET @TokenStepID = '$' + '(ESCAPE_SQUOTE(STEPID))';
SET @TokenDate = '$' + '(ESCAPE_SQUOTE(DATE))';
SET @TokenTime = '$' + '(ESCAPE_SQUOTE(TIME))';
IF @Version >= 13
BEGIN
SET @TokenJobName = '$' + '(ESCAPE_SQUOTE(JOBNAME))';
SET @TokenStepName = '$' + '(ESCAPE_SQUOTE(STEPNAME))';
END;
IF @Version >= 12 AND @HostPlatform = 'Windows'
BEGIN
SET @TokenLogDirectory = '$' + '(ESCAPE_SQUOTE(SQLLOGDIR))';
END;
SELECT @BackupDirectory = VALUE
FROM #Config
WHERE [Name] = 'BackupDirectory';
SELECT @BackupURL = VALUE
FROM #Config
WHERE [Name] = 'BackupURL';
SELECT @CleanupTime = VALUE
FROM #Config
WHERE [Name] = 'CleanupTime';
SELECT @OutputFileDirectory = VALUE
FROM #Config
WHERE [Name] = 'OutputFileDirectory';
SELECT @LogToTable = VALUE
FROM #Config
WHERE [Name] = 'LogToTable';
SELECT @DatabaseName = VALUE
FROM #Config
WHERE [Name] = 'DatabaseName';
IF @Version >= 11
BEGIN
SELECT @LogDirectory = [path]
FROM [sys].[dm_os_server_diagnostics_log_configurations];
END;
ELSE
BEGIN
SELECT @LogDirectory = LEFT(CAST(SERVERPROPERTY('ErrorLogFileName') AS NVARCHAR(MAX)),LEN(CAST(SERVERPROPERTY('ErrorLogFileName') AS NVARCHAR(MAX))) - CHARINDEX('\',REVERSE(CAST(SERVERPROPERTY('ErrorLogFileName') AS NVARCHAR(MAX)))));
END;
IF @OutputFileDirectory IS NOT NULL AND RIGHT(@OutputFileDirectory,1) = @DirectorySeparator
BEGIN
SET @OutputFileDirectory = LEFT(@OutputFileDirectory, LEN(@OutputFileDirectory) - 1);
END;
IF @LogDirectory IS NOT NULL AND RIGHT(@LogDirectory,1) = @DirectorySeparator
BEGIN
SET @LogDirectory = LEFT(@LogDirectory, LEN(@LogDirectory) - 1);
END;
SET @JobDescription = 'Source: https://ola.hallengren.com';
SET @JobCategory = 'Database Maintenance';
IF @AmazonRDS = 0
BEGIN
SET @JobOwner = SUSER_SNAME(0x01);
END;
INSERT INTO @Jobs ([Name], CommandTSQL, DatabaseName, OutputFileNamePart01, OutputFileNamePart02)
SELECT 'DatabaseBackup - SYSTEM_DATABASES - FULL',
'EXECUTE [dbo].[DatabaseBackup]' + CHAR(13) + CHAR(10) + '@Databases = ''SYSTEM_DATABASES'',' + CHAR(13) + CHAR(10) + CASE WHEN @BackupURL IS NOT NULL THEN '@URL = N''' + REPLACE(@BackupURL,'''','''''') + '''' ELSE '@Directory = ' + ISNULL('N''' + REPLACE(@BackupDirectory,'''','''''') + '''','NULL') END + ',' + CHAR(13) + CHAR(10) + '@BackupType = ''FULL'',' + CHAR(13) + CHAR(10) + '@Verify = ''Y'',' + CHAR(13) + CHAR(10) + '@CleanupTime = ' + ISNULL(CAST(@CleanupTime AS NVARCHAR),'NULL') + ',' + CHAR(13) + CHAR(10) + '@Checksum = ''Y'',' + CHAR(13) + CHAR(10) + '@LogToTable = ''' + @LogToTable + '''',
@DatabaseName,
'DatabaseBackup',
'FULL';
INSERT INTO @Jobs ([Name], CommandTSQL, DatabaseName, OutputFileNamePart01, OutputFileNamePart02)
SELECT 'DatabaseBackup - USER_DATABASES - DIFF',
'EXECUTE [dbo].[DatabaseBackup]' + CHAR(13) + CHAR(10) + '@Databases = ''USER_DATABASES'',' + CHAR(13) + CHAR(10) + CASE WHEN @BackupURL IS NOT NULL THEN '@URL = N''' + REPLACE(@BackupURL,'''','''''') + '''' ELSE '@Directory = ' + ISNULL('N''' + REPLACE(@BackupDirectory,'''','''''') + '''','NULL') END + ',' + CHAR(13) + CHAR(10) + '@BackupType = ''DIFF'',' + CHAR(13) + CHAR(10) + '@Verify = ''Y'',' + CHAR(13) + CHAR(10) + '@CleanupTime = ' + ISNULL(CAST(@CleanupTime AS NVARCHAR),'NULL') + ',' + CHAR(13) + CHAR(10) + '@Checksum = ''Y'',' + CHAR(13) + CHAR(10) + '@LogToTable = ''' + @LogToTable + '''',
@DatabaseName,
'DatabaseBackup',
'DIFF';
INSERT INTO @Jobs ([Name], CommandTSQL, DatabaseName, OutputFileNamePart01, OutputFileNamePart02)
SELECT 'DatabaseBackup - USER_DATABASES - FULL',
'EXECUTE [dbo].[DatabaseBackup]' + CHAR(13) + CHAR(10) + '@Databases = ''USER_DATABASES'',' + CHAR(13) + CHAR(10) + CASE WHEN @BackupURL IS NOT NULL THEN '@URL = N''' + REPLACE(@BackupURL,'''','''''') + '''' ELSE '@Directory = ' + ISNULL('N''' + REPLACE(@BackupDirectory,'''','''''') + '''','NULL') END + ',' + CHAR(13) + CHAR(10) + '@BackupType = ''FULL'',' + CHAR(13) + CHAR(10) + '@Verify = ''Y'',' + CHAR(13) + CHAR(10) + '@CleanupTime = ' + ISNULL(CAST(@CleanupTime AS NVARCHAR),'NULL') + ',' + CHAR(13) + CHAR(10) + '@Checksum = ''Y'',' + CHAR(13) + CHAR(10) + '@LogToTable = ''' + @LogToTable + '''',
@DatabaseName,
'DatabaseBackup',
'FULL';
INSERT INTO @Jobs ([Name], CommandTSQL, DatabaseName, OutputFileNamePart01, OutputFileNamePart02)
SELECT 'DatabaseBackup - USER_DATABASES - LOG',
'EXECUTE [dbo].[DatabaseBackup]' + CHAR(13) + CHAR(10) + '@Databases = ''USER_DATABASES'',' + CHAR(13) + CHAR(10) + CASE WHEN @BackupURL IS NOT NULL THEN '@URL = N''' + REPLACE(@BackupURL,'''','''''') + '''' ELSE '@Directory = ' + ISNULL('N''' + REPLACE(@BackupDirectory,'''','''''') + '''','NULL') END + ',' + CHAR(13) + CHAR(10) + '@BackupType = ''LOG'',' + CHAR(13) + CHAR(10) + '@Verify = ''Y'',' + CHAR(13) + CHAR(10) + '@CleanupTime = ' + ISNULL(CAST(@CleanupTime AS NVARCHAR),'NULL') + ',' + CHAR(13) + CHAR(10) + '@Checksum = ''Y'',' + CHAR(13) + CHAR(10) + '@LogToTable = ''' + @LogToTable + '''',
@DatabaseName,
'DatabaseBackup',
'LOG';
INSERT INTO @Jobs ([Name], CommandTSQL, DatabaseName, OutputFileNamePart01)
SELECT 'DatabaseIntegrityCheck - SYSTEM_DATABASES',
'EXECUTE [dbo].[DatabaseIntegrityCheck]' + CHAR(13) + CHAR(10) + '@Databases = ''SYSTEM_DATABASES'',' + CHAR(13) + CHAR(10) + '@LogToTable = ''' + @LogToTable + '''',
@DatabaseName,
'DatabaseIntegrityCheck';
INSERT INTO @Jobs ([Name], CommandTSQL, DatabaseName, OutputFileNamePart01)
SELECT 'DatabaseIntegrityCheck - USER_DATABASES',
'EXECUTE [dbo].[DatabaseIntegrityCheck]' + CHAR(13) + CHAR(10) + '@Databases = ''USER_DATABASES'',' + CHAR(13) + CHAR(10) + '@LogToTable = ''' + @LogToTable + '''',
@DatabaseName,
'DatabaseIntegrityCheck';
INSERT INTO @Jobs ([Name], CommandTSQL, DatabaseName, OutputFileNamePart01)
SELECT 'IndexOptimize - USER_DATABASES',
'EXECUTE [dbo].[IndexOptimize]' + CHAR(13) + CHAR(10) + '@Databases = ''USER_DATABASES'',' + CHAR(13) + CHAR(10) + '@LogToTable = ''' + @LogToTable + '''',
@DatabaseName,
'IndexOptimize';
INSERT INTO @Jobs ([Name], CommandTSQL, DatabaseName, OutputFileNamePart01)
SELECT 'sp_delete_backuphistory',
'DECLARE @CleanupDate datetime' + CHAR(13) + CHAR(10) + 'SET @CleanupDate = DATEADD(dd,-30,GETDATE())' + CHAR(13) + CHAR(10) + 'EXECUTE dbo.sp_delete_backuphistory @oldest_date = @CleanupDate',
'msdb',
'sp_delete_backuphistory';
INSERT INTO @Jobs ([Name], CommandTSQL, DatabaseName, OutputFileNamePart01)
SELECT 'sp_purge_jobhistory',
'DECLARE @CleanupDate datetime' + CHAR(13) + CHAR(10) + 'SET @CleanupDate = DATEADD(dd,-30,GETDATE())' + CHAR(13) + CHAR(10) + 'EXECUTE dbo.sp_purge_jobhistory @oldest_date = @CleanupDate',
'msdb',
'sp_purge_jobhistory';
INSERT INTO @Jobs ([Name], CommandTSQL, DatabaseName, OutputFileNamePart01)
SELECT 'CommandLog Cleanup',
'DELETE FROM [dbo].[CommandLog]' + CHAR(13) + CHAR(10) + 'WHERE StartTime < DATEADD(dd,-30,GETDATE())',
@DatabaseName,
'CommandLogCleanup';
INSERT INTO @Jobs ([Name], CommandCmdExec, OutputFileNamePart01)
SELECT 'Output File Cleanup',
'cmd /q /c "For /F "tokens=1 delims=" %v In (''ForFiles /P "' + COALESCE(@OutputFileDirectory,@TokenLogDirectory,@LogDirectory) + '" /m *_*_*_*.txt /d -30 2^>^&1'') do if EXIST "' + COALESCE(@OutputFileDirectory,@TokenLogDirectory,@LogDirectory) + '"\%v echo del "' + COALESCE(@OutputFileDirectory,@TokenLogDirectory,@LogDirectory) + '"\%v& del "' + COALESCE(@OutputFileDirectory,@TokenLogDirectory,@LogDirectory) + '"\%v"',
'OutputFileCleanup';
IF @AmazonRDS = 1
BEGIN
UPDATE @Jobs
SET Selected = 1
WHERE [Name] IN('DatabaseIntegrityCheck - USER_DATABASES','IndexOptimize - USER_DATABASES','CommandLog Cleanup');
END;
ELSE IF SERVERPROPERTY('EngineEdition') = 8
BEGIN
UPDATE @Jobs
SET Selected = 1
WHERE [Name] IN('DatabaseIntegrityCheck - SYSTEM_DATABASES','DatabaseIntegrityCheck - USER_DATABASES','IndexOptimize - USER_DATABASES','CommandLog Cleanup','sp_delete_backuphistory','sp_purge_jobhistory');
END;
ELSE IF @HostPlatform = 'Windows'
BEGIN
UPDATE @Jobs
SET Selected = 1;
END;
ELSE IF @HostPlatform = 'Linux'
BEGIN
UPDATE @Jobs
SET Selected = 1
WHERE CommandTSQL IS NOT NULL;
END;
WHILE EXISTS (SELECT * FROM @Jobs WHERE Completed = 0 AND Selected = 1)
BEGIN
SELECT @CurrentJobID = [JobId],
@CurrentJobName = [Name],
@CurrentCommandTSQL = CommandTSQL,
@CurrentCommandCmdExec = CommandCmdExec,
@CurrentDatabaseName = DatabaseName,
@CurrentOutputFileNamePart01 = OutputFileNamePart01,
@CurrentOutputFileNamePart02 = OutputFileNamePart02
FROM @Jobs
WHERE Completed = 0
AND Selected = 1
ORDER BY [JobId] ASC;
IF @CurrentCommandTSQL IS NOT NULL AND @AmazonRDS = 1
BEGIN
SET @CurrentJobStepSubSystem = 'TSQL';
SET @CurrentJobStepCommand = @CurrentCommandTSQL;
SET @CurrentJobStepDatabaseName = @CurrentDatabaseName;
END;
ELSE IF @CurrentCommandTSQL IS NOT NULL AND SERVERPROPERTY('EngineEdition') = 8
BEGIN
SET @CurrentJobStepSubSystem = 'TSQL';
SET @CurrentJobStepCommand = @CurrentCommandTSQL;
SET @CurrentJobStepDatabaseName = @CurrentDatabaseName;
END;
ELSE IF @CurrentCommandTSQL IS NOT NULL AND @HostPlatform = 'Linux'
BEGIN
SET @CurrentJobStepSubSystem = 'TSQL';
SET @CurrentJobStepCommand = @CurrentCommandTSQL;
SET @CurrentJobStepDatabaseName = @CurrentDatabaseName;
END;
ELSE IF @CurrentCommandTSQL IS NOT NULL AND @HostPlatform = 'Windows' AND @Version >= 11
BEGIN
SET @CurrentJobStepSubSystem = 'TSQL';
SET @CurrentJobStepCommand = @CurrentCommandTSQL;
SET @CurrentJobStepDatabaseName = @CurrentDatabaseName;
END;
ELSE IF @CurrentCommandTSQL IS NOT NULL AND @HostPlatform = 'Windows' AND @Version < 11
BEGIN
SET @CurrentJobStepSubSystem = 'CMDEXEC';
SET @CurrentJobStepCommand = 'sqlcmd -E -S ' + @TokenServer + ' -d ' + @CurrentDatabaseName + ' -Q "' + REPLACE(@CurrentCommandTSQL,(CHAR(13) + CHAR(10)),' ') + '" -b';
SET @CurrentJobStepDatabaseName = NULL;
END;
ELSE IF @CurrentCommandCmdExec IS NOT NULL AND @HostPlatform = 'Windows'
BEGIN
SET @CurrentJobStepSubSystem = 'CMDEXEC';
SET @CurrentJobStepCommand = @CurrentCommandCmdExec;
SET @CurrentJobStepDatabaseName = NULL;
END;
IF @AmazonRDS = 0 AND SERVERPROPERTY('EngineEdition') <> 8
BEGIN
SET @CurrentOutputFileName = COALESCE(@OutputFileDirectory,@TokenLogDirectory,@LogDirectory) + @DirectorySeparator + ISNULL(CASE WHEN @TokenJobName IS NULL THEN @CurrentOutputFileNamePart01 END + '_','') + ISNULL(CASE WHEN @TokenJobName IS NULL THEN @CurrentOutputFileNamePart02 END + '_','') + ISNULL(@TokenJobName,@TokenJobID) + '_' + @TokenStepID + '_' + @TokenDate + '_' + @TokenTime + '.txt';
IF LEN(@CurrentOutputFileName) > 200 SET @CurrentOutputFileName = COALESCE(@OutputFileDirectory,@TokenLogDirectory,@LogDirectory) + @DirectorySeparator + ISNULL(CASE WHEN @TokenJobName IS NULL THEN @CurrentOutputFileNamePart01 END + '_','') + ISNULL(@TokenJobName,@TokenJobID) + '_' + @TokenStepID + '_' + @TokenDate + '_' + @TokenTime + '.txt';
IF LEN(@CurrentOutputFileName) > 200 SET @CurrentOutputFileName = COALESCE(@OutputFileDirectory,@TokenLogDirectory,@LogDirectory) + @DirectorySeparator + ISNULL(@TokenJobName,@TokenJobID) + '_' + @TokenStepID + '_' + @TokenDate + '_' + @TokenTime + '.txt';
IF LEN(@CurrentOutputFileName) > 200 SET @CurrentOutputFileName = NULL;
END;
IF @CurrentJobStepSubSystem IS NOT NULL AND @CurrentJobStepCommand IS NOT NULL AND NOT EXISTS (SELECT * FROM msdb.[dbo].[sysjobs] WHERE [name] = @CurrentJobName)
BEGIN
EXECUTE msdb.[dbo].sp_add_job @job_name = @CurrentJobName, @description = @JobDescription, @category_name = @JobCategory, @owner_login_name = @JobOwner;
EXECUTE msdb.[dbo].sp_add_jobstep @job_name = @CurrentJobName, @step_name = @CurrentJobName, @subsystem = @CurrentJobStepSubSystem, @command = @CurrentJobStepCommand, @output_file_name = @CurrentOutputFileName, @database_name = @CurrentJobStepDatabaseName;
EXECUTE msdb.[dbo].sp_add_jobserver @job_name = @CurrentJobName;
END;
UPDATE Jobs
SET Completed = 1
FROM @Jobs Jobs
WHERE [JobId] = @CurrentJobID;
SET @CurrentJobID = NULL;
SET @CurrentJobName = NULL;
SET @CurrentCommandTSQL = NULL;
SET @CurrentCommandCmdExec = NULL;
SET @CurrentDatabaseName = NULL;
SET @CurrentOutputFileNamePart01 = NULL;
SET @CurrentOutputFileNamePart02 = NULL;
SET @CurrentJobStepCommand = NULL;
SET @CurrentJobStepSubSystem = NULL;
SET @CurrentJobStepDatabaseName = NULL;
SET @CurrentOutputFileName = NULL;
END;
END;
GO
DECLARE @job_id UNIQUEIDENTIFIER;
DECLARE @step_id INT;
DECLARE @command NVARCHAR(MAX);
DECLARE @AmazonRDS BIT = CASE WHEN SERVERPROPERTY('EngineEdition') IN (5, 8) THEN 0 WHEN EXISTS (SELECT * FROM [sys].[databases] WHERE [name] = 'rdsadmin') AND SUSER_SNAME(0x01) = 'rdsa' THEN 1 ELSE 0 END;
IF @AmazonRDS = 0
BEGIN
DECLARE JobCursor CURSOR FAST_FORWARD FOR SELECT [job_id], [step_id], [command] FROM msdb.[dbo].[sysjobsteps] WHERE [command] LIKE '%DatabaseBackup%@CheckSum%' COLLATE SQL_Latin1_General_CP1_CS_AS;
OPEN JobCursor;
FETCH JobCursor INTO @job_id, @step_id, @command;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @command = REPLACE(@command, '@CheckSum', '@Checksum');
EXECUTE msdb.[dbo].sp_update_jobstep @job_id = @job_id, @step_id = @step_id, @command = @command;
FETCH NEXT FROM JobCursor INTO @job_id, @step_id, @command;
END;
CLOSE JobCursor;
DEALLOCATE JobCursor;
END;
GO
--#endregion SQL Server Maintenance Solution
USE msdb;
GO
--#region deleting maintenance plans
DECLARE @maint_plans TABLE([plan_id] UNIQUEIDENTIFIER NULL, [subplan_id] UNIQUEIDENTIFIER NULL, [task_detail_id] UNIQUEIDENTIFIER NULL);
DECLARE @q NVARCHAR(MAX)='';
INSERT INTO @maint_plans ([plan_id],
[subplan_id],
[task_detail_id])
SELECT p.[id], sp.[subplan_id], pl.[task_detail_id]
FROM [sysmaintplan_plans] p
LEFT JOIN [sysmaintplan_subplans] sp ON sp.[plan_id] =p.[id]
LEFT JOIN [sysmaintplan_log] pl ON pl.[plan_id] = p.[id]
WHERE p.[name]='MaintenanceTasks'
AND p.[owner] IN(
N'E-MEDIAT\uapeh',
N'CENTRALINFRA\ucibebildm_adm'
);
SELECT @q=@q+'delete from [sysmaintplan_log] where [task_detail_id] ='''+TRY_CAST([task_detail_id] AS NVARCHAR(MAX))+''';
'
FROM @maint_plans
WHERE [task_detail_id] IS NOT NULL;
SELECT @q=@q+'delete from [sysmaintplan_subplans] where [subplan_id] ='''+TRY_CAST([subplan_id] AS NVARCHAR(MAX))+''';
'
FROM @maint_plans
WHERE [subplan_id] IS NOT NULL;
SELECT @q=@q+'delete from [sysmaintplan_plans] where [id] ='''+TRY_CAST([plan_id] AS NVARCHAR(MAX))+''';
'
FROM @maint_plans
WHERE [plan_id] IS NOT NULL;
--PRINT @q;
EXECUTE sp_executesql @q,N'';
PRINT 'Cleaned up maintenance plans owned by Paul or Mehdi';
--#endregion deleting maintenance plans
--#region Drop old jobs
IF EXISTS (SELECT 1 FROM [msdb].[dbo].[sysjobs] j WHERE [j].[name]='MaintenanceTasks.CheckDB')
BEGIN
EXECUTE [msdb].[dbo].[sp_delete_job] @job_name = 'MaintenanceTasks.CheckDB', @delete_unused_schedule = 1;
PRINT 'dropped job MaintenanceTasks.CheckDB';
END;
IF EXISTS (SELECT 1 FROM [msdb].[dbo].[sysjobs] j WHERE [j].[name]='MaintenanceTasks.Subplan_1')
BEGIN
EXECUTE [msdb].[dbo].[sp_delete_job] @job_name = 'MaintenanceTasks.Subplan_1', @delete_unused_schedule = 1;
PRINT 'dropped job MaintenanceTasks.Subplan_1';
END;
IF EXISTS (SELECT 1 FROM [msdb].[dbo].[sysjobs] j WHERE [j].[name]='MaintenanceTasks.IndexStatsCleanup')
BEGIN
EXECUTE [msdb].[dbo].[sp_delete_job] @job_name = 'MaintenanceTasks.IndexStatsCleanup', @delete_unused_schedule = 1;
PRINT 'dropped job MaintenanceTasks.IndexStatsCleanup';
END;
IF EXISTS (SELECT 1 FROM [msdb].[dbo].[sysjobs] j WHERE [j].[name]='MaintenanceTasks.IndexRebuild')
BEGIN
EXECUTE [msdb].[dbo].[sp_delete_job] @job_name = 'MaintenanceTasks.IndexRebuild', @delete_unused_schedule = 1;
PRINT 'dropped job MaintenanceTasks.IndexRebuild';
END;
--#endregion Drop old jobs
DECLARE @ReturnCode INT;
SELECT @ReturnCode = 0;
DECLARE @jobId BINARY(16);
PRINT 'creating missing jobs';
--#region integrity system
IF NOT EXISTS(SELECT 1 FROM [sysjobs] j WHERE [name] ='DatabaseIntegrityCheck - SYSTEM_DATABASES')
BEGIN
PRINT 'deploying DatabaseIntegrityCheck - SYSTEM_DATABASES';
/****** Object: Job [DatabaseIntegrityCheck - SYSTEM_DATABASES] Script Date: 12.08.2025 14:10:01 ******/
BEGIN TRANSACTION;
/****** Object: JobCategory [Database Maintenance] Script Date: 12.08.2025 14:10:01 ******/
IF NOT EXISTS (SELECT [name] FROM msdb.[dbo].[syscategories] WHERE [name]=N'Database Maintenance' AND [category_class]=1)
BEGIN
EXECUTE @ReturnCode = msdb.[dbo].sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'Database Maintenance';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
END;
EXECUTE @ReturnCode = msdb.[dbo].sp_add_job @job_name=N'DatabaseIntegrityCheck - SYSTEM_DATABASES',
@enabled=1,
@notify_level_eventlog=2,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'Source: https://ola.hallengren.com',
@category_name=N'Database Maintenance',
@owner_login_name=N'sa', @job_id = @jobId OUTPUT;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
/****** Object: Step [DatabaseIntegrityCheck - SYSTEM_DATABASES] Script Date: 12.08.2025 14:10:01 ******/
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobstep @job_id=@jobId, @step_name=N'DatabaseIntegrityCheck - SYSTEM_DATABASES',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'EXECUTE [dbo].[DatabaseIntegrityCheck]
@Databases = ''SYSTEM_DATABASES'',
@LogToTable = ''Y''',
@database_name=N'master',
@output_file_name=N'$(ESCAPE_SQUOTE(SQLLOGDIR))\$(ESCAPE_SQUOTE(JOBNAME))_$(ESCAPE_SQUOTE(STEPID))_$(ESCAPE_SQUOTE(DATE))_$(ESCAPE_SQUOTE(TIME)).txt',
@flags=0;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_update_job @job_id = @jobId, @start_step_id = 1;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobschedule @job_id=@jobId, @name=N'maintenance_dbIntegrity_system',
@enabled=1,
@freq_type=8,
@freq_interval=64,
@freq_subday_type=1,
@freq_subday_interval=0,
@freq_relative_interval=0,
@freq_recurrence_factor=1,
@active_start_date=20250812,
@active_end_date=99991231,
@active_start_time=100000,
@active_end_time=235959,
@schedule_uid=N'9dd773d6-47bb-4b9b-8d50-b1060cbfe444';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobserver @job_id = @jobId, @server_name = N'(local)';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
COMMIT TRANSACTION;
--GOTO EndSave
END;
--#endregion integrity system
SET @jobId=NULL;
--#region integrity users
IF NOT EXISTS(SELECT 1 FROM [sysjobs] j WHERE [name] ='DatabaseIntegrityCheck - USER_DATABASES')
BEGIN
PRINT 'deploying DatabaseIntegrityCheck - USER_DATABASES';
/****** Object: Job [DatabaseIntegrityCheck - USER_DATABASES] Script Date: 12.08.2025 14:11:12 ******/
BEGIN TRANSACTION;
/****** Object: JobCategory [Database Maintenance] Script Date: 12.08.2025 14:11:12 ******/
IF NOT EXISTS (SELECT [name] FROM msdb.[dbo].[syscategories] WHERE [name]=N'Database Maintenance' AND [category_class]=1)
BEGIN
EXECUTE @ReturnCode = msdb.[dbo].sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'Database Maintenance';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
END;
EXECUTE @ReturnCode = msdb.[dbo].sp_add_job @job_name=N'DatabaseIntegrityCheck - USER_DATABASES',
@enabled=1,
@notify_level_eventlog=2,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'Source: https://ola.hallengren.com',
@category_name=N'Database Maintenance',
@owner_login_name=N'sa', @job_id = @jobId OUTPUT;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
/****** Object: Step [DatabaseIntegrityCheck - USER_DATABASES] Script Date: 12.08.2025 14:11:12 ******/
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobstep @job_id=@jobId, @step_name=N'DatabaseIntegrityCheck - USER_DATABASES',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'EXECUTE [dbo].[DatabaseIntegrityCheck]
@Databases = ''USER_DATABASES'',
@LogToTable = ''Y''',
@database_name=N'master',
@output_file_name=N'$(ESCAPE_SQUOTE(SQLLOGDIR))\$(ESCAPE_SQUOTE(JOBNAME))_$(ESCAPE_SQUOTE(STEPID))_$(ESCAPE_SQUOTE(DATE))_$(ESCAPE_SQUOTE(TIME)).txt',
@flags=0;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_update_job @job_id = @jobId, @start_step_id = 1;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobschedule @job_id=@jobId, @name=N'maintenance_dbIntegrity_userDbs',
@enabled=1,
@freq_type=8,
@freq_interval=64,
@freq_subday_type=1,
@freq_subday_interval=0,
@freq_relative_interval=0,
@freq_recurrence_factor=1,
@active_start_date=20250812,
@active_end_date=99991231,
@active_start_time=110000,
@active_end_time=235959,
@schedule_uid=N'51482738-7705-4cbb-afbf-2cf188016bc2';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobserver @job_id = @jobId, @server_name = N'(local)';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
COMMIT TRANSACTION;
--GOTO EndSave
END;
--#endregion integrity users
SET @jobId=NULL;
--#region index optimize
IF NOT EXISTS(SELECT 1 FROM [sysjobs] j WHERE [name] ='IndexOptimize - USER_DATABASES')
BEGIN
PRINT 'deploying IndexOptimize - USER_DATABASES';
/****** Object: Job [IndexOptimize - USER_DATABASES] Script Date: 12.08.2025 14:17:02 ******/
BEGIN TRANSACTION;
/****** Object: JobCategory [Database Maintenance] Script Date: 12.08.2025 14:17:02 ******/
IF NOT EXISTS (SELECT [name] FROM msdb.[dbo].[syscategories] WHERE [name]=N'Database Maintenance' AND [category_class]=1)
BEGIN
EXECUTE @ReturnCode = msdb.[dbo].sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'Database Maintenance';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
END;
EXECUTE @ReturnCode = msdb.[dbo].sp_add_job @job_name=N'IndexOptimize - USER_DATABASES',
@enabled=1,
@notify_level_eventlog=2,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'Source: https://ola.hallengren.com',
@category_name=N'Database Maintenance',
@owner_login_name=N'sa', @job_id = @jobId OUTPUT;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
/****** Object: Step [IndexOptimize - USER_DATABASES] Script Date: 12.08.2025 14:17:03 ******/
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobstep @job_id=@jobId, @step_name=N'IndexOptimize - USER_DATABASES',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'EXECUTE [dbo].[IndexOptimize]
@Databases = ''USER_DATABASES'',
@LogToTable = ''Y''',
@database_name=N'master',
@output_file_name=N'$(ESCAPE_SQUOTE(SQLLOGDIR))\$(ESCAPE_SQUOTE(JOBNAME))_$(ESCAPE_SQUOTE(STEPID))_$(ESCAPE_SQUOTE(DATE))_$(ESCAPE_SQUOTE(TIME)).txt',
@flags=0;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_update_job @job_id = @jobId, @start_step_id = 1;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobschedule @job_id=@jobId, @name=N'maintenance_indexOptimise_userDbs',
@enabled=1,
@freq_type=8,
@freq_interval=1,
@freq_subday_type=1,
@freq_subday_interval=0,
@freq_relative_interval=0,
@freq_recurrence_factor=1,
@active_start_date=20250812,
@active_end_date=99991231,
@active_start_time=10000,
@active_end_time=235959,
@schedule_uid=N'934e9df7-5ee4-48df-9c04-0d9a9fd53ccb';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobserver @job_id = @jobId, @server_name = N'(local)';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
COMMIT TRANSACTION;
--GOTO EndSave
END;
--#endregion index optimize
SET @jobId=NULL;
--#region statistics refresh
IF NOT EXISTS(SELECT 1 FROM [sysjobs] j WHERE [name] ='IndexOptimize - statistics update USER_DATABASES')
BEGIN
PRINT 'deploying IndexOptimize - statistics update USER_DATABASES';
/****** Object: Job [IndexOptimize - statistics update USER_DATABASES] Script Date: 12.08.2025 14:20:16 ******/
BEGIN TRANSACTION;
/****** Object: JobCategory [Database Maintenance] Script Date: 12.08.2025 14:20:16 ******/
IF NOT EXISTS (SELECT [name] FROM msdb.[dbo].[syscategories] WHERE [name]=N'Database Maintenance' AND [category_class]=1)
BEGIN
EXECUTE @ReturnCode = msdb.[dbo].sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'Database Maintenance';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
END;
EXECUTE @ReturnCode = msdb.[dbo].sp_add_job @job_name=N'IndexOptimize - statistics update USER_DATABASES',
@enabled=1,
@notify_level_eventlog=0,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'Source: https://ola.hallengren.com',
@category_name=N'Database Maintenance',
@owner_login_name=N'sa', @job_id = @jobId OUTPUT;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
/****** Object: Step [IndexOptimize - statistics update USER_DATABASES] Script Date: 12.08.2025 14:20:16 ******/
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobstep @job_id=@jobId, @step_name=N'IndexOptimize - statistics update USER_DATABASES',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'EXECUTE [dbo].[IndexOptimize]
@Databases = ''USER_DATABASES'' ,
@FragmentationLow = NULL ,
@FragmentationMedium = NULL ,
@FragmentationHigh = NULL ,
@UpdateStatistics = ''ALL'' ,
@OnlyModifiedStatistics = N''Y'' ,
@LogToTable = N''Y'';',
@database_name=N'master',
@flags=0;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_update_job @job_id = @jobId, @start_step_id = 1;
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobschedule @job_id=@jobId, @name=N'maintenance_inexOptimize_statistics',
@enabled=1,
@freq_type=8,
@freq_interval=64,
@freq_subday_type=1,
@freq_subday_interval=0,
@freq_relative_interval=0,
@freq_recurrence_factor=1,
@active_start_date=20250812,
@active_end_date=99991231,
@active_start_time=10000,
@active_end_time=235959,
@schedule_uid=N'cbb27a89-d485-4e1c-b4fe-402db58bc131';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
EXECUTE @ReturnCode = msdb.[dbo].sp_add_jobserver @job_id = @jobId, @server_name = N'(local)';
IF (@@ERROR <> 0 OR @ReturnCode <> 0) RAISERROR('Error executing command',15,15);
COMMIT TRANSACTION;
--GOTO EndSave
END;
--#endregion statistics refresh
IF (@@TRANCOUNT > 0)
BEGIN
--ROLLBACK TRANSACTION;
COMMIT TRANSACTION
END