9880 lines
491 KiB
Transact-SQL
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 |