Skip to content

Commit

Permalink
Небольшие исправления для служебной базы данных
Browse files Browse the repository at this point in the history
  • Loading branch information
YPermitin committed Nov 12, 2023
1 parent 31cee1b commit 84ac447
Show file tree
Hide file tree
Showing 3 changed files with 451 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ INSERT [dbo].[changelog] ([id], [type], [version], [description], [name], [check
GO
INSERT [dbo].[changelog] ([id], [type], [version], [description], [name], [checksum], [installed_by], [installed_on], [success]) VALUES (14, 0, N'1.0.0.12', N'Jobs FixCreateOrUPdateJobsBySettingsProc (72 ms)', N'V1_0_0_12__Jobs_FixCreateOrUPdateJobsBySettingsProc.sql', N'830D32CAB88A1ACC673F515AA8D5B96D', N'sa', CAST(N'2023-11-09T18:58:14.717' AS DateTime), 1)
GO
INSERT [dbo].[changelog] ([id], [type], [version], [description], [name], [checksum], [installed_by], [installed_on], [success]) VALUES (1014, 0, N'1.0.0.13', N'Jobs FixCreateOrUPdateJobsBySettingsProcV2 (33 ms)', N'V1_0_0_13__Jobs_FixCreateOrUPdateJobsBySettingsProcV2.sql', N'20830460B9482F8F0E072F0258C2C246', N'sa', CAST(N'2023-11-10T10:20:16.897' AS DateTime), 1)
GO
SET IDENTITY_INSERT [dbo].[changelog] OFF
GO

Expand Down Expand Up @@ -1287,6 +1289,10 @@ BEGIN
SET @jobDescription = REPLACE(@Description, '{DatabaseName}', @currentDatabaseName);
DECLARE @currentJobAction nvarchar(max) = REPLACE(@JobAction, '{DatabaseName}', @currentDatabaseName);

SET @jobAlreadyExists = 0;
SET @currentJobId = NULL;
SET @currentjobVersionDate = NULL;

SELECT
@jobAlreadyExists = 1,
@currentJobId = sj.job_id,
Expand Down Expand Up @@ -1330,7 +1336,11 @@ BEGIN
END
CLOSE job_templates_databases_cursor;
DEALLOCATE job_templates_databases_cursor;
END ELSE BEGIN
END ELSE BEGIN
SET @jobAlreadyExists = 0;
SET @currentJobId = NULL;
SET @currentjobVersionDate = NULL;

SELECT
@jobAlreadyExists = 1,
@currentJobId = sj.job_id,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
ALTER PROCEDURE [dbo].[sp_CreateOrUpdateJobsBySettings]
@force bit = 0
AS
BEGIN
SET NOCOUNT ON;

-- Поля шаблона
DECLARE
@Id int,
@Enable bit,
@ApplyTemplateQuery nvarchar(max),
@Name nvarchar(250),
@Description nvarchar(512),
@JobAction nvarchar(max),
@ScheduleEnable bit,
@ScheduleFreqType int,
@ScheduleFreqInterval int,
@ScheduleFreqSubdayType int,
@ScheduleFreqSubdayInterval int,
@ScheduleFreqRelativeInterval int,
@ScheduleFreqRecurrenceFactor int,
@ScheduleActiveStartDay int,
@ScheduleActiveEndDay int,
@ScheduleActiveStartTime int,
@ScheduleActiveEndTime int,
@VersionDate datetime,
@TimeoutSec int;

DECLARE
@jobName nvarchar(250),
@jobDescription nvarchar(513),
@jobScript nvarchar(max),
@currentjobVersionDate datetime,
@currentJobId uniqueidentifier,
@JobAlreadyExists bit = 0,
@msg nvarchar(max);

-- Служебные переменные
DECLARE
@sql nvarchar(max),
@currentDatabaseName nvarchar(250);

DECLARE job_templates_cursor CURSOR
FOR SELECT
[Id]
,[Enable]
,[ApplyTemplateQuery]
,[Name]
,[Description]
,[JobAction]
,[ScheduleEnable]
,[ScheduleFreqType]
,[ScheduleFreqInterval]
,[ScheduleFreqSubdayType]
,[ScheduleFreqSubdayInterval]
,[ScheduleFreqRelativeInterval]
,[ScheduleFreqRecurrenceFactor]
,[ScheduleActiveStartDay]
,[ScheduleActiveEndDay]
,[ScheduleActiveStartTime]
,[ScheduleActiveEndTime]
,[VersionDate]
,[TimeoutSec]
FROM [dbo].[JobTemplates]
WHERE [UseSetting] = 1;
OPEN job_templates_cursor;

FETCH NEXT FROM job_templates_cursor
INTO @Id, @Enable, @ApplyTemplateQuery, @Name, @Description, @JobAction, @ScheduleEnable,
@ScheduleFreqType, @ScheduleFreqInterval, @ScheduleFreqSubdayType, @ScheduleFreqSubdayInterval,
@ScheduleFreqRelativeInterval, @ScheduleFreqRecurrenceFactor, @ScheduleActiveStartDay,
@ScheduleActiveEndDay, @ScheduleActiveStartTime, @ScheduleActiveEndTime, @VersionDate, @TimeoutSec;

WHILE @@FETCH_STATUS = 0
BEGIN
SET @Description = @Description + ' (Version date:' + CAST(@VersionDate AS nvarchar(max)) + ')';

IF(@ApplyTemplateQuery IS NOT NULL)
BEGIN
-- Задания создаются по базам данных
IF(NOT EXISTS(SELECT
[name]
FROM sys.dm_exec_describe_first_result_set (@ApplyTemplateQuery, NULL, 0)
WHERE [name] = 'DatabaseName'))
BEGIN
PRINT @Name;
THROW 51000, 'Запрос шаблона не содержит поля DatabaseName.', 1;
END

IF (OBJECT_ID('tempdb..##databasesForJobs') IS NOT NULL)
DROP Table ##databasesForJobs;
IF(1 = 0)
BEGIN
-- !!! Костыль для поддержания корректного поведения редактора SQL кода,
-- иначе ругается на несуществующую глобавльную временную таблицу
CREATE TABLE ##databasesForJobs (DatabaseName nvarchar(255));
END
SET @sql = CAST('SELECT [DatabaseName] INTO ##databasesForJobs FROM (' AS nvarchar(max))
+ CAST(@ApplyTemplateQuery AS nvarchar(max))
+ CAST(') AS T' AS nvarchar(max))
EXEC sp_executesql @sql

DECLARE job_templates_databases_cursor CURSOR
FOR SELECT [DatabaseName] FROM ##databasesForJobs;
OPEN job_templates_databases_cursor;
FETCH NEXT FROM job_templates_databases_cursor INTO @currentDatabaseName;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @jobName = REPLACE(@Name, '{DatabaseName}', @currentDatabaseName);
SET @jobDescription = REPLACE(@Description, '{DatabaseName}', @currentDatabaseName);
DECLARE @currentJobAction nvarchar(max) = REPLACE(@JobAction, '{DatabaseName}', @currentDatabaseName);

SELECT
@jobAlreadyExists = 1,
@currentJobId = sj.job_id,
@currentjobVersionDate = CASE WHEN sj.date_modified > sj.date_created THEN sj.date_modified ELSE sj.date_created END
FROM [msdb].[dbo].[sysjobs] sj
WHERE sj.[name] = @jobName

-- Если задание уже существует, но в настройках содержится более новая версия,
-- то удаляем старое задание и создаем заново
IF(@jobAlreadyExists = 1 AND (@force = 1 OR @VersionDate > @currentjobVersionDate))
BEGIN
EXEC msdb.dbo.sp_delete_job
@job_id = @currentJobId,
@delete_unused_schedule = 1;
SET @msg = 'Удалено задание: ' + @jobName;
PRINT @msg;
SET @jobAlreadyExists = 0;
END

IF(@jobAlreadyExists = 0)
BEGIN
EXECUTE [dbo].[sp_CreateSimpleJob]
@jobName = @jobName
,@jobDescription = @jobDescription
,@jobEnabled = @Enable
,@databaseName = @currentDatabaseName
,@jobAction = @currentJobAction
,@scheduleEnabled = @ScheduleEnable
,@scheduleFreqType = @ScheduleFreqType
,@scheduleFreqInterval = @ScheduleFreqInterval
,@scheduleFreqSubdayType = @ScheduleFreqSubdayType
,@scheduleFreqSubdayInterval = @ScheduleFreqSubdayInterval
,@scheduleFreqRelativeInterval = @ScheduleFreqRelativeInterval
,@scheduleFreqRecurrenceFactor = @ScheduleFreqRecurrenceFactor
,@scheduleActiveStartDate = @ScheduleActiveStartDay
,@scheduleActiveEndDate = @ScheduleActiveEndDay
,@scheduleActiveStartTime = @ScheduleActiveStartTime
,@scheduleActiveEndTime = @ScheduleActiveEndTime
,@jobTimeoutSec = @TimeoutSec

SET @msg = 'Создано задание: ' + @jobName;
PRINT @msg;
END

FETCH NEXT FROM job_templates_databases_cursor INTO @currentDatabaseName;
END
CLOSE job_templates_databases_cursor;
DEALLOCATE job_templates_databases_cursor;
END ELSE BEGIN
SELECT
@jobAlreadyExists = 1,
@currentJobId = sj.job_id,
@currentjobVersionDate = CASE WHEN sj.date_modified > sj.date_created THEN sj.date_modified ELSE sj.date_created END
FROM [msdb].[dbo].[sysjobs] sj
WHERE sj.[name] = @Name

-- Если задание уже существует, но в настройках содержится более новая версия,
-- то удаляем старое задание и создаем заново
IF(@jobAlreadyExists = 1 AND (@force = 1 OR @VersionDate > @currentjobVersionDate))
BEGIN
EXEC msdb.dbo.sp_delete_job
@job_id = @currentJobId,
@delete_unused_schedule = 1;
SET @msg = 'Удалено задание: ' + @Name;
PRINT @msg;
SET @jobAlreadyExists = 0;
END

IF(@jobAlreadyExists = 0)
BEGIN
-- Задание создается единое на весь сервер
EXECUTE [dbo].[sp_CreateSimpleJob]
@jobName = @Name
,@jobDescription = @Description
,@jobEnabled = @Enable
,@databaseName = 'SQLServerMaintenance'
,@jobAction = @JobAction
,@scheduleEnabled = @ScheduleEnable
,@scheduleFreqType = @ScheduleFreqType
,@scheduleFreqInterval = @ScheduleFreqInterval
,@scheduleFreqSubdayType = @ScheduleFreqSubdayType
,@scheduleFreqSubdayInterval = @ScheduleFreqSubdayInterval
,@scheduleFreqRelativeInterval = @ScheduleFreqRelativeInterval
,@scheduleFreqRecurrenceFactor = @ScheduleFreqRecurrenceFactor
,@scheduleActiveStartDate = @ScheduleActiveStartDay
,@scheduleActiveEndDate = @ScheduleActiveEndDay
,@scheduleActiveStartTime = @ScheduleActiveStartTime
,@scheduleActiveEndTime = @ScheduleActiveEndTime
,@jobTimeoutSec = @TimeoutSec

SET @msg = 'Создано задание: ' + @Name;
PRINT @msg;
END
END

FETCH NEXT FROM job_templates_cursor
INTO @Id, @Enable, @ApplyTemplateQuery, @Name, @Description, @JobAction, @ScheduleEnable,
@ScheduleFreqType, @ScheduleFreqInterval, @ScheduleFreqSubdayType, @ScheduleFreqSubdayInterval,
@ScheduleFreqRelativeInterval, @ScheduleFreqRecurrenceFactor, @ScheduleActiveStartDay,
@ScheduleActiveEndDay, @ScheduleActiveStartTime, @ScheduleActiveEndTime, @VersionDate, @TimeoutSec;
END
CLOSE job_templates_cursor;
DEALLOCATE job_templates_cursor;
END
Loading

0 comments on commit 84ac447

Please sign in to comment.