{"id":620,"date":"2024-11-05T20:54:08","date_gmt":"2024-11-05T20:54:08","guid":{"rendered":"https:\/\/datacrazyworld.com\/?p=620"},"modified":"2024-11-05T20:54:25","modified_gmt":"2024-11-05T20:54:25","slug":"sql-server-agent-y-el-cambio-de-hora","status":"publish","type":"post","link":"https:\/\/datacrazyworld.com\/index.php\/2024\/11\/05\/sql-server-agent-y-el-cambio-de-hora\/","title":{"rendered":"SQL Server Agent y el cambio de hora"},"content":{"rendered":"\n<p>Hace algunos d\u00edas nos hemos enfrentado al cambio de hora. \u00bfC\u00f3mo lo hab\u00e9is llevado? \u00bfHab\u00e9is tenido alg\u00fan problema? Si ten\u00e9is todo con UTCs imagino que no, pero si ten\u00e9is fechas locales seguro que os hab\u00e9is encontrado alguna que otra sorpresa.<\/p>\n\n\n\n<p>Hasta que empec\u00e9 a trabajar, me encantaba este cambio de hora. \u00a1Una hora m\u00e1s en el fin de semana! Para descansar m\u00e1s, ir de fiesta,\u2026 lo que quieras. Pero como t\u00e9cnica \u2026 \u00a0\u00e9ste es \u201cel malo\u201d, es el que m\u00e1s 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.<\/p>\n\n\n\n<p>Uno de los primeros consejos que recibir\u00e9is por mi parte, basada en la mala experiencia (esa que se graba en tu mente a fuego) \u00a0es que a la hora de modelar \u201csiempre hacer todo con horas UTCs\u201d . As\u00ed te evitar\u00e1s los problemas de los cambios de hora. De verdad, aunque no creas que lo vayas a necesitar porque se trate de un negocio local, <strong>usa UTCs en tus tablas<\/strong>. Te evitar\u00e1s muchos problemas.<\/p>\n\n\n\n<p>Veamos un ejemplo.<\/p>\n\n\n\n<p><em>Registro creado a las 2:30 am local \u2013 0:30 UTC<\/em><\/p>\n\n\n\n<p><em>Registro creado a las 2:10 am local\u00a0 &#8211;\u00a0 1:10 UTC<\/em><\/p>\n\n\n\n<p>Si miras las horas locales \u00bfCu\u00e1l se cre\u00f3 antes? No puedes decirlo. Si miras las UTCs, en cambio, s\u00ed.<\/p>\n\n\n\n<p>Pero este no es un problema s\u00f3lo de la creaci\u00f3n de los registros. El SQL Agent \u00a0funciona con la hora del servidor, por lo tanto hora local. Entonces \u00bfC\u00f3mo hago para que se lancen los jobs seg\u00fan 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. \u00bfC\u00f3mo lo har\u00edamos?<\/p>\n\n\n\n<p>Para lograrlo necesitar\u00e9 que cada job que quiera esto tenga dos programaciones, una para cuando est\u00e9 el horario de invierno (que llamaremos Winter) y otra para la del verano (que llamaremos Summer).<\/p>\n\n\n\n<p>Luego adem\u00e1s programar\u00e9 a las 0h un job, al que he llamado \u201c<em>WinterSummerSchedulerSwitch<\/em>\u201d, cuya funci\u00f3n es detectar si estamos en horario de invierno o de verano y activar el scheduler correspondiente.<\/p>\n\n\n\n<p>Aqu\u00ed os dejo el c\u00f3digo que ser\u00eda para un servidor ubicado en Espa\u00f1a.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>USE &#91;msdb]\nGO\n\nDECLARE @numh smallint\n\nSelect @numh = datediff(HOUR,getutcdate(),getdate())\n\ndeclare @summer table (schedule_id int)\ndeclare @winter table (schedule_id int)\ndeclare @id int\n\nIF @numh = 1\nBEGIN\t\n\t-- Para HORARIO DE INVIERNO\n\tinsert into @Summer (schedule_id)\n\tSELECT schedule_id\n\tFROM sysschedules_localserver_view\n\twhere &#91;name]='Summer' \n\n\tWhile EXISTS (select top 1 1 from @Summer)\n\tBEGIN\n\t\tSELECT @id = schedule_id from @Summer\n\n\t\tEXEC dbo.sp_update_schedule\n\t\t@schedule_id = @id,\n\t\t@enabled = 0\n\n\t\tDELETE FROM @Summer where schedule_id = @id\n\tEND\n\t\n\tinsert into @Winter (schedule_id)\n\tSELECT schedule_id\n\tFROM sysschedules_localserver_view\n\twhere &#91;name]='Winter' \n\n\t\tWhile EXISTS (select top 1 1 from @Winter)\n\tBEGIN\n\t\tSELECT @id = schedule_id from @Winter\n\n\t\tEXEC dbo.sp_update_schedule\n\t\t@schedule_id = @id,\n\t\t@enabled = 1\n\n\t\tDELETE FROM @Winter where schedule_id = @id\n\tEND\nEND\nELSE\nBEGIN\n\t-- Para HORARIO DE VERANO\n\tinsert into @Summer (schedule_id)\n\tSELECT schedule_id\n\tFROM sysschedules_localserver_view\n\twhere &#91;name]='Summer' \n\n\tWhile EXISTS (select top 1 1 from @Summer)\n\tBEGIN\n\t\tSELECT @id = schedule_id from @Summer\n\n\t\tEXEC dbo.sp_update_schedule\n\t\t@schedule_id = @id,\n\t\t@enabled = 1\n\n\t\tDELETE FROM @Summer where schedule_id = @id\n\tEND\n\n\tinsert into @Winter (schedule_id)\n\tSELECT schedule_id\n\tFROM sysschedules_localserver_view\n\twhere &#91;name]='Winter' \n\n\tWhile EXISTS (select top 1 1 from @Winter)\n\tBEGIN\n\t\tSELECT @id = schedule_id from @Winter\n\n\t\tEXEC dbo.sp_update_schedule\n\t\t@schedule_id = @id,\n\t\t@enabled = 0\n\n\t\tDELETE FROM @Winter where schedule_id = @id\n\tEND\nEND\n<\/code><\/pre>\n\n\n\n<p>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. \u00bf Alguno se ha encontrado tambi\u00e9n con esta necesidad? \u00bfC\u00f3mo lo ha solucionado? Me encantar\u00eda que lo compartierais en los comentarios.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hace algunos d\u00edas nos hemos enfrentado al cambio de hora. En esta ocasi\u00f3n os comparto una forma de que el SQL Server Agent adapte el horario de sus Jobs.<\/p>\n","protected":false},"author":2,"featured_media":614,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[8,9],"tags":[21,12],"class_list":["post-620","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-sqlserver","category-tsql","tag-sqlserver","tag-tsql"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/posts\/620","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/comments?post=620"}],"version-history":[{"count":2,"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/posts\/620\/revisions"}],"predecessor-version":[{"id":622,"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/posts\/620\/revisions\/622"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/media\/614"}],"wp:attachment":[{"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/media?parent=620"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/categories?post=620"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/datacrazyworld.com\/index.php\/wp-json\/wp\/v2\/tags?post=620"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}