SQL Server Agent y el cambio de hora

Hace algunos días nos hemos enfrentado al cambio de hora. ¿Cómo lo habéis llevado? ¿Habéis tenido algún problema? Si tenéis todo con UTCs imagino que no, pero si tenéis fechas locales seguro que os habéis encontrado alguna que otra sorpresa.

Hasta que empecé a trabajar, me encantaba este cambio de hora. ¡Una hora más en el fin de semana! Para descansar más, ir de fiesta,… lo que quieras. Pero como técnica …  éste es “el malo”, es el que más problemas me da porque he heredado un sistema basado en horas locales. Y es que tengo dos momentos distintos con la misma hora y no puedo distinguirlos: las 2 am.

Uno de los primeros consejos que recibiréis por mi parte, basada en la mala experiencia (esa que se graba en tu mente a fuego)  es que a la hora de modelar “siempre hacer todo con horas UTCs” . Así te evitarás los problemas de los cambios de hora. De verdad, aunque no creas que lo vayas a necesitar porque se trate de un negocio local, usa UTCs en tus tablas. Te evitarás muchos problemas.

Veamos un ejemplo.

Registro creado a las 2:30 am local – 0:30 UTC

Registro creado a las 2:10 am local  –  1:10 UTC

Si miras las horas locales ¿Cuál se creó antes? No puedes decirlo. Si miras las UTCs, en cambio, sí.

Pero este no es un problema sólo de la creación de los registros. El SQL Agent  funciona con la hora del servidor, por lo tanto hora local. Entonces ¿Cómo hago para que se lancen los jobs según la hora UTC? Supongamos, por ejemplo, que necesito lanzar unos procesos a partir de las 0h UTCs y como tardan mucho quiero ajustar y que se lancen cuanto antes. ¿Cómo lo haríamos?

Para lograrlo necesitaré que cada job que quiera esto tenga dos programaciones, una para cuando esté el horario de invierno (que llamaremos Winter) y otra para la del verano (que llamaremos Summer).

Luego además programaré a las 0h un job, al que he llamado “WinterSummerSchedulerSwitch”, cuya función es detectar si estamos en horario de invierno o de verano y activar el scheduler correspondiente.

Aquí os dejo el código que sería para un servidor ubicado en España.

USE [msdb]
GO

DECLARE @numh smallint

Select @numh = datediff(HOUR,getutcdate(),getdate())

declare @summer table (schedule_id int)
declare @winter table (schedule_id int)
declare @id int

IF @numh = 1
BEGIN	
	-- Para HORARIO DE INVIERNO
	insert into @Summer (schedule_id)
	SELECT schedule_id
	FROM sysschedules_localserver_view
	where [name]='Summer' 

	While EXISTS (select top 1 1 from @Summer)
	BEGIN
		SELECT @id = schedule_id from @Summer

		EXEC dbo.sp_update_schedule
		@schedule_id = @id,
		@enabled = 0

		DELETE FROM @Summer where schedule_id = @id
	END
	
	insert into @Winter (schedule_id)
	SELECT schedule_id
	FROM sysschedules_localserver_view
	where [name]='Winter' 

		While EXISTS (select top 1 1 from @Winter)
	BEGIN
		SELECT @id = schedule_id from @Winter

		EXEC dbo.sp_update_schedule
		@schedule_id = @id,
		@enabled = 1

		DELETE FROM @Winter where schedule_id = @id
	END
END
ELSE
BEGIN
	-- Para HORARIO DE VERANO
	insert into @Summer (schedule_id)
	SELECT schedule_id
	FROM sysschedules_localserver_view
	where [name]='Summer' 

	While EXISTS (select top 1 1 from @Summer)
	BEGIN
		SELECT @id = schedule_id from @Summer

		EXEC dbo.sp_update_schedule
		@schedule_id = @id,
		@enabled = 1

		DELETE FROM @Summer where schedule_id = @id
	END

	insert into @Winter (schedule_id)
	SELECT schedule_id
	FROM sysschedules_localserver_view
	where [name]='Winter' 

	While EXISTS (select top 1 1 from @Winter)
	BEGIN
		SELECT @id = schedule_id from @Winter

		EXEC dbo.sp_update_schedule
		@schedule_id = @id,
		@enabled = 0

		DELETE FROM @Winter where schedule_id = @id
	END
END

Yo lo he probado en este cambio horario, y me ha evitado cambiar las programaciones de los jobs, asi que he decidido compartirlo con vosotros. ¿ Alguno se ha encontrado también con esta necesidad? ¿Cómo lo ha solucionado? Me encantaría que lo compartierais en los comentarios.

También te podría gustar...

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.