<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Le Blog SQL Server d&#039;ElSüket &#187; Agent SQL Server</title>
	<atom:link href="https://blog.developpez.com/elsuket/pcategory/agent-sql-server/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/elsuket</link>
	<description>Nicolas Souquet - Expert SQL Server</description>
	<lastBuildDate>Mon, 05 Apr 2021 07:32:41 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Pourquoi je ne peux pas être supporter de l&#8217;utilisation des plans de maintenance en production</title>
		<link>https://blog.developpez.com/elsuket/p11161/agent-sql-server/supporter_plan_de_maintenance</link>
		<comments>https://blog.developpez.com/elsuket/p11161/agent-sql-server/supporter_plan_de_maintenance#comments</comments>
		<pubDate>Wed, 18 Jul 2012 17:27:08 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une énumération des raisons qui font que jusque ici, je n&#8217;ai jamais donné mon aval à la création de plans de maintenance sur des instance SQL Server de production : => Les plans de maintenance ne sont pas portables &#8230; <a href="https://blog.developpez.com/elsuket/p11161/agent-sql-server/supporter_plan_de_maintenance">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une énumération des raisons qui font que jusque ici, je n&rsquo;ai jamais donné mon aval à la création de plans de maintenance sur des instance SQL Server de production :</p>
<p><span id="more-19"></span></p>
<p>=> Les plans de maintenance ne sont pas portables : il est impossible de déployer simplement sur plusieurs instances de SQL Server un même plan de maintenance en une seule fois. D&rsquo;autre part, une fois la copie réalisée, il est nécessaire de mettre à jour la chaîne de connexion qui est dans celui-ci, et qui correspond a l&rsquo;instance sur laquelle celui-ci a été créé. Enfin, on peut se heurter à des problèmes d&rsquo;intégrité des données référentielle dans la base de données système msdb, ce que le DBA (trop) prudent que je suis se refuse catégoriquement à réaliser.</p>
<p>=> Lorsqu&rsquo;on supprime un plan de maintenance, le package SSIS est supprimé, mais pas le travail de l&rsquo;Agent SQL Server qui lui est attaché</p>
<p>=> A chaque fois que quelqu&rsquo;un crée ou modifie un plan de maintenance, il est nécessaire de changer de nouveau le propriétaire de celui-ci et/ou du travail de l&rsquo;Agent SQL Server qui est attaché à ce plan, car celui-ci est écrasé automatiquement par le nom de connexion de l&rsquo;utilisateur qui réalise l&rsquo;édition du plan de maintenance</p>
<p>=> Dans les éditions <em>Enterprise</em> de SQL Server 2005, il est impossible d&rsquo;obtenir l&rsquo;option CHECKSUM lorsqu&rsquo;on souhaite réaliser une sauvegarde de base de données. Sous SQL Server 2008, ce n&rsquo;est pas possible non plus, mais le CHECKSUM est calculé lorsqu&rsquo;on active la compression des sauvegardes de base de données.</p>
<p>=> En ce qui concerne la maintenance des statistiques, il est impossible d&rsquo;indiquer le niveau d&rsquo;échantillonnage par défaut. D&rsquo;autre part, l’échantillonnage est soit annulé (FULL), soit il est identique pour toutes les tables, ce qui n&rsquo;est pas optimal</p>
<p>=> Quand on connaît les dégâts que peuvent causer un rétrécissement de base de données, on comprend qu&rsquo;une telle tâche ne devrait tout simplement pas exister</p>
<p>=> Les tâches de défragmentation et de reconstruction des index ne permettent pas de spécifier des valeurs seuil pour lesquelles il est préférable de défragmenter plutôt que de reconstruire un index, et inversement.</p>
<p>=> La vérification de l&rsquo;intégrité des bases de données ne permet malheureusement pas de spécifier le niveau de vérification avec lequel on souhaite l&rsquo;effectuer.</p>
<p>En revanche les tâches de nettoyage des fichiers, d&rsquo;envoi de notification à un opérateur, d&rsquo;exécution d&rsquo;un travail de l&rsquo;Agent SQL Server, d&rsquo;exécution de script T-SQL ou de l&rsquo;historique sont plutôt bien conçues, même si pour la dernière j&rsquo;aurai préféré pouvoir spécifier une durée de rétention par type d&rsquo;historique.</p>
<p>Pour toutes ces raisons, je proscris pour le moment l&rsquo;utilisation des plans de maintenance sur les serveurs de production, pour lesquels j&rsquo;ai développé un ensemble de procédures stockées qui me permet de réaliser juste le minimum.</p>
<p>Je pense que les plans de maintenance sont un très bon moyen d&rsquo;assurer un niveau minimal de qualité d&rsquo;une base de données avec un minimum d&rsquo;effort, et sont appropriés pour des serveurs de développement ou des test peu importants, mais pas (encore ?) pour des instances de SQL Server qui supportent la production.</p>
<p>Attention donc à ne pas utiliser les plans de maintenance à tors et à travers <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Connaître la longueur maximale des lignes des tables, et calculs relatifs</title>
		<link>https://blog.developpez.com/elsuket/p8161/moteur-de-base-de-donnees-sql-server/connaitre_la_longueur_maximale_des_ligne</link>
		<comments>https://blog.developpez.com/elsuket/p8161/moteur-de-base-de-donnees-sql-server/connaitre_la_longueur_maximale_des_ligne#comments</comments>
		<pubDate>Tue, 06 Oct 2009 17:10:14 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Il est intéressant de connaître la longueur maximale qui peut être stockée par une table pour tenter de prévoir la taille d&#8217;une base de données lorsque le système sera arrivé à maturité. Voici une petite requête pour nous y aider &#8230; <a href="https://blog.developpez.com/elsuket/p8161/moteur-de-base-de-donnees-sql-server/connaitre_la_longueur_maximale_des_ligne">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Il est intéressant de connaître la longueur maximale qui peut être stockée par une table pour tenter de prévoir la taille d&rsquo;une base de données lorsque le système sera arrivé à maturité.<br />
Voici une petite requête pour nous y aider sous SQL Server 2005 et 2008&#8230;<br />
<span id="more-90"></span></p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">------------------------------- <br />
-- Nicolas SOUQUET - 06/10/2009 <br />
------------------------------- <br />
SELECT nomTable, <br />
&nbsp; &nbsp; longueurLigne, <br />
&nbsp; &nbsp; 8060 / longueurLigne AS nbLignesParPage, <br />
&nbsp; &nbsp; longueurLigne * (8060 / longueurLigne) AS nbMaxOctetsParPage, <br />
&nbsp; &nbsp; 8060 - (longueurLigne * (8060 / longueurLigne)) nbOctetsPerdusParPage, <br />
&nbsp; &nbsp; (longueurLigne + longueurLigne % 8060) / 8060 AS nbPagesStockeLigne <br />
FROM <br />
( <br />
&nbsp; SELECT T.name AS nomTable, <br />
&nbsp; &nbsp; &nbsp; SUM(C.max_length) AS longueurLigne <br />
&nbsp; FROM sys.tables AS T <br />
&nbsp; JOIN sys.columns AS C <br />
&nbsp; &nbsp; ON T.object_id = C.object_id <br />
&nbsp; JOIN sys.types AS TY <br />
&nbsp; &nbsp; ON C.user_type_id = TY.user_type_id <br />
&nbsp; GROUP BY T.name <br />
) AS TMP (nomTable, longueurLigne)</div></td></tr></tbody></table></div>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Une requête pour lister tous les travaux de l&#8217;Agent SQL Server avec leur caractéristiques d&#8217;exécution</title>
		<link>https://blog.developpez.com/elsuket/p11193/agent-sql-server/une_requete_pour_lister_tous_les_travaux</link>
		<comments>https://blog.developpez.com/elsuket/p11193/agent-sql-server/une_requete_pour_lister_tous_les_travaux#comments</comments>
		<pubDate>Mon, 30 Jul 2012 14:20:45 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une requête qui permet de lister tous les jobs existant sur une instance SQL Server : &#8211; toutes leurs étapes &#8211; la définition de ces étapes (appel à une procédure stockée, exécution d&#8217;un package SSIS, &#8230;) &#8211; la date &#8230; <a href="https://blog.developpez.com/elsuket/p11193/agent-sql-server/une_requete_pour_lister_tous_les_travaux">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une requête qui permet de lister tous les jobs existant sur une instance SQL Server : </p>
<p>&#8211; toutes leurs étapes<br />
&#8211; la définition de ces étapes (appel à une procédure stockée, exécution d&rsquo;un package SSIS, &#8230;)<br />
&#8211; la date et l&rsquo;heure de la prochaine fois que le job sera exécuté<br />
&#8211; la fréquence à laquelle l&rsquo;exécution du job est planifiée, si le job a une planification<br />
&#8211; la date à laquelle le job job a été créé, et à laquelle il a été modifié pour la dernière fois</p>
<p><span id="more-20"></span></p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">------------------------------- <br />
-- Nicolas Souquet - 30/07/2012 <br />
------------------------------- <br />
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED <br />
GO <br />
&nbsp;<br />
SELECT &nbsp; &nbsp;J.name AS job_name <br />
&nbsp; &nbsp; , JS.step_name <br />
&nbsp; &nbsp; , JS.command <br />
&nbsp; &nbsp; , JS.database_name AS database_context <br />
&nbsp; &nbsp; , NR.next_run_date_time <br />
&nbsp; &nbsp; , CASE J.enabled WHEN 1 THEN 'YES' ELSE 'NO' END AS job_is_enabled <br />
&nbsp; &nbsp; , CASE S.enabled WHEN 1 THEN 'YES' ELSE 'NO' END AS job_is_scheduled <br />
&nbsp; &nbsp; , SP.name AS owner_login_name <br />
&nbsp; &nbsp; , CASE S.freq_type <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN 'Once' <br />
&nbsp; &nbsp; &nbsp; WHEN 4 THEN 'Daily' <br />
&nbsp; &nbsp; &nbsp; WHEN 8 THEN 'Weekly' <br />
&nbsp; &nbsp; &nbsp; WHEN 16 THEN 'Monthly' <br />
&nbsp; &nbsp; &nbsp; WHEN 32 THEN 'Monthly relative' <br />
&nbsp; &nbsp; &nbsp; WHEN 64 THEN 'When SQL Server Agent starts' <br />
&nbsp; &nbsp; &nbsp; WHEN 128 THEN 'Start whenever the CPU(s) become idle' <br />
&nbsp; &nbsp; END AS frenquency <br />
&nbsp; &nbsp; , CASE S.freq_type <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN 'One time only' <br />
&nbsp; &nbsp; &nbsp; WHEN 4 THEN 'Every ' + CASE CONVERT(varchar, S.freq_interval) WHEN '1' THEN 'day' ELSE 'days' END <br />
&nbsp; &nbsp; &nbsp; WHEN 8 THEN 'Every ' + CASE CONVERT(varchar, S.freq_recurrence_factor) WHEN '1' THEN 'week' ELSE 'weeks' END + ' on ' + D.freq_day_concat <br />
&nbsp; &nbsp; &nbsp; WHEN 16 THEN 'Day ' + CONVERT(varchar, S.freq_interval) + ' of every ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; + CASE CONVERT(varchar, S.freq_recurrence_factor) WHEN '1' THEN ' month' ELSE ' months' END <br />
&nbsp; &nbsp; &nbsp; WHEN 32 THEN 'The ' + CASE S.freq_relative_interval <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN 'first' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 2 THEN 'second' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 4 THEN 'third' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 8 THEN 'fourth' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 16 THEN 'last' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + ' ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE S.freq_interval <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN 'Sunday' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 2 THEN 'Monday' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 3 THEN 'Tuesday' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 4 THEN 'Wednesday' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 5 THEN 'Thursday' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 6 THEN 'Friday' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 7 THEN 'Saturday' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 8 THEN 'Day' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 9 THEN 'Weekday' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 10 THEN 'Weekend Day' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + ' of every ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE CONVERT(varchar, S.freq_recurrence_factor) WHEN '1' THEN ' month' ELSE ' months' END <br />
&nbsp; &nbsp; END + CASE S.freq_subday_type <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN ', once, at ' + AT.start_time <br />
&nbsp; &nbsp; &nbsp; WHEN 2 THEN ', every ' + CONVERT(varchar(10), S.freq_subday_interval) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + ' seconds, starting at ' + AT.start_time <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + ' ending at ' &nbsp;+ AT.end_time <br />
&nbsp; &nbsp; &nbsp; WHEN 4 THEN ', every ' + CONVERT(varchar(10), S.freq_subday_interval) + ' minutes, from ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + AT.start_time + ', to ' + AT.end_time <br />
&nbsp; &nbsp; &nbsp; WHEN 8 THEN ', every ' + CONVERT(varchar(10), S.freq_subday_interval) + ' hours, starting at ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + AT.start_time + ', ending at ' + AT.end_time <br />
&nbsp; &nbsp; END AS frequency_detail <br />
&nbsp; &nbsp; , CASE <br />
&nbsp; &nbsp; &nbsp; WHEN S.freq_type = 1 THEN 'On date: ' + AD.active_start_date + ' At time: ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + AT.start_time <br />
&nbsp; &nbsp; &nbsp; WHEN S.freq_type &lt; 64 THEN 'Start date: ' + AD.active_start_date + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE AD.active_end_date <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN '31/12/9999' THEN ' - No end date' &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE ' - End date: ' + AD.active_end_date &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; END AS date_range <br />
&nbsp; &nbsp; , CASE C.name WHEN '[Uncategorized (Local)]' THEN 'Uncategorized' ELSE C.name END AS job_category_name <br />
&nbsp; &nbsp; , J.description AS job_description <br />
&nbsp; &nbsp; , J.date_created &nbsp;<br />
&nbsp; &nbsp; , J.date_modified <br />
FROM &nbsp; &nbsp;msdb.dbo.sysjobs AS J <br />
INNER JOIN &nbsp;msdb.dbo.sysjobsteps AS JS <br />
&nbsp; &nbsp; &nbsp; ON J.job_id = JS.job_id <br />
INNER JOIN &nbsp;msdb.dbo.sysjobschedules AS JSCH <br />
&nbsp; &nbsp; &nbsp; ON J.job_id = JSCH.job_id <br />
INNER JOIN &nbsp;msdb.dbo.sysschedules AS S <br />
&nbsp; &nbsp; &nbsp; ON JSCH.schedule_id = S.schedule_id <br />
INNER JOIN &nbsp;msdb.dbo.syscategories AS C <br />
&nbsp; &nbsp; &nbsp; ON J.category_id = C.category_id <br />
LEFT JOIN &nbsp;sys.server_principals AS SP <br />
&nbsp; &nbsp; &nbsp; ON SP.sid = J.owner_sid <br />
OUTER APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp;freq_day + ', ' <br />
&nbsp; &nbsp; &nbsp; FROM &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT CASE WHEN S.freq_interval &amp; 1 = 1 THEN 'Sunday' ELSE '' END AS freq_day <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UNION ALL SELECT CASE WHEN S.freq_interval &amp; 2 = 2 THEN 'Monday' ELSE '' END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UNION ALL SELECT CASE WHEN S.freq_interval &amp; 4 = 4 THEN 'Tuesday' ELSE '' END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UNION ALL SELECT CASE WHEN S.freq_interval &amp; 8 = 8 THEN 'Wednesday' ELSE '' END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UNION ALL SELECT CASE WHEN S.freq_interval &amp; 16 = 16 THEN 'Thursday' ELSE '' END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UNION ALL SELECT CASE WHEN S.freq_interval &amp; 32 = 32 THEN 'Friday' ELSE '' END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UNION ALL SELECT CASE WHEN S.freq_interval &amp; 64 = 64 THEN 'Saturday' ELSE '' END <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS S <br />
&nbsp; &nbsp; &nbsp; WHERE &nbsp;LEN(freq_day) &gt; 0 <br />
&nbsp; &nbsp; &nbsp; FOR &nbsp;XML PATH ('') <br />
&nbsp; &nbsp; ) AS D (freq_day_concat) <br />
OUTER APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp;STUFF(STUFF(REPLICATE('0', 6 - LEN(S.active_start_time)) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CAST(S.active_start_time AS varchar(6)), 3, 0, ':'), 6, 0, ':') AS start_time <br />
&nbsp; &nbsp; &nbsp; &nbsp; , STUFF(STUFF(REPLICATE('0', 6 - LEN(S.active_end_time)) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CAST(S.active_end_time AS varchar(6)), 3, 0, ':'), 6, 0, ':') AS end_time <br />
&nbsp; &nbsp; ) AS AT <br />
OUTER APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp;CONVERT(char(10), CAST(CAST(S.active_start_date AS char(8)) AS date), 103) AS active_start_date <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CONVERT(char(10), CAST(CAST(S.active_end_date AS char(8)) AS date), 103) AS active_end_date <br />
&nbsp; &nbsp; ) AS AD <br />
OUTER APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp;CAST(NULLIF(JSCH.next_run_date, 0) AS char(8)) + ' ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; + STUFF(STUFF(REPLICATE('0', 6 - LEN(JSCH.next_run_time)) + CAST(JSCH.next_run_time AS char(6)), 3, 0, ':'), 6, 0, ':') AS next_run_date_time <br />
&nbsp; &nbsp; ) AS NR <br />
WHERE &nbsp; &nbsp;1 = 1 <br />
--AND &nbsp; &nbsp;J.name LIKE '%unMot%' <br />
--AND &nbsp; &nbsp;JS.database_name = 'uneBD' <br />
--AND &nbsp; &nbsp;J.enabled &nbsp;= 1 <br />
ORDER BY &nbsp;J.name, JS.step_id</div></td></tr></tbody></table></div>
<p>Bonne planification de job à tous !</p>
<p>ElSüket <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Le petit lien qui fait du bien dans l&#8217;historique des jobs de l&#8217;Agent SQL Server 2012</title>
		<link>https://blog.developpez.com/elsuket/p10965/agent-sql-server/ssms_2012_job_historique_lien_definition</link>
		<comments>https://blog.developpez.com/elsuket/p10965/agent-sql-server/ssms_2012_job_historique_lien_definition#comments</comments>
		<pubDate>Thu, 19 Apr 2012 17:52:22 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>
		<category><![CDATA[SQL Server 2012]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Un petit lien bien agréable a été ajouté dans la visionneuse de l&#8217;historique des jobs de SQL Server dans la version 2012 de SQL Server Management Studio On peut consulter l&#8217;historique d&#8217;un job simplement en effectuant un clic-droit sur le &#8230; <a href="https://blog.developpez.com/elsuket/p10965/agent-sql-server/ssms_2012_job_historique_lien_definition">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Un petit lien bien agréable a été ajouté dans la visionneuse de l&rsquo;historique des jobs de SQL Server dans la version 2012 de <em>SQL Server Management Studio</em><br />
<span id="more-18"></span><br />
On peut consulter l&rsquo;historique d&rsquo;un job simplement en effectuant un clic-droit sur le job en question :</p>
<p><img src="http://blog.developpez.com/media/job_lien_0.png" width="434" height="663" alt="" /></p>
<p>La fenêtre du journal s&rsquo;ouvre alors :</p>
<p><img src="http://blog.developpez.com/media/job_lien_1.jpg" width="838" height="533" alt="" /></p>
<p>Et ce nouveau lien nous permet d&rsquo;accéder directement à la définition du job, ce qui n&rsquo;était pas la cas jusqu&rsquo;à <em>SQL Server Management Studio 2008</em> :</p>
<p><img src="http://blog.developpez.com/media/job_lien_2.png" width="704" height="632" alt="" /></p>
<p>Bonne gestion des jobs !</p>
<p>@++ <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gestion et lecture des journaux d&#8217;événements de SQL Server</title>
		<link>https://blog.developpez.com/elsuket/p10279/moteur-de-base-de-donnees-sql-server/gestion_lecture_journaux_sql_server</link>
		<comments>https://blog.developpez.com/elsuket/p10279/moteur-de-base-de-donnees-sql-server/gestion_lecture_journaux_sql_server#comments</comments>
		<pubDate>Mon, 19 Sep 2011 17:00:00 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici quelques procédures stockées systèmes et quelques suites de clics dans SQL Server Management Studio pour gérer un peu plus finement les fichiers d&#8217;information et d&#8217;erreur du moteur de bases de données de SQL Server, et de l&#8217;Agent SQL Server. &#8230; <a href="https://blog.developpez.com/elsuket/p10279/moteur-de-base-de-donnees-sql-server/gestion_lecture_journaux_sql_server">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici quelques procédures stockées systèmes et quelques suites de clics dans <em>SQL Server Management Studio</em> pour gérer un peu plus finement les fichiers d&rsquo;information et d&rsquo;erreur du moteur de bases de données de SQL Server, et de l&rsquo;Agent SQL Server.<br />
<span id="more-112"></span><br />
Commençons d&rsquo;abord par l&rsquo;emplacement de ces fichiers, qui sont en fait de simples fichiers texte : par défaut il s&rsquo;agit de :<br />
<em>C:\Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG\</em></p>
<p>Le <em>.n</em> indique le <a href="http://blog.developpez.com/elsuket/p7725/snippets/trouver-le-numero-d-une-instance-nommee/">numéro de l&rsquo;instance</a> s&rsquo;il s&rsquo;agit d&rsquo;une instance nommée : dans le cas contraire, le <em>.n</em> est absent.<br />
On trouve dans ce dossier : </p>
<p>=> Des fichiers ERRORLOG et ERRORLOG.[n], où [n] est un entier qui est d&rsquo;autant plus grand qu&rsquo;il est ancien.<br />
Ce sont les fichiers de journaux d&rsquo;erreurs de moteur de base de données.<br />
Si la configuration des journaux d&rsquo;événements n&rsquo;a jamais été modifiée, on a ERRORLOG.6, car comme nous allons le voir, SQL Server ne conserve que 6 journaux d&rsquo;erreur.</p>
<p>=> Des fichiers SQLAGENT et SQLAGENT.[n], où [n] est utilisé de la même façon que précédemment.<br />
On l&rsquo;aura compris, ces fichiers sont les journaux d&rsquo;événements de l&rsquo;Agent SQL Server.</p>
<p>=> Des fichiers FDLAUNCHERRORLOG et FDLAUNCHERRORLOG.[n], qui sont les journaux d&rsquo;événements du moteur de recherche en texte intégral de SQL Server.</p>
<p>=> Des fichiers log_xx.trc, qui sont les fichiers de trace SQL Profiler par défaut de SQL Server.<br />
En effet une trace SQL Profiler est démarrée par défaut à chaque démarrage d&rsquo;un instance SQL Server.<br />
En interrogeant la vue système sys.traces, vous verrez que cette trace est toujours démarrée et porte l&rsquo;id de valeur 1.</p>
<p>Tous les fichiers présents dans ce répertoire sont interprétables par n&rsquo;importe quel éditeur texte, à l&rsquo;exception des fichiers de trace par défaut.<br />
On peut ouvrir ces derniers directement par un double-clic qui exécutera SQL Profiler.</p>
<p>Dans ce billet nous nous limiterons à la gestion des fichiers d’événements :<br />
&#8211; du moteur de bases de données SQL Server<br />
&#8211; de l&rsquo;Agent SQL Server</p>
<p>On peut tout à fait changer le nombre de journaux d&rsquo;erreur à converser, et on peut aussi automatiser leur renouvellement, par exemple avec un fichier par jour.<br />
Cela permet, lorsqu&rsquo;on audite ces fichiers ou qu&rsquo;on conduit des investigations à la suite d&rsquo;un problème, d&rsquo;avoir un fichier de journal assez petit, en ne se focalisant que sur un seul jour.</p>
<p>Voyons d&rsquo;abord comment lire ces fichiers journaux à l&rsquo;aide de SQL Server Management Studio.<br />
Après avoir ouvert l&rsquo;<em>Explorateur d&rsquo;Objets</em> (F8), le nœud <em>Gestion</em> une fois développé, nous affiche un nœud <em>Journaux SQL Server</em>:<br />
<img src="http://blog.developpez.com/media/error_log_09.png" width="359" height="632" alt="" /></p>
<p>Un double-clic sur l&rsquo;un d&rsquo;entre eux affiche leur contenu, et on peut accéder aux autres journaux à partir du même dialogue :</p>
<p><img src="http://blog.developpez.com/media/error_log_10.jpg" width="693" height="433" alt="" /></p>
<p>A partir de cette fenêtre, on voit que l&rsquo;on peut visualiser plusieurs types de journaux :</p>
<p>&#8211; Ceux de l&rsquo;Agent SQL Server<br />
&#8211; Ceux du moteur de bases de donnée relationnelles<br />
&#8211; Ceux de Windows<br />
&#8211; Ceux de la messagerie de bases de données</p>
<p>On peut bien sûr mélanger le contenu de plusieurs journaux de types différents, ce qui peut aider à corréler les tenants et aboutissants d&rsquo;un événement touchant à SQL Server.</p>
<p>Enfin, à l&rsquo;aide des boutons de la barre d&rsquo;outils, il est possible de restreindre les dates entre lesquelles on souhaite afficher les messages, et aussi de rechercher dans le contenu de ceux-ci.<br />
Ces deux fonctions sont assez rapides si la machine et SQL Server fonctionnent correctement, mais il en va parfois tout autrement lorsque des problèmes surviennent.<br />
En effet, il m&rsquo;est arrivé de devoir lire des fichiers de journaux faisant plusieurs centaines de Mo, et il est impossible d&rsquo;arrêter la <em>Visionneuse de Journaux</em>, à moins de décocher tous les journaux, ce qui n&rsquo;affiche plus rien. C&rsquo;est là l&rsquo;intérêt de gérer ces fichiers.</p>
<p>Voyons donc comment augmenter (ou diminuer) le nombre de journaux d&rsquo;erreurs.<br />
Dans l&rsquo;Explorateur d&rsquo;Objets (F8), après avoir développé le nœud <em>Gestion</em>, il suffit de faire un clic-droit sur <em>Journaux SQL Server</em> puis de choisir l&rsquo;option <em>Configurer</em> :</p>
<p><img src="http://blog.developpez.com/media/error_log_01.png" width="339" height="554" alt="" /></p>
<p>On remarque que l&rsquo;étiquette portée par les fichiers journaux comporte la date de dernière écriture dans le fichier.<br />
Par défaut la case <em>Limiter le nombre de fichiers de journaux d&rsquo;erreurs avant qu&rsquo;ils ne soient recyclés</em> n&rsquo;est pas cochée.<br />
Dès lors qu&rsquo;on la coche, on est libre de spécifier le nombre de journaux que l&rsquo;on souhaite conserver :<br />
<img src="http://blog.developpez.com/media/error_log_02.png" width="704" height="499" alt="" /><br />
Je le mets toujours au maximum, 99, parce que je l&rsquo;assortis d&rsquo;un job de l&rsquo;Agent SQL Server pour recycler les journaux (ce que nous allons voir par la suite).<br />
En scriptant le changement, on obtient le script suivant :</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">USE [master] &lt;br /&gt;<br />
GO &lt;br /&gt;<br />
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'NumErrorLogs', REG_DWORD, 99 &lt;br /&gt;<br />
GO</div></td></tr></tbody></table></div>
<p>C&rsquo;est à dire que le nombre de journaux de l&rsquo;instance SQL Server n&rsquo;est pas stocké dans une des bases de données système (on aurait pu le stocker dans la base de données master ou msdb).</p>
<p>La procédure stockée <a href="http://msdn.microsoft.com/fr-fr/library/ms182512.aspx">sp_cycle_errorlog</a> permet de forcer la création d&rsquo;un nouveau fichier de journal.<br />
Le cas échéant, elle supprime également le fichier de journal le plus ancien si son numéro incrémenté dépasse le nombre de journaux que l&rsquo;on a spécifié vouloir conserver.<br />
On peut donc créer un job de l&rsquo;Agent SQL Server qui s&rsquo;exécute tous les jours à minuit pour forcer la création d&rsquo;un nouveau journal d&rsquo;erreur.<br />
Créons donc ce job, ce que l&rsquo;on peut faire très simplement par un clic-droit sur le nœud <em>Agent SQL Server</em> de l&rsquo;Explorateur d&rsquo;Objets :<br />
<img src="http://blog.developpez.com/media/error_log_03.png" width="538" height="657" alt="" /></p>
<p>On spécifie le nom du job, et un petit commentaire sur le rôle du job ne fait jamais de mal :</p>
<p><img src="http://blog.developpez.com/media/error_log_04.png" width="705" height="631" alt="" /></p>
<p>Puis on peut passer à la page <em>Étapes</em> :</p>
<p><img src="http://blog.developpez.com/media/error_log_05.png" width="704" height="634" alt="" /></p>
<p><strong>EDIT 09/02/2012: </strong> il faut mettre le contexte de base de données à <strong>msdb</strong>, et non pas le laisser sur <em>master</em></p>
<p>On peut ensuite basculer dans la page <em>Planifications</em>.<br />
Après avoir cliqué sur le bouton <em>Nouvelle</em>, on obtient la fenêtre suivante :<br />
<img src="http://blog.developpez.com/media/error_log_06.png" width="676" height="589" alt="" /></p>
<p>En cliquant sur OK dans ce dialogue et dans le dialogue parent (<em>Propriétés du travail</em>), on valide la création du travail.<br />
On le trouve dès lors dans l&rsquo;<em>Explorateur d&rsquo;Objets</em> dans la liste des travaux :<br />
<img src="http://blog.developpez.com/media/error_log_07.png" width="323" height="510" alt="" /></p>
<p>On remarque au passage le nœud <em>Journaux d&rsquo;erreurs</em>, enfant du nœud <em>Agent SQL server</em> : c&rsquo;est à partir de celui-ci que l&rsquo;on peut lire les journaux de l&rsquo;Agent SQL Server :</p>
<p><img src="http://blog.developpez.com/media/error_log_08.png" width="323" height="690" alt="" /></p>
<p>De la même façon, il est possible de configurer la rétention d&rsquo;informations :<br />
<img src="http://blog.developpez.com/media/error_log_12.png" width="302" height="554" alt="" /></p>
<p>Comme on le voit, à la différence des options pour les journaux du moteur de bases de données relationnelles, il est ici possible de recycler les journaux de l&rsquo;<em>Agent SQL Server</em>.<br />
<img src="http://blog.developpez.com/media/error_log_13.png" width="703" height="631" alt="" /></p>
<p>Cette fois, c&rsquo;est la procédure stockée <a href="http://msdn.microsoft.com/fr-fr/library/ms186874.aspx">sp_cycle_agent_errorlog</a> qui permet de forcer le recyclage des journaux de l&rsquo;Agent SQL Server.<br />
On peut donc tout à fait l&rsquo;ajouter en seconde étape de notre travail <em>DBA &#8211; Cycle Event Logs</em> :<br />
<img src="http://blog.developpez.com/media/error_log_14.png" width="942" height="632" alt="" /></p>
<p>Après avoir cliqué sur <em>Nouveau &#8230;</em>, on peut modifier le travail pour la régénération des journaux de l&rsquo;Agent SQL Server :</p>
<p><img src="http://blog.developpez.com/media/error_log_15.png" width="703" height="632" alt="" /></p>
<p>Une fois que l&rsquo;on a cliqué sur OK, puis de la même façon dans le dialogue parent (<em>Propriétés du travail</em>), le travail est maintenant modifié pour renouveler les journaux du moteur de bases de données et de l&rsquo;Agent SQL Server, tous les jours à minuit.</p>
<p>Il est enfin possible de lire les fichiers journaux de ces deux types (SGBDR et Agent) à l&rsquo;aide de la procédure stockée étendue système xp_readerrorlog, qui n&rsquo;est pas documentée.<br />
Comprenez par là que l&rsquo;utilisation à vos risques et périls, et que rien ne garantit que Microsoft mettra toujours à disposition cette fonctionnalité dans une future version de SQL Server.<br />
Ici on peut se permettre de l&rsquo;utiliser car cela n&rsquo;a aucun impact sur le moteur de bases de données : on ne fait que de la lecture de fichiers texte qui sont stockés en dehors des structures de stockage gérées par SQL Server.</p>
<p>Voici donc la document officieuse de cette procédure stockée étendue.<br />
Elle peut prendre quatre paramètres en entrée, qui sont les suivants :</p>
<p>=> le premier indique est un int, et indique l&rsquo;indice du journal à lire : passez zéro si vous souhaitez lire le journal courant, 1 si vous souhaitez l&rsquo;archive la plus récente. On peut également de rien passer, et on obtient alors le contenu du fichier de journal du SGBDR courant.<br />
=> le deuxième est un int, et précise le type de journal à lire : passez 1 pour les journaux du SGBDR, et 2 pour l&rsquo;Agent SQL Server<br />
=> le 3e et le 4e sont des varchar(255), et sont tous deux des chaînes à rechercher dans le contenu des messages.</p>
<p>Vous l&rsquo;aurez compris, aucun des paramètres n&rsquo;est obligatoire.<br />
Comme il s&rsquo;agit d&rsquo;une procédure stockée étendue, il est impossible d&rsquo;en obtenir le nom des paramètres, ce qui fait que tout appel se fait par une suite de valeurs.</p>
<p>Si l&rsquo;on souhaite donc chercher les échecs d&rsquo;authentification dans le journal courant du SGBDR, on exécutera :</p>
<p><code class="codecolorer text default"><span class="text">EXEC xp_readerrorlog 0, 1, 'Failed', 'login'</span></code></p>
<p>Bonnes investigations des journaux SQL Server !</p>
<p>ElSüket <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Trouver et changer le propriétaire d&#8217;un job de l&#8217;Agent SQL Server</title>
		<link>https://blog.developpez.com/elsuket/p10543/agent-sql-server/proprietaire_job</link>
		<comments>https://blog.developpez.com/elsuket/p10543/agent-sql-server/proprietaire_job#comments</comments>
		<pubDate>Sun, 27 Nov 2011 06:44:21 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Fonctionnalité pratique pour ne pas dire nécessaire, l&#8217;Agent SQL Server est le planificateur de tâches de SQL Server. Il permet d&#8217;effectuer des tâches très variées, qui vont de l&#8217;exécution d&#8217;une procédure stockée à celle d&#8217;un script PowerShell en passant par &#8230; <a href="https://blog.developpez.com/elsuket/p10543/agent-sql-server/proprietaire_job">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Fonctionnalité pratique pour ne pas dire nécessaire, l&rsquo;Agent SQL Server est le planificateur de tâches de SQL Server.<br />
Il permet d&rsquo;effectuer des tâches très variées, qui vont de l&rsquo;exécution d&rsquo;une procédure stockée à celle d&rsquo;un script PowerShell en passant par celle d&rsquo;un package SQL Server Integration Services et bien d&rsquo;autres, et ce, à intervalles de temps réguliers et planifiés.</p>
<p>Côté sécurité, cette fonctionnalité n&rsquo;est pas en reste, puisque tout job a un propriétaire.<br />
Il est donc requis de vérifier que le propriétaire d&rsquo;un job à les droits nécessaires à l&rsquo;exécution de celui-ci.</p>
<p>Cela peut se faire de deux façons : par l&rsquo;interface graphique de SQL Server Management Studio, ou bien en requêtes.<br />
Voyons cela plus en détails :<br />
<span id="more-17"></span></p>
<p>=> <strong>Par des requêtes</strong></p>
<p>Voici la requête qui permet de trouver le propriétaire de tous les jobs :</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">------------------------------- <br />
-- Nicolas Souquet - 27/11/2011 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;J.name AS job_name <br />
&nbsp; &nbsp; , SP.name AS job_owner_name <br />
FROM &nbsp; &nbsp;msdb.dbo.sysjobs AS J <br />
INNER JOIN &nbsp;sys.server_principals AS SP <br />
&nbsp; &nbsp; &nbsp; ON SP.sid = J.owner_sid <br />
WHERE &nbsp; &nbsp;J.name = 'monJob'</div></td></tr></tbody></table></div>
<p>En dé-commentant la dernière ligne, on peut trouver le propriétaire d&rsquo;un job en particulier.</p>
<p>Si l&rsquo;on souhaite le changer, il suffit d&rsquo;exécuter :</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UPDATE &nbsp; &nbsp;msdb.dbo.sysjobs <br />
SET &nbsp; &nbsp;owner_sid = SP.sid <br />
FROM &nbsp; &nbsp;msdb.dbo.sysjobs AS J <br />
CROSS JOIN &nbsp;sys.server_principals AS SP <br />
WHERE &nbsp; &nbsp;J.name = 'monJob' <br />
AND &nbsp; &nbsp;SP.name = 'nomDeLogin'</div></td></tr></tbody></table></div>
<p>Et le tour est joué <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p>=> <strong>Par l&rsquo;interface graphique</strong> :</p>
<p>Il suffit de se rendre dans les propriétés du job en question :</p>
<p><img src="http://blog.developpez.com/media/job_owner_1.png" width="497" height="505" alt="" /></p>
<p>Une fenêtre s&rsquo;ouvre alors, montrant le propriétaire du job dans la saisie texte à la même étiquette :</p>
<p><img src="http://blog.developpez.com/media/job_owner_2.png" width="704" height="632" alt="" /></p>
<p>On peut dès lors changer ce propriétaire à l&rsquo;aide du bouton de parcours des utilisateurs, (les 3 points de suspension à droite ce cette saisie) ou bien saisir un nom de connexion existant.</p>
<p>On trouve les connexions existantes toujours dans l&rsquo;explorateur d&rsquo;objets (F8) :</p>
<p><img src="http://blog.developpez.com/media/job_owner_3.png" width="340" height="503" alt="" /></p>
<p>Bonne gestion des connexions et des jobs <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p>ElSüket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Voir l&#8217;historique d&#8217;exécution des jobs par une requête</title>
		<link>https://blog.developpez.com/elsuket/p7895/snippets/voir_l_historique_d_execution_des_jobs_p</link>
		<comments>https://blog.developpez.com/elsuket/p7895/snippets/voir_l_historique_d_execution_des_jobs_p#comments</comments>
		<pubDate>Fri, 24 Jul 2009 06:00:00 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Si la visionneuse du journal est pratique pour voir l&#8217;historique des exécutions d&#8217;un job, comment peut-on voir s&#8217;il existe des jobs dont l&#8217;exécution a échoué (ou réussi) pour pouvoir l&#8217;encapsuler dans une application ou un rapport SSRS par exemple ? &#8230; <a href="https://blog.developpez.com/elsuket/p7895/snippets/voir_l_historique_d_execution_des_jobs_p">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Si la visionneuse du journal est pratique pour voir l&rsquo;historique des exécutions d&rsquo;un job, comment peut-on voir s&rsquo;il existe des jobs dont l&rsquo;exécution a échoué (ou réussi) pour pouvoir l&rsquo;encapsuler dans une application ou un rapport SSRS par exemple ?</p>
<p><span id="more-14"></span></p>
<p>Les tables système de la base de données MSDB nous permettent de spécifier une requête nous permettant de retrouver tous les informations dont nous avons besoin à propos des jobs :</p>
<p>&#8211; msdb.dbo.sysjobs stocke la liste de tous les jobs présents sur l&rsquo;instance, qu&rsquo;ils soient activés ou non<br />
&#8211; msdb.dbo.sysjobhistory stocke la liste de toutes les exécutions des jobs et de leurs étapes<br />
&#8211; msdb.dbo.sysjobsteps stocke la description de toutes les étapes de tous les jobs de l&rsquo;instance</p>
<p>Voici donc, par exemple, comment retrouver tous les échecs pour le job nommé &lsquo;TEST&rsquo;, avec leur date :</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--------------------------------- <br />
-- Nicolas SOUQUET - 24/07/2009 - <br />
--------------------------------- <br />
SELECT nomJob, <br />
&nbsp; &nbsp; CAST(STUFF(STUFF(runDateTime, 12, 0, ':'), 15, 0, ':') AS DATETIME) AS DateEchecExecJob <br />
FROM <br />
( <br />
&nbsp; SELECT J.name AS nomJob, <br />
&nbsp; &nbsp; &nbsp; CAST(H.run_date AS CHAR(8)) + ' ' + <br />
&nbsp; &nbsp; &nbsp; CASE LEN(CAST(H.run_time AS VARCHAR(6))) <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 5 THEN '0' + CAST(H.run_time AS CHAR(5)) <br />
&nbsp; &nbsp; &nbsp; &nbsp; ELSE CAST(H.run_time AS CHAR(6)) <br />
&nbsp; &nbsp; &nbsp; END AS runDateTime <br />
&nbsp; FROM msdb.dbo.sysjobs J <br />
&nbsp; JOIN msdb.dbo.sysjobhistory H <br />
&nbsp; &nbsp; ON J.job_id = H.job_id <br />
&nbsp; WHERE J.name = 'TEST' <br />
&nbsp; AND J.enabled = 1 -- Le job est activé <br />
&nbsp; AND H.run_status = 0 -- 0 : Echec | 1 : Réussite <br />
&nbsp; AND H.step_id = 0 -- quelle que soit l'étape du job <br />
) AS JOB_FAILED_EXEC (nomJob, runDateTime)</div></td></tr></tbody></table></div>
<p>Et si l&rsquo;on veut être relativement complet :</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--------------------------------- <br />
-- Nicolas SOUQUET - 24/07/2009 - <br />
--------------------------------- <br />
SELECT &nbsp;nomJob <br />
&nbsp; , nomEtapeJob <br />
&nbsp; , numeroEtapeJob <br />
&nbsp; , msgEtape <br />
&nbsp; , CAST(STUFF(STUFF(dateExecutionEtape, 12, 0, ':'), 15, 0, ':') AS DATETIME) AS dateExecutionEtape <br />
&nbsp; , dureeExecutionEtape <br />
&nbsp; , statutExecutionEtape <br />
FROM &nbsp;<br />
( &nbsp;<br />
&nbsp; SELECT &nbsp; &nbsp;J.name AS nomJob <br />
&nbsp; &nbsp; &nbsp; , S.step_name AS nomEtapeJob <br />
&nbsp; &nbsp; &nbsp; , S.step_id AS numeroEtapeJob <br />
&nbsp; &nbsp; &nbsp; , ISNULL('Erreur : ' + M.description, H.message) AS msgEtape <br />
&nbsp; &nbsp; &nbsp; , CAST(H.run_date AS CHAR(8)) + ' ' + &nbsp;<br />
&nbsp; &nbsp; &nbsp; CASE LEN(CAST(H.run_time AS VARCHAR(6))) <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN '00000' + CAST(H.run_time AS CHAR(1)) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 2 THEN '0000' + CAST(H.run_time AS CHAR(2)) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 3 THEN '000' + CAST(H.run_time AS CHAR(3)) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 4 THEN '00' + CAST(H.run_time AS CHAR(4)) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 5 THEN '0' + CAST(H.run_time AS CHAR(5)) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; ELSE CAST(H.run_time AS CHAR(6)) &nbsp;<br />
&nbsp; &nbsp; &nbsp; END AS dateExecutionEtape <br />
&nbsp; &nbsp; &nbsp; , CASE LEN(CAST(H.run_duration AS VARCHAR(10))) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN '00:00:0' + CAST(H.run_duration AS CHAR(1)) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 2 THEN '00:00:' + CAST(H.run_duration AS CHAR(2)) &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 3 THEN '00:0' + STUFF(CAST(H.run_duration AS CHAR(3)), 2, 0, ':') &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 4 THEN '00:' + STUFF(CAST(H.run_duration AS CHAR(4)), 3, 0, ':') &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 5 THEN '0' + STUFF(STUFF(CAST(H.run_duration AS CHAR(5)), 2, 0, ':'), 5, 0, ':') &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 6 THEN STUFF(STUFF(CAST(H.run_duration AS CHAR(6)), 3, 0, ':'), 6, 0, ':') &nbsp;<br />
&nbsp; &nbsp; &nbsp; END AS dureeExecutionEtape <br />
&nbsp; &nbsp; &nbsp; , CASE H.run_status &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 0 THEN 'FAILED' <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN 'SUCCESS' <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 2 THEN 'RETRY' <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 3 THEN 'CANCELED' <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 4 THEN 'RUNNING' -- Pas fiable <br />
&nbsp; &nbsp; &nbsp; END AS statutExecutionEtape <br />
&nbsp; FROM &nbsp; &nbsp;msdb.dbo.sysjobs AS J &nbsp; <br />
&nbsp; INNER JOIN &nbsp;msdb.dbo.sysjobsteps AS S &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; ON J.job_id = S.job_id &nbsp;<br />
&nbsp; INNER JOIN &nbsp;msdb.dbo.sysjobhistory AS H &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; ON S.job_id = H.job_id &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; AND S.step_id = H.step_id &nbsp;<br />
&nbsp; LEFT JOIN &nbsp;sys.sysmessages AS M &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; ON H.sql_message_id = M.error &nbsp;<br />
) AS JOB_CHARACTERISTICS (nomJob, nomEtapeJob, numeroEtapeJob, msgEtape, dateExecutionEtape, dureeExecutionEtape, statutExecutionEtape)</div></td></tr></tbody></table></div>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Une procédure stockée pour défragmenter les indexes sous SQL Server 2005 et ultérieur</title>
		<link>https://blog.developpez.com/elsuket/p7712/moteur-de-base-de-donnees-sql-server/indexation/une_procedure_stockee_pour_defragmenter</link>
		<comments>https://blog.developpez.com/elsuket/p7712/moteur-de-base-de-donnees-sql-server/indexation/une_procedure_stockee_pour_defragmenter#comments</comments>
		<pubDate>Fri, 05 Jun 2009 16:53:33 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>
		<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une petite procédure stockée que l&#8217;on peut exécuter régulièrement dans un job pour défragmenter les indexes de toutes les bases de données, en fixant les seuils de nombre de page et de pourcentage moyen de fragmentation 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169--------------------------------- -- Nicolas &#8230; <a href="https://blog.developpez.com/elsuket/p7712/moteur-de-base-de-donnees-sql-server/indexation/une_procedure_stockee_pour_defragmenter">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une petite procédure stockée que l&rsquo;on peut exécuter régulièrement dans un job pour défragmenter les indexes de toutes les bases de données, en fixant les seuils de nombre de page et de pourcentage moyen de fragmentation</p>
<p><span id="more-24"></span></p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br />93<br />94<br />95<br />96<br />97<br />98<br />99<br />100<br />101<br />102<br />103<br />104<br />105<br />106<br />107<br />108<br />109<br />110<br />111<br />112<br />113<br />114<br />115<br />116<br />117<br />118<br />119<br />120<br />121<br />122<br />123<br />124<br />125<br />126<br />127<br />128<br />129<br />130<br />131<br />132<br />133<br />134<br />135<br />136<br />137<br />138<br />139<br />140<br />141<br />142<br />143<br />144<br />145<br />146<br />147<br />148<br />149<br />150<br />151<br />152<br />153<br />154<br />155<br />156<br />157<br />158<br />159<br />160<br />161<br />162<br />163<br />164<br />165<br />166<br />167<br />168<br />169<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--------------------------------- <br />
-- Nicolas SOUQUET - 05/06/2009 - <br />
--------------------------------- <br />
CREATE PROCEDURE [dbo].[Ps_Indexes_Rebuild] <br />
AS <br />
BEGIN <br />
&nbsp; SET NOCOUNT ON <br />
&nbsp;<br />
&nbsp; -- Table dans laquelle on va récupérer les noms et caractéristiques des indexes <br />
&nbsp; DECLARE @Tbindexes TABLE <br />
&nbsp; ( <br />
&nbsp; &nbsp; DB SYSNAME, <br />
&nbsp; &nbsp; Tables SYSNAME, <br />
&nbsp; &nbsp; IndexName SYSNAME, <br />
&nbsp; &nbsp; Frag VARCHAR(5), <br />
&nbsp; &nbsp; PageUsage VARCHAR(5), <br />
&nbsp; &nbsp; Pages VARCHAR(10), <br />
&nbsp; &nbsp; FillFactors TINYINT, <br />
&nbsp; &nbsp; Seeks VARCHAR(20), <br />
&nbsp; &nbsp; Scans VARCHAR(20), <br />
&nbsp; &nbsp; LastUserSeek VARCHAR(19), <br />
&nbsp; &nbsp; LastUserScan VARCHAR(19), <br />
&nbsp; &nbsp; IsUniqueConstraint BIT, <br />
&nbsp; &nbsp; IsPadded BIT, <br />
&nbsp; &nbsp; IsHypothetical BIT <br />
&nbsp; ) <br />
&nbsp;<br />
&nbsp; -- Table dans laquelle on récupère les statistiques des indexes <br />
&nbsp; DECLARE @TbIndexesStats TABLE <br />
&nbsp; ( <br />
&nbsp; &nbsp; database_id SMALLINT, <br />
&nbsp; &nbsp; object_id INT, <br />
&nbsp; &nbsp; index_id INT, <br />
&nbsp; &nbsp; avg_fragmentation_in_percent NUMERIC(4,2), <br />
&nbsp; &nbsp; avg_page_space_used_in_percent NUMERIC(4,2), <br />
&nbsp; &nbsp; page_count BIGINT, <br />
&nbsp; &nbsp; user_seeks BIGINT, <br />
&nbsp; &nbsp; user_scans BIGINT, <br />
&nbsp; &nbsp; last_user_seek DATETIME, <br />
&nbsp; &nbsp; last_user_scan DATETIME <br />
&nbsp; ); <br />
&nbsp;<br />
&nbsp; -- Récupération des stats sur les indexes <br />
&nbsp; WITH CTE_DB AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT database_id <br />
&nbsp; &nbsp; FROM sys.databases <br />
&nbsp; &nbsp; WHERE name NOT IN ('master', 'model', 'msdb', 'tempdb', 'ReportServer', 'ReportServerTempDB', 'distribution') <br />
&nbsp; ) <br />
&nbsp; INSERT INTO @TbIndexesStats <br />
&nbsp; SELECT IPS.database_id, <br />
&nbsp; &nbsp; &nbsp; IPS.object_id, <br />
&nbsp; &nbsp; &nbsp; IPS.index_id, <br />
&nbsp; &nbsp; &nbsp; IPS.avg_fragmentation_in_percent, <br />
&nbsp; &nbsp; &nbsp; IPS.avg_page_space_used_in_percent, <br />
&nbsp; &nbsp; &nbsp; IPS.page_count, <br />
&nbsp; &nbsp; &nbsp; IUS.user_seeks, <br />
&nbsp; &nbsp; &nbsp; IUS.user_scans, <br />
&nbsp; &nbsp; &nbsp; IUS.last_user_seek, <br />
&nbsp; &nbsp; &nbsp; IUS.last_user_scan <br />
&nbsp; FROM sys.dm_db_index_physical_stats(NULL, NULL, NULL, NULL, 'SAMPLED') IPS <br />
&nbsp; JOIN CTE_DB ON CTE_DB.database_id = IPS.database_id <br />
&nbsp; JOIN sys.dm_db_index_usage_stats IUS <br />
&nbsp; &nbsp; &nbsp; ON IUS.database_id = IPS.database_id <br />
&nbsp; &nbsp; &nbsp; AND IUS.object_id = IPS.object_id <br />
&nbsp; &nbsp; &nbsp; AND IUS.index_id = IPS.index_id <br />
&nbsp; WHERE IPS.index_id &gt; 0 <br />
&nbsp; AND IPS.avg_fragmentation_in_percent &gt; 25.0 <br />
&nbsp; AND IPS.page_count &gt; 50 <br />
&nbsp;<br />
&nbsp; -- Récupération des noms et caractéristiques des indexes <br />
&nbsp; DECLARE @SQL VARCHAR(1024), <br />
&nbsp; &nbsp; &nbsp; @Database_id VARCHAR(10), <br />
&nbsp; &nbsp; &nbsp; @Object_id VARCHAR(10), <br />
&nbsp; &nbsp; &nbsp; @Index_id VARCHAR(10), <br />
&nbsp; &nbsp; &nbsp; @AvgFragInPercent VARCHAR(5), <br />
&nbsp; &nbsp; &nbsp; @AvgPageSpaceUsedInPercent VARCHAR(5), <br />
&nbsp; &nbsp; &nbsp; @PageCount VARCHAR(10), <br />
&nbsp; &nbsp; &nbsp; @User_seeks VARCHAR(20), <br />
&nbsp; &nbsp; &nbsp; @User_scans VARCHAR(20), <br />
&nbsp; &nbsp; &nbsp; @Last_user_seek VARCHAR(19), <br />
&nbsp; &nbsp; &nbsp; @Last_user_scan VARCHAR(19) <br />
&nbsp;<br />
&nbsp; DECLARE curDBIndexes CURSOR FOR <br />
&nbsp; &nbsp; SELECT CAST(database_id AS VARCHAR(10)), <br />
&nbsp; &nbsp; &nbsp; CAST(object_id AS VARCHAR(10)), <br />
&nbsp; &nbsp; &nbsp; CAST(index_id AS VARCHAR(10)), <br />
&nbsp; &nbsp; &nbsp; CAST(avg_fragmentation_in_percent AS VARCHAR(5)), <br />
&nbsp; &nbsp; &nbsp; CAST(avg_page_space_used_in_percent AS VARCHAR(5)), <br />
&nbsp; &nbsp; &nbsp; CAST(page_count AS VARCHAR(10)), <br />
&nbsp; &nbsp; &nbsp; CAST(user_seeks AS VARCHAR(20)), <br />
&nbsp; &nbsp; &nbsp; CAST(user_scans AS VARCHAR(20)), <br />
&nbsp; &nbsp; &nbsp; COALESCE(CONVERT(VARCHAR(19), last_user_seek, 120), 'NULL'), <br />
&nbsp; &nbsp; &nbsp; COALESCE(CONVERT(VARCHAR(19), last_user_scan, 120), 'NULL') <br />
&nbsp; &nbsp; FROM @TbIndexesStats <br />
&nbsp; FOR READ ONLY <br />
&nbsp;<br />
&nbsp; OPEN curDBIndexes <br />
&nbsp; FETCH NEXT FROM curDBIndexes INTO @Database_id, @Object_id, @Index_id, @AvgFragInPercent, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @AvgPageSpaceUsedInPercent, @PageCount, @User_seeks, @User_scans, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Last_user_seek, @Last_user_scan <br />
&nbsp; WHILE @@FETCH_STATUS = 0 <br />
&nbsp; BEGIN <br />
&nbsp; &nbsp; SET @SQL = 'SELECT DB_NAME(' + @Database_id + '),' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'O.name,' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'IDX.name,' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @AvgFragInPercent + ',' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @AvgPageSpaceUsedInPercent + ',' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @PageCount + ',' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'IDX.fill_factor, ' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @User_seeks + ',' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @User_scans + ',''' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Last_user_seek + ''',''' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Last_user_scan + ''',' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'IDX.is_unique_constraint, ' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'IDX.is_padded, ' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'IDX.is_hypothetical' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' FROM ' + DB_NAME(CAST(@Database_id AS INT)) + '.sys.indexes IDX' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' JOIN ' &nbsp;+ DB_NAME(CAST(@Database_id AS INT)) + '.sys.objects O ON O.object_id = IDX.object_id' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' WHERE IDX.object_id = ' + @Object_id + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' AND IDX.index_id = ' + @Index_id <br />
&nbsp;<br />
&nbsp; &nbsp; INSERT INTO @Tbindexes <br />
&nbsp; &nbsp; EXEC (@SQL) <br />
&nbsp;<br />
&nbsp; &nbsp; FETCH NEXT FROM curDBIndexes INTO @Database_id, @Object_id, @Index_id, @AvgFragInPercent, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @AvgPageSpaceUsedInPercent, @PageCount, @User_seeks, @User_scans, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Last_user_seek, @Last_user_scan <br />
&nbsp; END <br />
&nbsp; DEALLOCATE curDBIndexes <br />
&nbsp;<br />
&nbsp; -- Reconstruction des indexes <br />
&nbsp; DECLARE @DB SYSNAME, <br />
&nbsp; &nbsp; &nbsp; @Tables SYSNAME, <br />
&nbsp; &nbsp; &nbsp; @IndexName SYSNAME, <br />
&nbsp; &nbsp; &nbsp; @FillFactors VARCHAR(5), <br />
&nbsp; &nbsp; &nbsp; @IsPadded BIT, <br />
&nbsp; &nbsp; &nbsp; @RebuildCommand VARCHAR(1024) <br />
&nbsp;<br />
&nbsp; DECLARE CUR_INDEXES_TO_REBUILD CURSOR FOR <br />
&nbsp; &nbsp; SELECT DB, <br />
&nbsp; &nbsp; &nbsp; &nbsp; Tables, <br />
&nbsp; &nbsp; &nbsp; &nbsp; IndexName, <br />
&nbsp; &nbsp; &nbsp; &nbsp; CAST( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CASE FillFactors <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 0 THEN 99 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE FillFactors <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END AS VARCHAR(5) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ), <br />
&nbsp; &nbsp; &nbsp; &nbsp; IsPadded <br />
&nbsp; &nbsp; FROM @Tbindexes <br />
&nbsp; FOR READ ONLY <br />
&nbsp;<br />
&nbsp; OPEN CUR_INDEXES_TO_REBUILD <br />
&nbsp; FETCH NEXT FROM CUR_INDEXES_TO_REBUILD INTO @DB, @Tables, @IndexName, @FillFactors, @IsPadded <br />
&nbsp; WHILE @@FETCH_STATUS = 0 <br />
&nbsp; BEGIN <br />
&nbsp; &nbsp; SELECT @RebuildCommand = 'ALTER INDEX ' + @IndexName + ' ON ' + @DB + '.dbo.' + @Tables + &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' REBUILD WITH (FILLFACTOR = ' + @FillFactors + &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CASE @IsPadded <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN ', PAD_INDEX = ON)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE ')' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; EXEC (@RebuildCommand) <br />
&nbsp; &nbsp; FETCH NEXT FROM CUR_INDEXES_TO_REBUILD INTO @DB, @Tables, @IndexName, @FillFactors, @IsPadded <br />
&nbsp; END <br />
&nbsp; DEALLOCATE CUR_INDEXES_TO_REBUILD <br />
END</div></td></tr></tbody></table></div>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Suivre les plans de maintenance</title>
		<link>https://blog.developpez.com/elsuket/p7865/moteur-de-base-de-donnees-sql-server/suivre_les_plans_de_maintenance</link>
		<comments>https://blog.developpez.com/elsuket/p7865/moteur-de-base-de-donnees-sql-server/suivre_les_plans_de_maintenance#comments</comments>
		<pubDate>Thu, 09 Jul 2009 20:15:56 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Comment savoir si un plan de maintenance s&#8217;est correctement exécuté ? Comment savoir combien de temps a duré son exécution ? Une requête simple dans la base de données système MSDB nous donne la réponse &#8230; Valable sous SQL Server &#8230; <a href="https://blog.developpez.com/elsuket/p7865/moteur-de-base-de-donnees-sql-server/suivre_les_plans_de_maintenance">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Comment savoir si un plan de maintenance s&rsquo;est correctement exécuté ?<br />
Comment savoir combien de temps a duré son exécution ?</p>
<p>Une requête simple dans la base de données système MSDB nous donne la réponse &#8230;<br />
Valable sous SQL Server 2000 et ultérieur <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p><span id="more-13"></span></p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--------------------------------- <br />
-- Nicolas SOUQUET - 09/07/2009 - &nbsp;<br />
--------------------------------- <br />
SELECT plan_name, <br />
&nbsp; &nbsp; database_name, <br />
&nbsp; &nbsp; activity, <br />
&nbsp; &nbsp; start_time, <br />
&nbsp; &nbsp; end_time, <br />
&nbsp; &nbsp; CASE LEN(CAST(duration / 3600 AS VARCHAR(4))) <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN '0' + CAST(duration / 3600 AS VARCHAR(4)) <br />
&nbsp; &nbsp; &nbsp; ELSE CAST(duration / 3600 AS VARCHAR(4)) <br />
&nbsp; &nbsp; END + ':' + <br />
&nbsp; &nbsp; CASE LEN(CAST(duration / 60 % 60 AS VARCHAR(2))) <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN '0' + CAST(duration / 60 % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; &nbsp; ELSE CAST(duration / 60 % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; END <br />
&nbsp; &nbsp; + ':' + &nbsp;<br />
&nbsp; &nbsp; CASE LEN(CAST(duration % 60 AS VARCHAR(2))) <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN '0' + CAST(duration % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; &nbsp; ELSE CAST(duration % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; END Durée <br />
FROM msdb.dbo.sysdbmaintplan_history <br />
WHERE succeeded = 0 -- 0 : échec | 1 : réussite <br />
-- AND start_time BETWEEN '20090907' AND '20090908' <br />
ORDER BY database_name, start_time</div></td></tr></tbody></table></div>
<p>Il est dès lors facile de placer cette requête dans un DataSet sous Reporting Services ou dans une application WinForms pour pouvoir s&rsquo;afficher l&rsquo;état des plans de maintenance qui doivent avoir lieu sur une instance de SQL Server <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[Agent SQL Server] Gestion de l&#8217;historique</title>
		<link>https://blog.developpez.com/elsuket/p6884/moteur-de-base-de-donnees-sql-server/indexation/agent_sql_server_gestion_de_l_historique</link>
		<comments>https://blog.developpez.com/elsuket/p6884/moteur-de-base-de-donnees-sql-server/indexation/agent_sql_server_gestion_de_l_historique#comments</comments>
		<pubDate>Fri, 05 Dec 2008 23:01:50 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>
		<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Outre sa principale fonctionnalité de gestion d&#8217;exécutions, l&#8217;Agent SQL Server comporte quelques fonctionnalités intéressantes concernant la gestion de son historique. Par défaut, l&#8217;historique pour chaque job est configuré à un maximum de 100 lignes, et de 1000 lignes pour tous &#8230; <a href="https://blog.developpez.com/elsuket/p6884/moteur-de-base-de-donnees-sql-server/indexation/agent_sql_server_gestion_de_l_historique">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Outre sa principale fonctionnalité de gestion d&rsquo;exécutions, l&rsquo;Agent SQL Server comporte quelques fonctionnalités intéressantes concernant la gestion de son historique.<br />
<span id="more-23"></span><br />
Par défaut, l&rsquo;historique pour chaque job est configuré à un maximum de 100 lignes, et de 1000 lignes pour tous les jobs.<br />
Donc si votre job s&rsquo;exécute plus de 100 fois par jour, et que vous arrivez au travail en souhaitant voir si celui-ci s&rsquo;est correctement exécuté pendant que vous dormiez paisiblement, c&rsquo;est râpé <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_biggrin.gif" alt=":D" class="wp-smiley" /></p>
<p>En choisissant l&rsquo;option &laquo;&nbsp;Propriétés&nbsp;&raquo; par clic-droit sur la node &laquo;&nbsp;SQL Server Agent&nbsp;&raquo; sous SQL Server Management Studio, voici ce que l&rsquo;on trouve :</p>
<p><img src="http://blog.developpez.com/media/histoAgent1.png" width="704" height="632" alt="" /></p>
<p>Autre désagrément : l&rsquo;historique concernant un job est assez long, par exemple si vous exécutez un job une fois par semaine depuis des mois.<br />
Vous souhaitez maintenant purger l&rsquo;historique, pour voir ce qui se passera la semaine prochaine, d&rsquo;un coup d&rsquo;oeil :</p>
<p><img src="http://blog.developpez.com/media/histoAgent2.png" width="1065" height="636" alt="" /></p>
<p>Vous pouvez également supprimer de l&rsquo;historique les lignes qui sont plus vieilles qu&rsquo;une date de votre choix, avec l&rsquo;option &laquo;&nbsp;Supprimer l&rsquo;historique avant&nbsp;&raquo; :</p>
<p><img src="http://blog.developpez.com/media/histoAgent3.png" width="440" height="368" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
