<?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; Moteur de base de données SQL Server</title>
	<atom:link href="https://blog.developpez.com/elsuket/pcategory/moteur-de-base-de-donnees-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>Vidéos des sessions Data Frogs</title>
		<link>https://blog.developpez.com/elsuket/p13206/moteur-de-base-de-donnees-sql-server/indexation/videos-des-sessions-data-frogs</link>
		<comments>https://blog.developpez.com/elsuket/p13206/moteur-de-base-de-donnees-sql-server/indexation/videos-des-sessions-data-frogs#comments</comments>
		<pubDate>Mon, 05 Apr 2021 07:32:41 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1527</guid>
		<description><![CDATA[Après un long moment d&#8217;absence, je suis revenu en animant une session parmi d&#8217;autres, sur le Query Store. Voici le menu : David Barbarin – Maintenance des statistiques avec SQL Server Nicolas Souquet – Tout savoir sur le Query Store &#8230; <a href="https://blog.developpez.com/elsuket/p13206/moteur-de-base-de-donnees-sql-server/indexation/videos-des-sessions-data-frogs">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Après un long moment d&rsquo;absence, je suis revenu en animant une session parmi d&rsquo;autres, sur le Query Store. Voici le menu :</p>
<p>David Barbarin – Maintenance des statistiques avec SQL Server<br />
Nicolas Souquet – Tout savoir sur le Query Store<br />
Amar Adghar – Azure, quelle architecture pour moi ?<br />
Arian Papillon and Julien Pierre – Les fausses bonnes idées SQL Server<br />
Christophe Laporte – Configurer SQL Server pour un dépannage efficace<br />
Hugo Kornelis – T-SQL User-Defined Functions, or: How to kill performance in one, easy step<br />
Frédéric Brouard – Passer de SQL Server à PostGreSQL &#8230; ou l&rsquo;inverse ?</p>
<p>Les vidéos sont disponibles <a href="https://www.youtube.com/channel/UCd1tirBk4XtjQ_hWZ0uAFrw">ici</a>.<br />
Retrouvez également les scripts que j&rsquo;ai utilisés pour les démos <a href="https://1drv.ms/u/s!Akx83zoei9Kzc4rPEi-GIFYf088?e=Z70fYe">ici</a>.</p>
<p>Bonne visualisation <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>Sortie de SQL Server 2017 : installation !</title>
		<link>https://blog.developpez.com/elsuket/p13153/moteur-de-base-de-donnees-sql-server/indexation/sortie-de-sql-server-2017-installation</link>
		<comments>https://blog.developpez.com/elsuket/p13153/moteur-de-base-de-donnees-sql-server/indexation/sortie-de-sql-server-2017-installation#comments</comments>
		<pubDate>Mon, 02 Oct 2017 19:08:10 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>
		<category><![CDATA[SQL Server 2017]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1481</guid>
		<description><![CDATA[La sortie de SQL Server 2017 marque un tournant majeur pour Microsoft, puisque SQL Server est maintenant disponible sous Linux. Jusqu&#8217;ici, ce n&#8217;était pas le cas, et c&#8217;était très probablement le dernier rempart à l&#8217;adoption de SQL Server dans les &#8230; <a href="https://blog.developpez.com/elsuket/p13153/moteur-de-base-de-donnees-sql-server/indexation/sortie-de-sql-server-2017-installation">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>La sortie de SQL Server 2017 marque un tournant majeur pour Microsoft, puisque SQL Server est maintenant disponible sous Linux. Jusqu&rsquo;ici, ce n&rsquo;était pas le cas, et c&rsquo;était très probablement le dernier rempart à l&rsquo;adoption de SQL Server dans les entreprises où l&rsquo;infrastructure logicielle de Linux/Unix est prépondérante.</p>
<p>Il y a bien d&rsquo;autres éléments qui ont été ajoutés aux fonctionnalités de SQL Server avec ce nouvel opus, que l&rsquo;on peut télécharger à partir de <a href="https://www.microsoft.com/en-us/sql-server/sql-server-downloads">cette page</a>.  Plus bas dans celle-ci, on trouve également les téléchargements de SQL Server Management Studio 2017, SQL Server Data Tools, et les connecteurs pour faire interagir une application avec SQL Server en .NET, Java, mais aussi Python et Ruby.</p>
<p>Notons que depuis SQL Server 2014, l&rsquo;édition <em>Developer</em> de SQL Server est gratuite, ce qui fait qu&rsquo;on peut la télécharger sur nos PCs et commencer à bricoler après quelques minutes d&rsquo;installation, en faisant appel à toutes les possibilités et fonctionnalités du moteur de base de données : l&rsquo;édition Developer, est, en termes de fonctionnalités, équivalente à l&rsquo;édition Enterprise, qui les offre toutes.</p>
<p>Voyons donc ce qu&rsquo;il en est :<br />
<span id="more-1481"></span></p>
<p>A partir de la page, on obtient un petit installeur de 5Mo, et lors de sont exécution, on obtient la fenêtre suivante :</p>
<p><img src="https://i.imgur.com/bG7f0Rh.png" alt="" /></p>
<p>Ici j&rsquo;ai choisi <em>Download Media</em>, puisque c&rsquo;est l&rsquo;option qui me permettra d&rsquo;installer au besoin, avec seulement les fonctionnalités que je souhaite. Nous obtenons alors l&rsquo;écran suivant :</p>
<p><img src="https://i.imgur.com/evxbSsT.png" alt="" /></p>
<p>Plus besoin donc de se soucier du langage, et on peut télécharger selon son envie et l&rsquo;OS, soit sous le format ISO, soit en CAB. Un lien nous permet aussi créer une instance SQL Server dans Azure.</p>
<p>Une fois le tout validé, le téléchargement débute &#8230; et se termine par :</p>
<p><img src="https://i.imgur.com/lasY6a0.png" alt="" /></p>
<p>Un clic sur le bouton <em>Open folder</em> nous amène directement sur le fichier ISO fraîchement téléchargé. A l’exécution de ce dernier, on obtient la fenêtre suivante :</p>
<p><img src="https://i.imgur.com/n6WGnAD.png" alt="" /></p>
<p>A partir de la page <em>Installation</em>, on peut bien sûr démarrer l&rsquo;installation d&rsquo;une instance SQL Server 2017, et ici encore accéder aux pages qui permettent de télécharger la dernière version de SQL Server Management Studio (SSMS) et SQL Server Data Tools (SSDT). Depuis SQL Server 2016, ces outils ne sont en effet plus contenus dans l&rsquo;installeur de SQL Server : ceci permet à l&rsquo;installeur de garder une taille relativement raisonnable (1.4 Go), étant donné que l&rsquo;installeur de SSMS pèse à lui seul près de 800 Mo. </p>
<p>Les différences avec l&rsquo;installation de SQL Server 2016 sont peu nombreuses, mais valent qu&rsquo;on s&rsquo;y arrête : alors que SQL Server 2016 supportait l’apprentissage automatisé avec le langage R, on pouvait installer en plus de SQL Server une instance de <em>R Server</em>. Comme SQL Server 2017 supporte en plus Python pour servir ce même besoin, l&rsquo;installation de <em>R Server</em> a été remplacée dans ce nouvel opus par un <em>Machine Learning Server</em> :</p>
<p><img src="https://i.imgur.com/n6WGnAD.png" alt="" /></p>
<p>Les écrans de clé de produit et de licence demeurent inchangés :</p>
<p><img src="https://i.imgur.com/5vsyssv.png" alt="" /></p>
<p><img src="https://imgur.com/sl2wJEc.png" alt="" /></p>
<p>Idem pour le calcul des règles d&rsquo;installation :</p>
<p><img src="https://imgur.com/IdOmSm4.png" alt="" /></p>
<p><img src="https://imgur.com/qTtZjNJ.png" alt="" /></p>
<p>Nous voici maintenant à la sélection des fonctionnalités à installer : comme vu précédemment, nous pouvons ajouter les fonctionnalités d&rsquo;Apprentissage Automatisé, soit en support de script (<em>Machine-Learning Services (In-Database)</em>), soit en instance dédiée (<em>Machine-Learning Services (Standalone)</em>) et choisir d&rsquo;installer seulement R ou Python. Cocher la case de l&rsquo;une de ces deux fonctionnalités génère une nouvelle page dans la liste à gauche : <em>Consent to install Microsoft R Server/Python</em></p>
<p><img src="https://imgur.com/oAFrYvT.png" alt="" /></p>
<p>L&rsquo;écran de nommage de l&rsquo;instance reste inchangé :</p>
<p><img src="https://imgur.com/2WT9Nd8.png" alt="" /></p>
<p>De même que celui de configuration des services de l&rsquo;instance :</p>
<p><img src="https://imgur.com/8dxreKG.png" alt="" /></p>
<p>L&rsquo;octroi du droit <em>Perform Volume Maintenance Task</em> au compte de service qui exécute SQL Server, introduite avec SQL Server 2016, est toujours bienvenu, et sa description est limpide.</p>
<p>En ce qui concerne la configuration du moteur de base de données, pas de surprise non plus &#8230;</p>
<p><img src="https://imgur.com/Dkzhkbj.png" alt="" /></p>
<p>&#8230; mais on apprécie toujours l&rsquo;onglet qui permet de configurer plusieurs fichiers pour TempDB, introduite avec SQL Server 2016 :</p>
<p><img src="https://imgur.com/SdpqPAO.png" alt="" /></p>
<p>Comme nous l&rsquo;avons vu, l&rsquo;acceptation de la licence pour R Server et Python est requise :</p>
<p><img src="https://imgur.com/tBjZ6gh.png" alt="" /></p>
<p><img src="https://imgur.com/32VFNJS.png" alt="" /></p>
<p>Comme d&rsquo;habitude, un résumé des éléments qui vont être installés s&rsquo;affiche, permettant de revoir le tout avant de cliquer sur le bouton <em>Install</em></p>
<p><img src="https://imgur.com/LpymZlU.png" alt="" /></p>
<p>Et bien sûr, on peut récupérer l&rsquo;emplacement du fichier de configuration de cette installation juste en-dessous du résumé, pour le passer en paramètre à une installation scriptée et silencieuse de SQL Server. Il se trouve toujours dans le répertoire <em>C:\Program Files\Microsoft SQL Server\140\Setup Bootstrap\Log\AAAAMMJJ_HHmmss\ConfigurationFile.ini</em>.</p>
<p>L&rsquo;installation démarre alors, et, si nous avions choisi d&rsquo;installer les fonctionnalités de Machine-Learning, on observera le téléchargement des éléments nécessaires à celles-ci par l&rsquo;utilisation de la bande passante réseau/Internet. Une fois terminée, on peut démarrer <a href="http://blog.developpez.com/elsuket/p13152/sql-server-management-studio/telecharger-sql-server-management-studio-2017-v17-2" title="Télécharger SQL Server Management Studio 2017 (v17.2)"><em>SQL Server Management Studio 17.2</em></a>, et obtenir alors :</p>
<p><img src="https://imgur.com/h3SNsrK.png" alt="" /></p>
<p>Il ne nous reste plus qu&rsquo;à nous amuser avec les nouvelles fonctionnalités de cette version, listées sur <a href="https://docs.microsoft.com/en-us/sql/sql-server/what-s-new-in-sql-server-2017">cette page</a>, et dont les plus marquantes à mon sens sont :</p>
<ul>
<li>Reprise de reconstruction d&rsquo;index en ligne, ce qui permet de la mettre en pause pour la reprendre plus tard</li>
<li>Exécution adaptative des requêtes : adaptation de l&rsquo;algorithme de jointure et feedback sur l&rsquo;octroi de mémoire à l&rsquo;exécution d&rsquo;une requête</li>
<li>Tuning automatisé : détection et correction automatique de régression de performance pour un plan de requête, et création/suppression de doublons d&rsquo;index dans Azure</li>
<li>Ajout du type de données graphe</li>
<li>Groupes de disponibilité AlwaysOn sans cluster</li>
<li>Nouvelles DMVs : sys.dm_db_log_stats, sys.dm_tran_version_store_space_usage, sys.dm_db_log_info et sys.dm_db_stats_histogram</li>
<li>Amélioration du support In-Memory  : colonnes calculées, JSON, CASE et CROSS APPLY</li>
<li>Fonctions de chaîne : CONCAT_WS et TRIM (enfin !)</li>
<li>Et bien sûr le niveau de compatibilité de base de données 140</li>
</ul>
<p>Pour voir les fonctionnalités devenues dépréciées, et notamment celles qui ne seront plus supportées dans la prochaine version de SQL Server (2018 ou 2019 ? les paris sont ouverts ! :)), c&rsquo;est par <a href="https://docs.microsoft.com/en-us/sql/database-engine/deprecated-database-engine-features-in-sql-server-2017">ici</a>.</p>
<p>Bon SQL Server 2017 à tous !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Variables de type table, statistiques et drapeau de trace 2453</title>
		<link>https://blog.developpez.com/elsuket/p13151/moteur-de-base-de-donnees-sql-server/variables-de-type-table-statistiques-et-drapeau-de-trace-2453</link>
		<comments>https://blog.developpez.com/elsuket/p13151/moteur-de-base-de-donnees-sql-server/variables-de-type-table-statistiques-et-drapeau-de-trace-2453#comments</comments>
		<pubDate>Sun, 30 Jul 2017 21:39:01 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[SQL Server 2014]]></category>
		<category><![CDATA[SQL Server 2016]]></category>
		<category><![CDATA[drapeau de trace]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[trace flag]]></category>
		<category><![CDATA[variable de type table]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1409</guid>
		<description><![CDATA[M&#8217;étant arrêté d&#8217;écrire pendant un certain temps, mais certainement pas de lire, me voilà de retour au clavier pour partager sur mon sujet préféré : l&#8217;optimiseur de requêtes, et plus particulièrement l&#8217;estimation de cardinalités. En butinant des billets de blog &#8230; <a href="https://blog.developpez.com/elsuket/p13151/moteur-de-base-de-donnees-sql-server/variables-de-type-table-statistiques-et-drapeau-de-trace-2453">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>M&rsquo;étant arrêté d&rsquo;écrire pendant un certain temps, mais certainement pas de lire, me voilà de retour au clavier pour partager sur mon sujet préféré : l&rsquo;optimiseur de requêtes, et plus particulièrement l&rsquo;estimation de cardinalités. En butinant des billets de blog ici et là à propos de SQL Server, je trouvais un billet détaillant le comportement des requêtes spécifiant des variables de type TABLE.</p>
<p>Qu&rsquo;est-ce que l&rsquo;estimation de cardinalités ? Pour faire très court, c&rsquo;est l&rsquo;ensemble des règles mathématiques qui permettent à SQL Server d&rsquo;avoir une idée assez précise du nombre de lignes qu&rsquo;il aura à traiter lors de l&rsquo;exécution d&rsquo;une requête. C&rsquo;est avec ce calcul-là qu&rsquo;il sélectionne les algorithmes de jointure, de regroupement, l&rsquo;ordre et la façon d&rsquo;accéder aux tables, et bien d&rsquo;autres choses encore. Bien sûr, ces choix varient suivant le volume de données à traiter. On le comprend donc, c&rsquo;est un sujet très important, puisqu&rsquo;il impacte directement les performances de l&rsquo;exécution de nos chères (parfois en IO et temps CPU !) requêtes.</p>
<p>Alors vous allez me dire, crevant d&rsquo;impatience : &laquo;&nbsp;bon d&rsquo;accord, mais il le sort de son chapeau magique ce calcul ?&nbsp;&raquo; : au risque de vous décevoir, non. Dès lors qu&rsquo;on soumet une requête qui filtre une table par une colonne, ou l&rsquo;utilise dans une jointure, un regroupement, alors par défaut, le moteur crée automatiquement des objets de statistique. C&rsquo;est à dire qu&rsquo;il va échantillonner les données des colonnes des tables participant à la requête pour évaluer la distribution des données dans les colonnes (et index) de ces tables. Fort de ces informations, il peut alors réaliser le fameux calcul. Bref, ce sont des mathématiques <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>L&rsquo;auteur du billet en question partageait sur le fait que par défaut, SQL Server estime qu&rsquo;il n&rsquo;y a qu&rsquo;une seule ligne dans une variable de type TABLE. Ceci s&rsquo;explique par le fait que SQL Server ne maintient pas d&rsquo;objet de statistique sur les variables de type TABLE (pour les curieux, il le fait néanmoins sur les <a href="http://blog.developpez.com/elsuket/p7739/moteur-de-base-de-donnees-sql-server/variable_table_temporaire_performance" title="Utilisation des variables de type table ou des tables temporaires, et performances">tables temporaires</a>). Quand on sait l&rsquo;usage qui est fait des variables de type TABLE dans les applications, il est évident qu&rsquo;il arrive rarement que ces tables ne soient en charge que d&rsquo;une seule ligne; de là des performances qui ne sont pas toujours en adéquation avec le volume de données à traiter.</p>
<p>Voyons le comportement par défaut du moteur à l&rsquo;aide de la base de données AdventureWorks2012 :<br />
<span id="more-1409"></span></p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span><br />
GO<br />
<br />
<span style="color: #0000FF;">USE</span> AdventureWorks2012<br />
GO<br />
<br />
<span style="color: #0000FF;">DECLARE</span> @BusinessEntityId <span style="color: #0000FF;">TABLE</span><br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; BusinessEntityID <span style="color: #0000FF;">INT</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
<span style="color: #808080;">&#41;</span>;<br />
&nbsp;<br />
<span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> @BusinessEntityId<br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; BusinessEntityID<br />
<span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; BusinessEntityID<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; Person.<span style="color: #202020;">Person</span>;<br />
&nbsp;<br />
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">STATISTICS</span> IO, <span style="color: #0000FF;">TIME</span>, XML <span style="color: #0000FF;">ON</span><br />
&nbsp;<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">*</span><span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @BusinessEntityId b<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; Person.<span style="color: #202020;">Person</span> p<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> b.<span style="color: #202020;">BusinessEntityID</span> <span style="color: #808080;">=</span> p.<span style="color: #202020;">BusinessEntityID</span>;<br />
<br />
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">STATISTICS</span> IO, <span style="color: #0000FF;">TIME</span>, XML <span style="color: #0000FF;">OFF</span></div></td></tr></tbody></table></div>
<p>L&rsquo;option de session SET STATISTICS nous permet de collecter des métriques IO, temps CPU et durée en millisecondes de la requête. Son option XML expose le <a href="http://blog.developpez.com/elsuket/p12879/moteur-de-base-de-donnees-sql-server/capture-manuelle-de-plans-de-requete" title="Capture manuelle de plans de requête">plan réel de requête</a> en plus du résultat de la requête.  La sortie de ce lot est, tronquée des lectures &laquo;&nbsp;physiques&nbsp;&raquo; (i.e. sur disque et pas en RAM), et des lectures LOB, puisqu&rsquo;il n&rsquo;y en a pas :</p>
<p><em>Table &lsquo;Person&rsquo;. Scan count 0, logical reads 59916<br />
Table &lsquo;#BEF1AB90&prime;. Scan count 1, logical reads 33</p>
<p> SQL Server Execution Times:<br />
   CPU time = 47 ms,  elapsed time = 56 ms.</em></p>
<p>Si l&rsquo;on étudie le plan de requête, voici ce que l&rsquo;on trouve pour notre variable de type TABLE :</p>
<p><img src="http://imgur.com/IyPj2KC.png" alt="" /></p>
<p>Pour voir sur quelle base le moteur a réalisé ses calculs, il suffit de survoler l&rsquo;opérateur <em>Table Scan</em> avec le curseur de la souris :</p>
<p><img src="http://imgur.com/CPy7CtN.png" alt="" /></p>
<p>Le moteur a donc estimé qu&rsquo;il n&rsquo;y qu&rsquo;une seule ligne dans la variable de type TABLE, puis il a exécuté le plan de cette requête. D&rsquo;une certaine manière, il nous avoue s&rsquo;être un peu trompé, puisqu&rsquo;il nous indique qu&rsquo;en réalité, il a lu 19972 lignes.</p>
<p>Mais, à la lecture du résumé l&rsquo;article <a href="https://support.microsoft.com/en-us/help/2952444">2952444</a>, on voit que ce comportement a été corrigé à l&rsquo;aide d&rsquo;un correctif dès SQL Server 2012 SP2 et le CU3 de SQL Server 2014, ce qui fait qu&rsquo;il est dans les RTM des versions suivantes de SQL Server, à ce jour SQL Server 2016 et 2017 (bientôt !) :</p>
<p><em>When you populate a table variable with many rows and then join it with other tables, the query optimizer may choose an inefficient query plan, which may lead to slow query performance.<br />
</em></p>
<p>Voyons donc ce qu&rsquo;il en est : nous rejouons le même lot de requête, mais avec le drapeau de trace activé cette fois :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-- Activation du drapeau de trace 2453 pour toutes</span><br />
<span style="color: #008080;">-- les bases de données que l'instance héberge</span><br />
<span style="color: #0000FF;">DBCC</span> TRACEON <span style="color: #808080;">&#40;</span><span style="color: #000;">2453</span>, <span style="color: #808080;">-</span><span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><br />
GO<br />
<br />
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span><br />
GO<br />
<br />
<span style="color: #0000FF;">USE</span> AdventureWorks2012<br />
GO<br />
<br />
<span style="color: #0000FF;">DECLARE</span> @BusinessEntityId <span style="color: #0000FF;">TABLE</span><br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; BusinessEntityID <span style="color: #0000FF;">INT</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
<span style="color: #808080;">&#41;</span>;<br />
&nbsp;<br />
<span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> @BusinessEntityId<br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; BusinessEntityID<br />
<span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">SELECT</span> &nbsp;BusinessEntityID<br />
<span style="color: #0000FF;">FROM</span> &nbsp; &nbsp;Person.<span style="color: #202020;">Person</span>;<br />
&nbsp;<br />
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">STATISTICS</span> IO, <span style="color: #0000FF;">TIME</span>, XML <span style="color: #0000FF;">ON</span><br />
&nbsp;<br />
<span style="color: #0000FF;">SELECT</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">*</span><span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">FROM</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@BusinessEntityId b<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span> &nbsp; &nbsp; &nbsp;Person.<span style="color: #202020;">Person</span> p<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> b.<span style="color: #202020;">BusinessEntityID</span> <span style="color: #808080;">=</span> p.<span style="color: #202020;">BusinessEntityID</span>;<br />
<br />
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">STATISTICS</span> IO, <span style="color: #0000FF;">TIME</span>, XML <span style="color: #0000FF;">OFF</span></div></td></tr></tbody></table></div>
<p>La sortie est :</p>
<p><em>Table &lsquo;Workfile&rsquo;. Scan count 7, logical reads 64, physical reads 0, read-ahead reads 64<br />
Table &lsquo;Worktable&rsquo;. Scan count 0, logical reads 0<br />
Table &lsquo;Person&rsquo;. Scan count 1, logical reads 67<br />
Table &lsquo;#A96F2843&prime;. Scan count 1, logical reads 33</p>
<p> SQL Server Execution Times:<br />
   CPU time = 31 ms,  elapsed time = 39 ms.</em></p>
<p>Le gain de temps pour une requête aussi simple n&rsquo;est pas négligeable, mais c&rsquo;est surtout le gain en IOs qui est très intéressant ! Voyons ce que nous dit le plan de requête :</p>
<p><img src="http://imgur.com/suEqrcd.png" alt="" /></p>
<p>L&rsquo;ordre d&rsquo;accès aux tables est le même, mais on voit bien que la façon de les traiter a changé : les jointures et agrégats sont exécutés par hachage. On note aussi les avertissements (petit point d&rsquo;exclamation noir dans un triangle jaune) sur ces deux opérateurs : ils ont du accéder à TempDB pour exécuter la jointure et l&rsquo;agrégat, d&rsquo;où les <em>Workfile</em> et <em>Worktable</em> dans la sortie de SET STATISTICS : ce sont des structures créées à la volée dans TempDB, souvent à défaut d&rsquo;index pouvant supporter la requête efficacement.</p>
<p>Voyons ce que nous indique l&rsquo;opérateur <em>Table Scan</em> :</p>
<p><img src="http://imgur.com/JuxVHGM.png" alt="" /></p>
<p>Ici on voit bien que l&rsquo;estimation du nombre de lignes s&rsquo;est faite correctement, et c&rsquo;est donc bien cela qui a conduit le moteur à changer les algorithmes de jointure et de calcul de l&rsquo;agrégat.</p>
<p>Pour ma part, la grande majorité des instances SQL Server que j&rsquo;administre actuellement sont de version 2014, et j&rsquo;ai activé ce drapeau de trace sur toutes celles-ci. En effet, l&rsquo;application qui repose sur cette base de données fait souvent appel à des <em>Tabled-Valued Parameters</em>, qui sont des variables de type table que l&rsquo;on peut passer en paramètre à une procédure stockée ou un appel à la procédure stockée système <em>sp_executesql</em>. Les performances générales de l&rsquo;application s&rsquo;en sont immédiatement ressenti positivement.</p>
<p>Je n&rsquo;irai pas jusqu&rsquo;à écrire qu&rsquo;il faudrait que ce drapeau de trace soit activé sur toute les instances de production, car :</p>
<ol>
<li>toutes les applications et leurs charges de travail sont différentes</li>
<li>il est toujours primordial de tester et de mesurer avant d&rsquo;effectuer un quelconque changement de configuration sur une instance de production</li>
</ol>
<p>Je vous engage vivement donc à tester pour en observer l&rsquo;effet :</p>
<ul>
<li>Pour savoir quels sont les drapeaux de trace actifs, il suffit d&rsquo;exécuter DBCC TRACESTATUS seul, ou si l&rsquo;on veut être plus spécifique : DBCC TRACESTATUS (2453, -1)</li>
<li>Pour désactiver un drapeau de trace, il faut exécuter : DBCC TRACEOFF ({traceFlag}, -1), soit dans le cadre de ce billet : DBCC TRACEOFF (2453, -1)</li>
</ul>
<p>N&rsquo;hésitez pas à me laisser un petit commentaire !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Résoudre les problèmes les plus communs de connexion à SQL Server</title>
		<link>https://blog.developpez.com/elsuket/p13147/moteur-de-base-de-donnees-sql-server/indexation/resoudre-problemes-communs-connexion-a-sql-server</link>
		<comments>https://blog.developpez.com/elsuket/p13147/moteur-de-base-de-donnees-sql-server/indexation/resoudre-problemes-communs-connexion-a-sql-server#comments</comments>
		<pubDate>Wed, 22 Mar 2017 20:23:23 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1396</guid>
		<description><![CDATA[Qui n&#8217;a jamais eu le message d&#8217;erreur suivant ? A network-related or instance-specific error occurred while establishing a connection to SQL Server Login failed for user DOMAIN\user Microsoft vient de publier un guide de résolution de ces erreurs, qui indique &#8230; <a href="https://blog.developpez.com/elsuket/p13147/moteur-de-base-de-donnees-sql-server/indexation/resoudre-problemes-communs-connexion-a-sql-server">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Qui n&rsquo;a jamais eu le message d&rsquo;erreur suivant ?</p>
<ul>
<li>A network-related or instance-specific error occurred while establishing a connection to SQL Server</li>
<li>Login failed for user DOMAIN\user</li>
</ul>
<p>Microsoft vient de publier un <a href="https://support.microsoft.com/fr-fr/help/4009936/solving-connectivity-errors-to-sql-server">guide de résolution</a> de ces erreurs, qui indique les sources du problème et les étapes de résolution.</p>
<p>Bonne connexion(s) !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Redémarrer la trace par défaut</title>
		<link>https://blog.developpez.com/elsuket/p13143/snippets/redemarrer-la-trace-par-defaut</link>
		<comments>https://blog.developpez.com/elsuket/p13143/snippets/redemarrer-la-trace-par-defaut#comments</comments>
		<pubDate>Thu, 02 Mar 2017 08:00:02 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1377</guid>
		<description><![CDATA[SQL Server fournit de nombreux outils de monitoring d&#8217;arrière-plan par défaut, comme le journal SQL Server, la session d&#8217;événements étendus system_health, mais aussi une trace SQL Profiler. Cette dernière est enregistrée dans un fichier dans le répertoire des journaux, et &#8230; <a href="https://blog.developpez.com/elsuket/p13143/snippets/redemarrer-la-trace-par-defaut">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>SQL Server fournit de nombreux outils de monitoring d&rsquo;arrière-plan par défaut, comme le journal SQL Server, la session d&rsquo;événements étendus <em>system_health</em>, mais aussi une trace <em>SQL Profiler</em>. Cette dernière est enregistrée dans un fichier dans le répertoire des journaux, et SQL Server conserve 6 fichiers de cette trace.</p>
<p>Elle capture, entre autres, les événements d&rsquo;échec d&rsquo;authentification, la création d&rsquo;objets dans TempDB, les warnings sur Hash et Sort, les grossissements de fichiers, et de nombreux autres événements. Ceux-ci peuvent aider à comprendre, a posteriori, ce qui a causé une grande consommation de CPU, des latences disque, &#8230;</p>
<p>Comme cette trace est écrite sur disque, il peut malencontreusement arriver que ce dernier devienne plein, provoquant alors l&rsquo;arrêt automatique et forcé de la trace. Ce léger incident (l&rsquo;arrêt de la trace, pas l&rsquo;absence d&rsquo;espace disque libre !) n&rsquo;empêche aucunement l&rsquo;instance de fonctionner, ou au moins d&rsquo;être accessible. Cependant, comment peut-on redémarrer cette trace sans redémarrer l&rsquo;instance SQL Server ?</p>
<p><span id="more-1377"></span></p>
<p>En effet, la documentation nous indique que la trace par défaut n&rsquo;est démarrée que lorsque l&rsquo;instance démarre aussi &#8230; nous allons voir que c&rsquo;est incomplet. Une fois le disque supportant la trace disposant à nouveau d&rsquo;espace disque libre, on constate que la trace par défaut est arrêtée à l&rsquo;aide de l&rsquo;instruction suivante :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">traces</span></div></td></tr></tbody></table></div>
<p>Lorsque la trace par défaut est active, cette requête retourne une ligne, dont la colonne <em>id</em> est à 1. On peut vérifier que c&rsquo;est la trace par défaut à l&rsquo;aide de la valeur de la colonne <em>is_default</em> : 1 si c&rsquo;est le cas, 0 à l&rsquo;inverse :</p>
<p><img src="http://i.imgur.com/msPoxLS.png" alt="" /></p>
<p>Dans la situation de l&rsquo;incident que nous évoquons, cette même requête ne retournera pas de ligne (ou tout du moins aucune dont la colonne <em>is_default</em> est à 1). Pour démarrer la trace par défaut, il suffit de s&rsquo;en remettre à l&rsquo;option de configuration d&rsquo;instance <em>default trace enabled</em> :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">configurations</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; name <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'%trace%'</span></div></td></tr></tbody></table></div>
<p><img src="http://i.imgur.com/swPu4gE.png" alt="" /></p>
<p>On voit que c&rsquo;est une option avancée et dynamique, ce qui signifie qu&rsquo;un redémarrage de l&rsquo;instance SQL Server n&rsquo;est pas nécessaire. Dès lors, pour réactiver la trace par défaut, il suffit de positionner cette option à 0, puis immédiatement ensuite à 1, ce qui est sa valeur par défaut :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-- Activation de la modification des options d'instance avancées</span><br />
<span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'show advanced options'</span>, <span style="color: #000;">1</span><br />
GO<br />
<span style="color: #0000FF;">RECONFIGURE</span><br />
GO<br />
<br />
<span style="color: #008080;">-- Désactivation de la trace par défaut</span><br />
<span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'default trace enabled'</span>, <span style="color: #000;">0</span><br />
GO<br />
<span style="color: #0000FF;">RECONFIGURE</span><br />
GO<br />
<br />
<span style="color: #008080;">-- Ré-activation de la trace par défaut</span><br />
<span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'default trace enabled'</span>, <span style="color: #000;">1</span><br />
GO<br />
<span style="color: #0000FF;">RECONFIGURE</span><br />
GO<br />
<br />
<span style="color: #008080;">-- Désactivation de la modification des options d'instance avancées</span><br />
<span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'show advanced options'</span>, <span style="color: #000;">0</span><br />
GO<br />
<span style="color: #0000FF;">RECONFIGURE</span><br />
GO</div></td></tr></tbody></table></div>
<p>Sur exécution de ce lot, l&rsquo;onglet <em>Messages</em> du panneau de résultats de <em>SQL Server Management Studio</em> affiche :</p>
<p><em>Configuration option &lsquo;show advanced options&rsquo; changed from 0 to 1. Run the RECONFIGURE statement to install.<br />
Configuration option &lsquo;default trace enabled&rsquo; changed from 1 to 0. Run the RECONFIGURE statement to install.<br />
Configuration option &lsquo;default trace enabled&rsquo; changed from 0 to 1. Run the RECONFIGURE statement to install.<br />
Configuration option &lsquo;show advanced options&rsquo; changed from 1 to 0. Run the RECONFIGURE statement to install.</em></p>
<p>Et l&rsquo;on voit alors que la trace a été démarrée, en interrogeant une nouvelle fois la vue <em>sys.traces</em>.<br />
On trouvera aussi dans les journal de SQL Server les lignes suivantes :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-- Recherche de l'heure de dernier démarrage de l'instance SQL Server</span><br />
<span style="color: #0000FF;">SELECT</span> sqlserver_start_time <span style="color: #0000FF;">FROM</span> sys.<span style="color: #202020;">dm_os_sys_info</span><br />
<br />
<span style="color: #008080;">-- Recherche du démarrage de la trace par défaut</span><br />
<span style="color: #0000FF;">EXEC</span> xp_readerrorlog <span style="color: #000;">0</span>, <span style="color: #000;">1</span>, N<span style="color: #FF0000;">'Trace ID 1'</span></div></td></tr></tbody></table></div>
<p><img src="http://i.imgur.com/e2rFeEt.png" alt="" /></p>
<p>Ici on voit bien que la trace par défaut a été démarré par le système (le SPID est inférieur à 50), quelques millisecondes après le démarrage de celui-ci. Elle a ensuite été redémarrée par nos soins un peu plus tard.</p>
<p>Petite note finale : les fonctionnalités <em>SQL Trace</em> et <em>SQL Profiler</em> sont obsolètes, et remplacées par la fonctionnalité d&#039;<a href="http://blog.developpez.com/elsuket/p11065/moteur-de-base-de-donnees-sql-server/evenements_etendus_sql_server_2008" title="Les Événements Étendus avec SQL Server 2008" target="_blank">événements étendus</a>, plus puissante et performante. Vous pouvez voir comment les utiliser dans <a href="http://blog.developpez.com/elsuket/p13085/moteur-de-base-de-donnees-sql-server/evenements-etendus/troubleshooting-avec-les-evenements-etendus-en-video" title="Troubleshooting avec les événements étendus en vidéo" target="_blank">cette vidéo</a>, en gardant bien à l&rsquo;esprit que dès SQL Server 2012, une interface graphique intégrée à <em>SQL Server Management Studio</em> permet de créer une session sans écrire de code, et de visualiser les événements capturés à la façon de ce que permet SQL Profiler.</p>
<p>Enfin, pour interroger un fichier de trace SQL Profiler, il suffit d&rsquo;utiliser la fonction <a href="https://msdn.microsoft.com/en-us/library/ms188425.aspx"><em>sys.fn_trace_gettable()</em></a>. Donc pour en faire l&rsquo;analyse, on peut utiliser le lot suivant :</p>
<div class="codecolorer-container tsql 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 />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">DECLARE</span> @events <span style="color: #0000FF;">TABLE</span><br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; event_id <span style="color: #0000FF;">tinyint</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , event_name sysname<br />
<span style="color: #808080;">&#41;</span><br />
<br />
<span style="color: #0000FF;">INSERT</span> @events <span style="color: #0000FF;">VALUES</span> <span style="color: #808080;">&#40;</span><span style="color: #000;">0</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">1</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">2</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">3</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">4</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">5</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">6</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">7</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">8</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">9</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">10</span>, <span style="color: #FF0000;">'RPC:Completed'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">11</span>, <span style="color: #FF0000;">'RPC:Starting'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">12</span>, <span style="color: #FF0000;">'SQL:BatchCompleted'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">13</span>, <span style="color: #FF0000;">'SQL:BatchStarting'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">14</span>, <span style="color: #FF0000;">'Audit Login'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">15</span>, <span style="color: #FF0000;">'Audit Logout'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">16</span>, <span style="color: #FF0000;">'Attention'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">17</span>, <span style="color: #FF0000;">'ExistingConnection'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">18</span>, <span style="color: #FF0000;">'Audit Server Starts and Stops'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">19</span>, <span style="color: #FF0000;">'DTCTransaction'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">20</span>, <span style="color: #FF0000;">'Audit Login Failed'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">21</span>, <span style="color: #FF0000;">'EventLog'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">22</span>, <span style="color: #FF0000;">'ErrorLog'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">23</span>, <span style="color: #FF0000;">'Lock:Released'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">24</span>, <span style="color: #FF0000;">'Lock:Acquired'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">25</span>, <span style="color: #FF0000;">'Lock:Deadlock'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">26</span>, <span style="color: #FF0000;">'Lock:Cancel'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">27</span>, <span style="color: #FF0000;">'Lock:Timeout'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">28</span>, <span style="color: #FF0000;">'Degree of Parallelism Event (7.0 Insert)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">29</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">30</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">31</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">32</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">33</span>, <span style="color: #FF0000;">'Exception'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">34</span>, <span style="color: #FF0000;">'SP:CacheMiss'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">35</span>, <span style="color: #FF0000;">'SP:CacheInsert'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">36</span>, <span style="color: #FF0000;">'SP:CacheRemove'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">37</span>, <span style="color: #FF0000;">'SP:Recompile'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">38</span>, <span style="color: #FF0000;">'SP:CacheHit'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">39</span>, <span style="color: #FF0000;">'Deprecated'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">40</span>, <span style="color: #FF0000;">'SQL:StmtStarting'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">41</span>, <span style="color: #FF0000;">'SQL:StmtCompleted'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">42</span>, <span style="color: #FF0000;">'SP:Starting'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">43</span>, <span style="color: #FF0000;">'SP:Completed'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">44</span>, <span style="color: #FF0000;">'SP:StmtStarting'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">45</span>, <span style="color: #FF0000;">'SP:StmtCompleted'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">46</span>, <span style="color: #FF0000;">'Object:Created'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">47</span>, <span style="color: #FF0000;">'Object:Deleted'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">48</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">49</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">50</span>, <span style="color: #FF0000;">'SQL Transaction'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">51</span>, <span style="color: #FF0000;">'Scan:Started'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">52</span>, <span style="color: #FF0000;">'Scan:Stopped'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">53</span>, <span style="color: #FF0000;">'CursorOpen'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">54</span>, <span style="color: #FF0000;">'TransactionLog'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">55</span>, <span style="color: #FF0000;">'Hash Warning'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">56</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">57</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">58</span>, <span style="color: #FF0000;">'Auto Stats'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">59</span>, <span style="color: #FF0000;">'Lock:Deadlock Chain'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">60</span>, <span style="color: #FF0000;">'Lock:Escalation'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">61</span>, <span style="color: #FF0000;">'OLE DB Errors'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">62</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">63</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">64</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">65</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">66</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">67</span>, <span style="color: #FF0000;">'Execution Warnings'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">68</span>, <span style="color: #FF0000;">'Showplan Text (Unencoded)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">69</span>, <span style="color: #FF0000;">'Sort Warnings'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">70</span>, <span style="color: #FF0000;">'CursorPrepare'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">71</span>, <span style="color: #FF0000;">'Prepare SQL'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">72</span>, <span style="color: #FF0000;">'Exec Prepared SQL'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">73</span>, <span style="color: #FF0000;">'Unprepare SQL'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">74</span>, <span style="color: #FF0000;">'CursorExecute'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">75</span>, <span style="color: #FF0000;">'CursorRecompile'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">76</span>, <span style="color: #FF0000;">'CursorImplicitConversion'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">77</span>, <span style="color: #FF0000;">'CursorUnprepare'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">78</span>, <span style="color: #FF0000;">'CursorClose'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">79</span>, <span style="color: #FF0000;">'Missing Column Statistics'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">80</span>, <span style="color: #FF0000;">'Missing Join Predicate'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">81</span>, <span style="color: #FF0000;">'Server Memory Change'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">82</span>, <span style="color: #FF0000;">'User Configurable (0-9)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">83</span>, <span style="color: #FF0000;">'User Configurable (0-9)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">84</span>, <span style="color: #FF0000;">'User Configurable (0-9)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">85</span>, <span style="color: #FF0000;">'User Configurable (0-9)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">86</span>, <span style="color: #FF0000;">'User Configurable (0-9)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">87</span>, <span style="color: #FF0000;">'User Configurable (0-9)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">88</span>, <span style="color: #FF0000;">'User Configurable (0-9)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">89</span>, <span style="color: #FF0000;">'User Configurable (0-9)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">90</span>, <span style="color: #FF0000;">'User Configurable (0-9)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">91</span>, <span style="color: #FF0000;">'User Configurable (0-9)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">92</span>, <span style="color: #FF0000;">'Data File Auto Grow'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">93</span>, <span style="color: #FF0000;">'Log File Auto Grow'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">94</span>, <span style="color: #FF0000;">'Data File Auto Shrink'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">95</span>, <span style="color: #FF0000;">'Log File Auto Shrink'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">96</span>, <span style="color: #FF0000;">'Showplan Text'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">97</span>, <span style="color: #FF0000;">'Showplan All'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">98</span>, <span style="color: #FF0000;">'Showplan Statistics Profile'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">99</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">100</span>, <span style="color: #FF0000;">'RPC Output Parameter'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">101</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">102</span>, <span style="color: #FF0000;">'Audit Statement GDR Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">103</span>, <span style="color: #FF0000;">'Audit Object GDR Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">104</span>, <span style="color: #FF0000;">'Audit AddLogin Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">105</span>, <span style="color: #FF0000;">'Audit Login GDR Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">106</span>, <span style="color: #FF0000;">'Audit Login Change Property Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">107</span>, <span style="color: #FF0000;">'Audit Login Change Password Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">108</span>, <span style="color: #FF0000;">'Audit Add Login to Server Role Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">109</span>, <span style="color: #FF0000;">'Audit Add DB User Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">110</span>, <span style="color: #FF0000;">'Audit Add Member to DB Role Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">111</span>, <span style="color: #FF0000;">'Audit Add Role Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">112</span>, <span style="color: #FF0000;">'Audit App Role Change Password Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">113</span>, <span style="color: #FF0000;">'Audit Statement Permission Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">114</span>, <span style="color: #FF0000;">'Audit Schema Object Access Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">115</span>, <span style="color: #FF0000;">'Audit Backup/Restore Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">116</span>, <span style="color: #FF0000;">'Audit DBCC Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">117</span>, <span style="color: #FF0000;">'Audit Change Audit Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">118</span>, <span style="color: #FF0000;">'Audit Object Derived Permission Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">119</span>, <span style="color: #FF0000;">'OLEDB Call Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">120</span>, <span style="color: #FF0000;">'OLEDB QueryInterface Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">121</span>, <span style="color: #FF0000;">'OLEDB DataRead Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">122</span>, <span style="color: #FF0000;">'Showplan XML'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">123</span>, <span style="color: #FF0000;">'SQL:FullTextQuery'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">124</span>, <span style="color: #FF0000;">'Broker:Conversation'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">125</span>, <span style="color: #FF0000;">'Deprecation Announcement'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">126</span>, <span style="color: #FF0000;">'Deprecation Final Support'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">127</span>, <span style="color: #FF0000;">'Exchange Spill Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">128</span>, <span style="color: #FF0000;">'Audit Database Management Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">129</span>, <span style="color: #FF0000;">'Audit Database Object Management Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">130</span>, <span style="color: #FF0000;">'Audit Database Principal Management Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">131</span>, <span style="color: #FF0000;">'Audit Schema Object Management Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">132</span>, <span style="color: #FF0000;">'Audit Server Principal Impersonation Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">133</span>, <span style="color: #FF0000;">'Audit Database Principal Impersonation Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">134</span>, <span style="color: #FF0000;">'Audit Server Object Take Ownership Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">135</span>, <span style="color: #FF0000;">'Audit Database Object Take Ownership Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">136</span>, <span style="color: #FF0000;">'Broker:Conversation Group'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">137</span>, <span style="color: #FF0000;">'Blocked Process Report'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">138</span>, <span style="color: #FF0000;">'Broker:Connection'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">139</span>, <span style="color: #FF0000;">'Broker:Forwarded Message Sent'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">140</span>, <span style="color: #FF0000;">'Broker:Forwarded Message Dropped'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">141</span>, <span style="color: #FF0000;">'Broker:Message Classify'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">142</span>, <span style="color: #FF0000;">'Broker:Transmission'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">143</span>, <span style="color: #FF0000;">'Broker:Queue Disabled'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">144</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">145</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">146</span>, <span style="color: #FF0000;">'Showplan XML Statistics Profile'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">148</span>, <span style="color: #FF0000;">'Deadlock Graph'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">149</span>, <span style="color: #FF0000;">'Broker:Remote Message Acknowledgement'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">150</span>, <span style="color: #FF0000;">'Trace File Close'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">151</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">152</span>, <span style="color: #FF0000;">'Audit Change Database Owner'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">153</span>, <span style="color: #FF0000;">'Audit Schema Object Take Ownership Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">154</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">155</span>, <span style="color: #FF0000;">'FT:Crawl Started'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">156</span>, <span style="color: #FF0000;">'FT:Crawl Stopped'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">157</span>, <span style="color: #FF0000;">'FT:Crawl Aborted'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">158</span>, <span style="color: #FF0000;">'Audit Broker Conversation'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">159</span>, <span style="color: #FF0000;">'Audit Broker Login'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">160</span>, <span style="color: #FF0000;">'Broker:Message Undeliverable'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">161</span>, <span style="color: #FF0000;">'Broker:Corrupted Message'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">162</span>, <span style="color: #FF0000;">'User Error Message'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">163</span>, <span style="color: #FF0000;">'Broker:Activation'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">164</span>, <span style="color: #FF0000;">'Object:Altered'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">165</span>, <span style="color: #FF0000;">'Performance statistics'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">166</span>, <span style="color: #FF0000;">'SQL:StmtRecompile'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">167</span>, <span style="color: #FF0000;">'Database Mirroring State Change'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">168</span>, <span style="color: #FF0000;">'Showplan XML For Query Compile'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">169</span>, <span style="color: #FF0000;">'Showplan All For Query Compile'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">170</span>, <span style="color: #FF0000;">'Audit Server Scope GDR Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">171</span>, <span style="color: #FF0000;">'Audit Server Object GDR Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">172</span>, <span style="color: #FF0000;">'Audit Database Object GDR Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">173</span>, <span style="color: #FF0000;">'Audit Server Operation Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">175</span>, <span style="color: #FF0000;">'Audit Server Alter Trace Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">176</span>, <span style="color: #FF0000;">'Audit Server Object Management Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">177</span>, <span style="color: #FF0000;">'Audit Server Principal Management Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">178</span>, <span style="color: #FF0000;">'Audit Database Operation Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">180</span>, <span style="color: #FF0000;">'Audit Database Object Access Event'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">181</span>, <span style="color: #FF0000;">'TM: Begin Tran starting'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">182</span>, <span style="color: #FF0000;">'TM: Begin Tran completed'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">183</span>, <span style="color: #FF0000;">'TM: Promote Tran starting'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">184</span>, <span style="color: #FF0000;">'TM: Promote Tran completed'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">185</span>, <span style="color: #FF0000;">'TM: Commit Tran starting'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">186</span>, <span style="color: #FF0000;">'TM: Commit Tran completed'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">187</span>, <span style="color: #FF0000;">'TM: Rollback Tran starting'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">188</span>, <span style="color: #FF0000;">'TM: Rollback Tran completed'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">189</span>, <span style="color: #FF0000;">'Lock:Timeout (timeout &amp;gt; 0)'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">190</span>, <span style="color: #FF0000;">'Progress Report: Online Index Operation'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">191</span>, <span style="color: #FF0000;">'TM: Save Tran starting'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">192</span>, <span style="color: #FF0000;">'TM: Save Tran completed'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">193</span>, <span style="color: #FF0000;">'Background Job Error'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">194</span>, <span style="color: #FF0000;">'OLEDB Provider Information'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">195</span>, <span style="color: #FF0000;">'Mount Tape'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">196</span>, <span style="color: #FF0000;">'Assembly Load'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">197</span>, <span style="color: #FF0000;">'Reserved'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">198</span>, <span style="color: #FF0000;">'XQuery Static Type'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">199</span>, <span style="color: #FF0000;">'QN: subscription'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">200</span>, <span style="color: #FF0000;">'QN: parameter table'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">201</span>, <span style="color: #FF0000;">'QN: template'</span><span style="color: #808080;">&#41;</span><br />
, <span style="color: #808080;">&#40;</span><span style="color: #000;">202</span>, <span style="color: #FF0000;">'QN: dynamics'</span><span style="color: #808080;">&#41;</span><br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FTG.<span style="color: #202020;">DatabaseName</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , E.<span style="color: #202020;">event_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , FTG.<span style="color: #202020;">ApplicationName</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">*</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> occurences<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">MIN</span><span style="color: #808080;">&#40;</span>FTG.<span style="color: #202020;">StartTime</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> first_time<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#40;</span>FTG.<span style="color: #202020;">StartTime</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> last_time<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , FTG.<span style="color: #202020;">SessionLoginName</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , E.<span style="color: #202020;">event_id</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #AF0000;">fn_trace_gettable</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">path</span>, <span style="color: #FF00FF;">LEN</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">path</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">-</span> <span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'\'</span>, <span style="color: #FF00FF;">REVERSE</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">path</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'\Log.trc'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">traces</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; is_default <span style="color: #808080;">=</span> <span style="color: #000;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #000;">6</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> FTG<br />
<span style="color: #0000FF;">LEFT</span> <span style="color: #808080;">JOIN</span> &nbsp; &nbsp; &nbsp; @events <span style="color: #0000FF;">AS</span> E<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> E.<span style="color: #202020;">event_id</span> <span style="color: #808080;">=</span> FTG.<span style="color: #202020;">EventClass</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FTG.<span style="color: #202020;">EventClass</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">BETWEEN</span> <span style="color: #000;">65527</span> <span style="color: #808080;">AND</span> <span style="color: #000;">65528</span><br />
<span style="color: #0000FF;">GROUP</span> <span style="color: #0000FF;">BY</span>&nbsp; &nbsp; &nbsp; &nbsp; FTG.<span style="color: #202020;">DatabaseName</span>, E.<span style="color: #202020;">event_name</span>, FTG.<span style="color: #202020;">ApplicationName</span>, E.<span style="color: #202020;">event_id</span>, FTG.<span style="color: #202020;">SessionLoginName</span><br />
<span style="color: #0000FF;">ORDER</span> <span style="color: #0000FF;">BY</span>&nbsp; &nbsp; &nbsp; &nbsp; first_time</div></td></tr></tbody></table></div>
<p>Alors bon traçage à tous !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Retrouver les séquences attachées à des contraintes de valeur par défaut</title>
		<link>https://blog.developpez.com/elsuket/p13120/moteur-de-base-de-donnees-sql-server/indexation/retrouver-les-sequences-attachees-a-des-contraintes-de-valeur-par-defaut</link>
		<comments>https://blog.developpez.com/elsuket/p13120/moteur-de-base-de-donnees-sql-server/indexation/retrouver-les-sequences-attachees-a-des-contraintes-de-valeur-par-defaut#comments</comments>
		<pubDate>Mon, 26 Dec 2016 17:13:06 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1369</guid>
		<description><![CDATA[SQL Server 2012 a introduit les objets SEQUENCE. Ils permettent, en outre, de spécifier des contraintes de valeur par défaut. Ils vont aussi remplacer la propriété d&#8217;auto-incrémentation typiquement utilisée pour les colonnes supportant des contraintes de clé primaire subrogée. Dès &#8230; <a href="https://blog.developpez.com/elsuket/p13120/moteur-de-base-de-donnees-sql-server/indexation/retrouver-les-sequences-attachees-a-des-contraintes-de-valeur-par-defaut">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>SQL Server 2012 a introduit <a href="http://blog.developpez.com/elsuket/p11008/t-sql/sql_server_2012_sequence" title="Tout savoir sur SEQUENCE avec SQL Server 2012" target="_blank">les objets SEQUENCE</a>.<br />
Ils permettent, en outre, de spécifier des contraintes de valeur par défaut. Ils vont aussi remplacer la propriété d&rsquo;auto-incrémentation typiquement utilisée pour les colonnes supportant des contraintes de clé primaire subrogée.</p>
<p>Dès lors, comment retrouver les séquences référencées par de telles contraintes ? Voici un exemple et une petite requête pour nous y aider &#8230;<br />
<span id="more-1369"></span></p>
<p>Pour l&rsquo;exemple, supposons la séquence et la table suivantes :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">USE</span> ELSUKET<br />
GO<br />
<br />
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">SEQUENCE</span> dbo.<span style="color: #202020;">seq_user</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">int</span><br />
<span style="color: #0000FF;">START</span> <span style="color: #0000FF;">WITH</span> <span style="color: #808080;">-</span><span style="color: #000;">2147483648</span> <span style="color: #808080;">IN</span>CREMENT <span style="color: #0000FF;">BY</span> <span style="color: #000;">1</span> ;<br />
GO<br />
&nbsp;<br />
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> t_user<br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; id <span style="color: #0000FF;">int</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CONSTRAINT</span> PK_t_user <span style="color: #0000FF;">PRIMARY</span> <span style="color: #0000FF;">KEY</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CONSTRAINT</span> DF_t_user__id <span style="color: #0000FF;">DEFAULT</span> <span style="color: #808080;">&#40;</span><span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">VALUE</span> <span style="color: #0000FF;">FOR</span> dbo.<span style="color: #202020;">seq_user</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , name <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">32</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CONSTRAINT</span> UQ_t_user__name <span style="color: #0000FF;">UNIQUE</span><br />
<span style="color: #808080;">&#41;</span></div></td></tr></tbody></table></div>
<p>Il est nécessaire d&rsquo;utiliser la fonction de gestion dynamique <em>sys.dm_sql_referencing_entities()</em> pour retrouver les caractéristiques de la contrainte :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #FF00FF;">QUOTENAME</span><span style="color: #808080;">&#40;</span>SCHEMA_NAME<span style="color: #808080;">&#40;</span>T.<span style="color: #202020;">schema_id</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.'</span> <span style="color: #808080;">+</span> <span style="color: #FF00FF;">QUOTENAME</span><span style="color: #808080;">&#40;</span>T.<span style="color: #202020;">name</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> table_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">QUOTENAME</span><span style="color: #808080;">&#40;</span>DC.<span style="color: #202020;">name</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> default_constraint_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">QUOTENAME</span><span style="color: #808080;">&#40;</span>SCHEMA_NAME<span style="color: #808080;">&#40;</span>SQ.<span style="color: #202020;">schema_id</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.'</span> <span style="color: #808080;">+</span> <span style="color: #FF00FF;">QUOTENAME</span><span style="color: #808080;">&#40;</span>SQ.<span style="color: #202020;">name</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> sequence_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF0000;">'ALTER TABLE '</span> <span style="color: #808080;">+</span> <span style="color: #FF00FF;">QUOTENAME</span><span style="color: #808080;">&#40;</span>SCHEMA_NAME<span style="color: #808080;">&#40;</span>T.<span style="color: #202020;">schema_id</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.'</span> <span style="color: #808080;">+</span> <span style="color: #FF00FF;">QUOTENAME</span><span style="color: #808080;">&#40;</span>T.<span style="color: #202020;">name</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">' DROP CONSTRAINT '</span> <span style="color: #808080;">+</span> <span style="color: #FF00FF;">QUOTENAME</span><span style="color: #808080;">&#40;</span>DC.<span style="color: #202020;">name</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> sql_drop_constraint<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">sequences</span> <span style="color: #0000FF;">AS</span> SQ<br />
<span style="color: #808080;">CROSS</span> APPLY &nbsp; &nbsp; sys.<span style="color: #202020;">dm_sql_referencing_entities</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">QUOTENAME</span><span style="color: #808080;">&#40;</span>SCHEMA_NAME<span style="color: #808080;">&#40;</span>SQ.<span style="color: #202020;">schema_id</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.'</span> <span style="color: #808080;">+</span> <span style="color: #FF00FF;">QUOTENAME</span><span style="color: #808080;">&#40;</span>SQ.<span style="color: #202020;">name</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF0000;">'OBJECT'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> RE<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">default_constraints</span> <span style="color: #0000FF;">AS</span> DC<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> RE.<span style="color: #202020;">referencing_id</span> <span style="color: #808080;">=</span> DC.<span style="color: #FF00FF;">object_id</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">tables</span> <span style="color: #0000FF;">AS</span> T<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> T.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> DC.<span style="color: #202020;">parent_object_id</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; T.<span style="color: #202020;">name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'t_user'</span></div></td></tr></tbody></table></div>
<p>ce qui donne :</p>
<p><img src="http://i.imgur.com/0zS4TTc.png" alt="" /></p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server 2016 Service Pack 1 : monumentale mise à jour !</title>
		<link>https://blog.developpez.com/elsuket/p13119/moteur-de-base-de-donnees-sql-server/sql-server-2016-service-pack-1-monumentale-mise-a-jour</link>
		<comments>https://blog.developpez.com/elsuket/p13119/moteur-de-base-de-donnees-sql-server/sql-server-2016-service-pack-1-monumentale-mise-a-jour#comments</comments>
		<pubDate>Wed, 23 Nov 2016 08:00:47 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[SQL Server 2016]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1351</guid>
		<description><![CDATA[La sortie du Service Pack 1 pour SQL Server 2016 est venue avec une annonce pour le moins inattendue : de nombreuses fonctionnalités jusqu&#8217;ici réservées à l&#8217;édition Enterprise le sont maintenant dans les éditions Standard, Express, et même LocalDB. La &#8230; <a href="https://blog.developpez.com/elsuket/p13119/moteur-de-base-de-donnees-sql-server/sql-server-2016-service-pack-1-monumentale-mise-a-jour">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>La sortie du Service Pack 1 pour SQL Server 2016 est venue avec une annonce pour le moins inattendue : de nombreuses fonctionnalités jusqu&rsquo;ici réservées à l&rsquo;édition <em>Enterprise</em> le sont maintenant dans les éditions <em>Standard</em>, <em>Express</em>, et même <em>LocalDB</em>.</p>
<p><span id="more-1351"></span></p>
<p>La table suivante décrit ce changement de façon plus visuelle : le moins qu&rsquo;on puisse dire, c&rsquo;est qu&rsquo;elle s&rsquo;est éclairci avec ce Service Pack !</p>
<p><img src="http://i.imgur.com/Viyy4ne.png" alt="" /></p>
<p>Mêmes les fonctionnalités introduites avec SQL Server 2016 RTM <em>Enterprise</em> ont été élargies aux autres éditions. Ceci permet bien sûr de programmer de façon plus uniforme, en ayant moins recours à la vérification de l&rsquo;édition. C&rsquo;est tout à fait avantageux pour les éditeurs de logiciels, mais aussi pour les scripts de maintenance, notamment PowerShell, qui devraient donc compter moins de <em>if</em> une fois toutes les bases de données migrées vers cette version (ce qui n&rsquo;est pas une mince affaire :)). Mon seul regret ira peut-être à la reconstruction d&rsquo;index en ligne, mais c&rsquo;est un choix qui se justifie si l&rsquo;on se place de l&rsquo;autre côté du comptoir.</p>
<p>Pour avoir une vue plus complète, voici <a href="https://www.microsoft.com/en-us/sql-server/sql-server-editions">la page de comparaison des éditions de SQL Server 2016 SP1</a>.</p>
<p>Ceci étant, c&rsquo;est d&rsquo;abord une excellente nouvelle, quoique la littérature actuelle sur ce sujet en dise du fait des limitations suivantes pour les index ColumnStore et les tables optimisées en mémoire (InMemory OLTP) :</p>
<ul>
<li>un quart de la quantité de RAM allouée à SQL Server</li>
<li>degré de parallélisation maximal : 2 cores</li>
</ul>
<p>Mais ne serait-ce que pour la sécurité des données, les fonctionnalités introduites avec SQL Server 2016 RTM sont bienvenues dans l&rsquo;édition <em>Standard</em> en SP1. Ensuite ces deux fonctionnalités limitées couvrent des cas d&rsquo;utilisation très courants, comme l&rsquo;analytique simple que l&rsquo;on développe pour une application OLTP, ou encore les variables de type TABLE et autres tables temporaires que l&rsquo;on peut tenter de déplacer en InMemory pour alléger la charge d&rsquo;IOs disque de TempDB.</p>
<p>Mais bien sûr ce n&rsquo;est pas Black Friday tous les jours, donc il faut aussi voir ce qui justifie toujours l&rsquo;achat d&rsquo;une édition <em>Enterprise</em> ou <em>Standard</em> de SQL Server 2016 SP1 :</p>
<ul>
<li>L&rsquo;Agent SQL Server n&rsquo;est pas porté aux éditions <em>Express</em> et <em>LocalDB</em>;</li>
<li>La parallélisation n&rsquo;est pas disponible dans ces deux mêmes éditions;</li>
<li>ALTER INDEX &#8230; REBUILD WITH (ONLINE = ON) est toujours réservé à l&rsquo;édition <em>Enterprise</em>;</li>
<li>Les groupes de disponibilité AlwaysOn prennent tout leur sens sous l&rsquo;édition <em>Enterprise</em>; autrement, cela s&rsquo;apparente à de la mise en mirroir;</li>
<li>La prise en compte à chaud de CPU et de RAM additionnels est réservé à l&rsquo;édition <em>Enterprise</em>;</li>
<li>Le cryptage (<em>Transparent Data Encryption</em>) avec ou sans EKM (<em>Extensible Key Management</em>, qui permet de déplacer la gestion des clés à un petit serveur spécialisé (<em>Hardware Security Module</em>)) reste une fonctionnalité <em>Enterprise</em>;</li>
<li>Le cryptage et la compression des sauvegardes n&rsquo;est pas disponible en édition <em>Express</em> ou <em>LocalDB</em>;</li>
<li>La quantité de RAM est toujours limitée à 128Go pour une édition <em>Standard</em>, quand l&rsquo;<em>Enterprise</em> est à 24 To (!!!);</li>
</ul>
<p>Pas grand chose de choquant donc, si ce n&rsquo;est peut-être le dernier élément de cette liste : l&rsquo;écart entre <em>Enterprise</em> et <em>Standard</em> frise le gouffre. Ceci est accentué lorsqu&rsquo;on trouve des PC portables disposant de 32 voire 64Go de RAM. On peut donc avoir bonne espérance que cette limite sera repoussée dans un avenir relativement proche.</p>
<p>Dès lors il est simple de voir que le volume de licences <em>Standard</em> de SQL Server 2016 va forcément augmenter, sans pour autant marcher sur les plates-bandes de celui de l&rsquo;édition <em>Enterprise</em>.</p>
<p>En ce qui concerne la consolidation du code à travers les éditions, nous les verrons dans un prochain billet.</p>
<p>Bonne migration vers SQL Server 2016 SP1 à tous !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Sentry Plan Explorer Pro maintenant entièrement gratuit</title>
		<link>https://blog.developpez.com/elsuket/p13106/moteur-de-base-de-donnees-sql-server/indexation/sql-sentry-plan-explorer-pro-maintenant-entierement-gratuit</link>
		<comments>https://blog.developpez.com/elsuket/p13106/moteur-de-base-de-donnees-sql-server/indexation/sql-sentry-plan-explorer-pro-maintenant-entierement-gratuit#comments</comments>
		<pubDate>Fri, 09 Sep 2016 08:00:31 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1344</guid>
		<description><![CDATA[On ne présente plus l’incontournable outil SQL Sentry Plan Explorer, que j&#8217;avais introduit ici et détaillé là. SQL Sentry a annoncé hier que le fabuleux outil qui facilite grandement la lecture de plans de requête, SQL Sentry Plan Explorer, est &#8230; <a href="https://blog.developpez.com/elsuket/p13106/moteur-de-base-de-donnees-sql-server/indexation/sql-sentry-plan-explorer-pro-maintenant-entierement-gratuit">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>On ne présente plus l’incontournable outil SQL Sentry Plan Explorer, que j&rsquo;avais introduit <a href="http://blog.developpez.com/elsuket/p10724/utilitaires/sql_sentry_plan_explorer" title="Analyse de plans de requête : SQL Sentry Plan Explorer">ici</a> et détaillé <a href="http://blog.developpez.com/elsuket/p12879/moteur-de-base-de-donnees-sql-server/capture-manuelle-de-plans-de-requete" title="Capture manuelle de plans de requête">là</a>.</p>
<p>SQL Sentry a annoncé hier que le fabuleux outil qui facilite grandement la lecture de plans de requête, SQL Sentry Plan Explorer, est maintenant gratuit dans son édition Pro.<br />
Jusqu&rsquo;ici, l&rsquo;édition Express était déjà un bel outil, qui est maintenant complété par :</p>
<ul>
<li>L&rsquo;ouverture de plusieurs documents de plan de requête (fichiers .sqlplan, .queryanalysis, .pesession)</li>
<li>L&rsquo;historique et ses commentaires au fur et à mesure du processus d&rsquo;optimisation</li>
<li>L&rsquo;ouverture des graphes décrivant un deadlock (fichiers de type .xdl)</li>
<li>La comparaison de l&rsquo;impact des index pour une même requête</li>
<li>L&rsquo;aide à l&rsquo;analyse de la distribution des valeurs dans un objet de statistique</li>
</ul>
<p>Bonne analyse de plans !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>sys.dm_exec_query_profiles : la DMV qui détaille les noeuds d&#8217;un plan d&#8217;exécution réel</title>
		<link>https://blog.developpez.com/elsuket/p13089/moteur-de-base-de-donnees-sql-server/indexation/sys-dm_exec_query_profiles-la-dmv-qui-detaille-les-noeuds-dun-plan-dexecution-reel</link>
		<comments>https://blog.developpez.com/elsuket/p13089/moteur-de-base-de-donnees-sql-server/indexation/sys-dm_exec_query_profiles-la-dmv-qui-detaille-les-noeuds-dun-plan-dexecution-reel#comments</comments>
		<pubDate>Tue, 09 Aug 2016 08:00:57 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[SQL Server 2014]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1266</guid>
		<description><![CDATA[La lecture du plan d&#8217;exécution réel peut s&#8217;avérer être une tâche laborieuse, surtout lorsque le plan contient de nombreux opérateurs ou nœuds. Introduite avec SQL Server 2014, la vue de gestion dynamique sys.dm_exec_query_profiles nous permet de voir quel(s) nœud(s) d&#8217;un &#8230; <a href="https://blog.developpez.com/elsuket/p13089/moteur-de-base-de-donnees-sql-server/indexation/sys-dm_exec_query_profiles-la-dmv-qui-detaille-les-noeuds-dun-plan-dexecution-reel">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>La lecture du plan d&rsquo;exécution réel peut s&rsquo;avérer être une tâche laborieuse, surtout lorsque le plan contient de nombreux opérateurs ou nœuds.</p>
<p>Introduite avec SQL Server 2014, la vue de gestion dynamique <em>sys.dm_exec_query_profiles</em> nous permet de voir quel(s) nœud(s) d&rsquo;un <a href="http://blog.developpez.com/elsuket/p12879/moteur-de-base-de-donnees-sql-server/capture-manuelle-de-plans-de-requete" title="Capture manuelle de plans de requête">plan d&rsquo;exécution réel</a> consomme le plus de ressources et /ou de temps. C&rsquo;est donc un formidable outil qui peut faire largement diminuer la recherche des points noueux d&rsquo;une requête à l&rsquo;étude.</p>
<p><span id="more-1266"></span></p>
<p><a href="https://msdn.microsoft.com/en-us/library/dn223301.aspx">La documentation</a> de cette DMV montre qu&rsquo;elle expose de nombreuses colonnes, qui nous renseignent de façon très précise sur la consommation de ressources physiques de chaque opérateur du plan de requête, notamment avec le nombre de millisecondes après lequel un opérateur s&rsquo;est exécuté pour la première et la dernière fois. Pour simplifier l&rsquo;analyse des requêtes, on peut s&rsquo;en tenir à quelques unes d&rsquo;entre-elles, comme dans la requête suivante :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; physical_operator_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; , node_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , elapsed_time_ms<br />
&nbsp; &nbsp; &nbsp; &nbsp; , cpu_time_ms<br />
&nbsp; &nbsp; &nbsp; &nbsp; , row_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , estimate_row_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , logical_read_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , rewind_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , rebind_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , end_of_scan_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , scan_count<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_exec_query_profiles</span></div></td></tr></tbody></table></div>
<p>La colonne <em>node_id</em> nous donne le numéro de l&rsquo;opérateur dans le plan de requête. Il faut noter que l&rsquo;opérateur racine de l&rsquo;arbre de résolution qu&rsquo;est le plan de requête, et qui se situe en haut et à gauche dans le plan d&rsquo;exécution graphique, est le seul dans tout plan à ne pas porter de <em>NodeID</em>. L&rsquo;opérateur qui le précède porte le <em>NodeID</em> 0, et celui qui précède ce dernier le <em>NodeID</em> 1, et ainsi de suite. Le plus grand numéro de <em>NodeID</em> est à l&rsquo;opérateur qui est le plus à droite et en bas du plan d&rsquo;exécution graphique.</p>
<p>La colonne <em>session_id</em> va nous permettre de spécifier sur quelle session porte notre étude : pour que cette vue expose des lignes, il est nécessaire que l&rsquo;option de session SET STATISTICS XML soit positionnée à ON pour la requête à étudier. Ceci équivaut à l&rsquo;activation de l&rsquo;option d&rsquo;inclusion du plan d&rsquo;exécution réel dans la barre d&rsquo;outil de SQL Server Management Studio (SSMS) avant l&rsquo;exécution d&rsquo;une requête. Ceci est normal, puisque comme pour toutes les tâches de monitoring, elle viennent avec un coût : celui-ci pourrait devenir trop élevé si toutes les requêtes étaient auditées à ce niveau de détail, d&rsquo;autant que ce type d&rsquo;information est utilisé par les DBAs, et pas par les applications qui interagissent avec la base de données.</p>
<p>Supposons que la requête (très simple) que l&rsquo;on souhaite étudier est la suivante :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Sales.<span style="color: #202020;">SalesOrderDetail</span> <span style="color: #0000FF;">AS</span> SOD<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; Production.<span style="color: #202020;">Product</span> <span style="color: #0000FF;">AS</span> P<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> SOD.<span style="color: #202020;">ProductID</span> <span style="color: #808080;">=</span> P.<span style="color: #202020;">ProductID</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; P.<span style="color: #202020;">ListPrice</span> <span style="color: #808080;">&amp;</span>gt; <span style="color: #000;">1000</span></div></td></tr></tbody></table></div>
<p>On peut récupérer le session_id de plusieurs manières :</p>
<ul>
<li>Il est indiqué dans la barre d&rsquo;état de toute fenêtre de requête sous SSMS, en bas à droite;</li>
<li>Si l&rsquo;on a conservé les options par défaut de SSMS, il est aussi indiqué sur l&rsquo;onglet de la fenêtre de requête;</li>
<li>On peut exécuter SELECT @@SPID dans la même fenêtre de requête que celle à étudier.</li>
</ul>
<p><img src="http://i.imgur.com/JLFuhns.png" alt="" /></p>
<p>Ne soyez pas perturbé par l&rsquo;option de session <em>SET STATISTICS IO, TIME ON</em> positionné juste avant la requête : je l&rsquo;utilise toujours pour diagnostiquer une requête, car cela expose le temps CPU, la durée totale, et surtout, le nombre d&rsquo;IOs produit par la requête pour chaque table participant à celle-ci. On peut adjoindre l&rsquo;option <em>XML</em> à la liste <em>IO, TIME</em> si on le souhaite.</p>
<p>Les lecteurs aux yeux affûtés auront remarqué que dans la capture d&rsquo;écran ci-dessus, il y a un deuxième onglet ouvert : en effet, on doit utiliser une fenêtre de requête pour celle à étudier, et une autre pour lire la sortie de la vue <em>sys.dm_exec_query_profiles</em> pour cette session. Pour cet exemple, on peut reprendre la première requête, et rajouter la clause WHERE adéquate : la session qui va exécuter la requête à l&rsquo;étude porte le <em>session_id</em> 51 :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; physical_operator_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; , node_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , elapsed_time_ms<br />
&nbsp; &nbsp; &nbsp; &nbsp; , cpu_time_ms<br />
&nbsp; &nbsp; &nbsp; &nbsp; , row_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , estimate_row_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , logical_read_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , rewind_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , rebind_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , end_of_scan_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , scan_count<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_exec_query_profiles</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; session_id <span style="color: #808080;">=</span> <span style="color: #000;">51</span> <span style="color: #008080;">-- session_id de la requête à l'étude</span></div></td></tr></tbody></table></div>
<p>L&rsquo;exercice consiste donc à démarrer l&rsquo;exécution de la requête à l&rsquo;étude, puis à basculer vers la fenêtre de requête qui spécifie la vue <em>sys.dm_exec_query_profiles</em> avant la fin de l&rsquo;exécution de la requête à l&rsquo;étude. Pour la requête de cet exemple, cela nous donne :</p>
<p><img src="http://i.imgur.com/FJozDlw.png" alt="" /></p>
<p>On constate ainsi des écarts importants entre le nombre de lignes estimé et réel pour les opérateurs dont le <em>NodeID</em> est 0 et 4, mais il y a un problème : alors que la somme des valeurs de la colonne <em>elapsed_time_ms</em> nous donne 15, la sortie dans l&rsquo;onglet <em>Messages</em> est la suivante (légèrement écourtée, notamment les IOs physiques et de LOBs, pour les besoins de l&rsquo;article) :</p>
<blockquote><p>(29382 row(s) affected)<br />
Table &lsquo;Workfile&rsquo;. Scan count 0, logical reads 0<br />
Table &lsquo;Worktable&rsquo;. Scan count 0, logical reads 0<br />
Table &lsquo;SalesOrderDetail&rsquo;. Scan count 1, logical reads 1246<br />
Table &lsquo;Product&rsquo;. Scan count 1, logical reads 15</p>
<p> SQL Server Execution Times:<br />
   CPU time = 156 ms,  elapsed time = <strong>1225</strong> ms.</p></blockquote>
<p>Il y a bien sûr le temps de consommation du jeu de lignes de résultat par SSMS. On peut le confirmer en éliminant le résultat une fois la requête exécutée : pour ce faire, il suffit de faire un clic-droit dans un zone vierge de la requête &gt; <em>Query options</em> &#8230; &gt; <em>Results</em> / <em>Grid</em> &gt; et de cocher la case <em>Discard results after execution</em>.</p>
<p>La question qui vient maintenant est : comment faire pour les requêtes dont l&rsquo;exécution est bien plus longue ? Et dans tous les cas, la durée d&rsquo;exécution des requêtes n&rsquo;étant pas précisément prédictible même après une ou deux exécutions, comment capturer les valeurs qu&rsquo;expose cette DMV en s&rsquo;approchant le plus possible de la fin de la requête ? On peut pour cela écrire une boucle qui va stocker le contenu de la DMV à intervalles réguliers et fréquents, et qui vérifie à chaque tour que la requête est toujours en cours d&rsquo;exécution :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span><br />
GO<br />
<br />
<span style="color: #0000FF;">DECLARE</span> @session_id <span style="color: #0000FF;">int</span> <span style="color: #808080;">=</span> <span style="color: #000;">51</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @delay <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">8</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'00:00:00.010'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @i <span style="color: #0000FF;">int</span> <span style="color: #808080;">=</span> <span style="color: #000;">1</span><br />
<br />
<span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'TempDB.dbo.#query_profile_global'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DROP</span> <span style="color: #0000FF;">TABLE</span> #query_profile_global<br />
<br />
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> #query_profile_global<br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; physical_operator_name <span style="color: #0000FF;">nvarchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">256</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , node_id <span style="color: #0000FF;">int</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , elapsed_time_ms <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , cpu_time_ms <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , row_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , estimate_row_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , logical_read_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , rewind_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , rebind_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , end_of_scan_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">object_name</span> sysname <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , index_name sysname <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , scan_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , time_stamp <span style="color: #0000FF;">datetime</span> <span style="color: #808080;">NULL</span><br />
<span style="color: #808080;">&#41;</span><br />
<br />
<span style="color: #0000FF;">DECLARE</span> @query_profile <span style="color: #0000FF;">TABLE</span><br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; physical_operator_name <span style="color: #0000FF;">nvarchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">256</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , node_id <span style="color: #0000FF;">int</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , elapsed_time_ms <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , cpu_time_ms <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , row_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , estimate_row_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , logical_read_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , rewind_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , rebind_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , end_of_scan_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">object_name</span> sysname <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , index_name sysname <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , scan_count <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , time_stamp <span style="color: #0000FF;">datetime</span> <span style="color: #808080;">NULL</span><br />
<span style="color: #808080;">&#41;</span><br />
<br />
<span style="color: #0000FF;">WHILE</span> <span style="color: #808080;">EXISTS</span><br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_exec_requests</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; session_id <span style="color: #808080;">=</span> @session_id<br />
<span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INTO</span> @query_profile<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QP.<span style="color: #202020;">physical_operator_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , QP.<span style="color: #202020;">node_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , QP.<span style="color: #202020;">elapsed_time_ms</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , QP.<span style="color: #202020;">cpu_time_ms</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , QP.<span style="color: #202020;">row_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , QP.<span style="color: #202020;">estimate_row_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , QP.<span style="color: #202020;">logical_read_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , QP.<span style="color: #202020;">rewind_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , QP.<span style="color: #202020;">rebind_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , QP.<span style="color: #202020;">end_of_scan_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , O.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> <span style="color: #FF00FF;">object_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , I.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> index_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , QP.<span style="color: #202020;">scan_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> time_stamp<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_exec_query_profiles</span> <span style="color: #0000FF;">AS</span> QP<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">LEFT</span> <span style="color: #808080;">JOIN</span> &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">objects</span> <span style="color: #0000FF;">AS</span> O<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> QP.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> O.<span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">LEFT</span> <span style="color: #808080;">JOIN</span> &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">indexes</span> <span style="color: #0000FF;">AS</span> I<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> QP.<span style="color: #202020;">index_id</span> <span style="color: #808080;">=</span> I.<span style="color: #202020;">index_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> QP.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> I.<span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; QP.<span style="color: #202020;">session_id</span> <span style="color: #808080;">=</span> @session_id <span style="color: #008080;">-- spid running query</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> @i <span style="color: #808080;">=</span> <span style="color: #000;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> #query_profile_global<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; @query_profile<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">UPDATE</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #query_profile_global<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; physical_operator_name <span style="color: #808080;">=</span> QP.<span style="color: #202020;">physical_operator_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , node_id <span style="color: #808080;">=</span> QP.<span style="color: #202020;">node_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , elapsed_time_ms <span style="color: #808080;">=</span> QP.<span style="color: #202020;">elapsed_time_ms</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , cpu_time_ms <span style="color: #808080;">=</span> QP.<span style="color: #202020;">cpu_time_ms</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , row_count <span style="color: #808080;">=</span> QP.<span style="color: #202020;">row_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , estimate_row_count <span style="color: #808080;">=</span> QP.<span style="color: #202020;">estimate_row_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , logical_read_count <span style="color: #808080;">=</span> QP.<span style="color: #202020;">logical_read_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , rewind_count <span style="color: #808080;">=</span> QP.<span style="color: #202020;">rewind_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , rebind_count <span style="color: #808080;">=</span> QP.<span style="color: #202020;">rebind_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , end_of_scan_count <span style="color: #808080;">=</span> QP.<span style="color: #202020;">end_of_scan_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">object_name</span> <span style="color: #808080;">=</span> QP.<span style="color: #FF00FF;">object_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , index_name <span style="color: #808080;">=</span> QP.<span style="color: #202020;">index_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , scan_count <span style="color: #808080;">=</span> QP.<span style="color: #202020;">scan_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , time_stamp <span style="color: #808080;">=</span> QP.<span style="color: #202020;">time_stamp</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @query_profile <span style="color: #0000FF;">AS</span> QP<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; #query_profile_global <span style="color: #0000FF;">AS</span> QFG<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> QFG.<span style="color: #202020;">node_id</span> <span style="color: #808080;">=</span> QP.<span style="color: #202020;">node_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WAITFOR</span> DELAY @delay<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DELETE</span> <span style="color: #0000FF;">FROM</span> @query_profile<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @i <span style="color: #808080;">+=</span> <span style="color: #000;">1</span><br />
<span style="color: #0000FF;">END</span><br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #0000FF;">DISTINCT</span> <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; #query_profile_global<br />
<span style="color: #0000FF;">ORDER</span> &nbsp; <span style="color: #0000FF;">BY</span> node_id<br />
<span style="color: #008080;">--ORDER BY elapsed_time_ms DESC</span></div></td></tr></tbody></table></div>
<p>Ici on stocke le contenu de la DMV toutes les 10 ms. Le délai entre chaque boucle peut être adapté : si l&rsquo;on sait que la requête dure environ quart d&rsquo;heure, une récupération du contenu de la vue toutes les secondes est suffisante. Cette valeur peut donc être adaptée suivant la durée d&rsquo;exécution globale de la requête. Il faut aussi veiller à exécuter ce lot de requêtes dans le même contexte de base de données que celui sous lequel on exécute la requête à étudier. En effet, cela permet d&rsquo;obtenir le nom de l&rsquo;objet de base de données accédé :</p>
<p><img src="http://i.imgur.com/vdDfdkK.png" /></p>
<p>On constate dans la sortie du lot de requêtes interrogeant la DMV que, par exemple, l&rsquo;opérateur de <em>NodeID</em> 4 est l&rsquo;accès à l&rsquo;index cluster de la table <em>SalesOrderDetail</em>, et qu&rsquo;il a traité 121317 lignes. Voyons si cela est reflété par le plan d&rsquo;exécution réel graphique de la requête :</p>
<p><img src="http://i.imgur.com/Z6l9xMA.png" alt="" /></p>
<p>Le numéro de <em>NodeID</em> 4 est bien l&rsquo;opérateur exposé par la DMV, et si l&rsquo;on lit la ligne de la bulle dont le libellé est <em>Actual number of rows</em>, on a bien 121317.</p>
<p>Pour l&rsquo;étude des requêtes plus lourdes, la DMV <em>sys.dm_exec_query_profiles</em> nous permettra de repérer immédiatement les opérateurs les plus consommateurs de ressources, et donc de travailler directement sur ceux-ci en se reportant au plan de requête, puis à la requête elle-même pour en revoir l&rsquo;écriture et éventuellement l&rsquo;indexation.</p>
<p>Bonne optimisation !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Les nouveautés de l&#8217;optimiseur de SQL Server 2016</title>
		<link>https://blog.developpez.com/elsuket/p13088/moteur-de-base-de-donnees-sql-server/les-nouveautes-de-loptimiseur-de-sql-server-2016</link>
		<comments>https://blog.developpez.com/elsuket/p13088/moteur-de-base-de-donnees-sql-server/les-nouveautes-de-loptimiseur-de-sql-server-2016#comments</comments>
		<pubDate>Wed, 03 Aug 2016 20:28:29 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Annonces]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1310</guid>
		<description><![CDATA[Avec la sortie de SQL Server 2016, sous le mode de compatibilité des bases de données à 130, les corrections et ajouts sont listés dans ce billet officiel. On notera comme très bienvenues : le fait de ne plus avoir &#8230; <a href="https://blog.developpez.com/elsuket/p13088/moteur-de-base-de-donnees-sql-server/les-nouveautes-de-loptimiseur-de-sql-server-2016">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Avec la sortie de SQL Server 2016, sous le mode de compatibilité des bases de données à 130, les corrections et ajouts sont listés dans ce <a href="https://blogs.msdn.microsoft.com/sqlserverstorageengine/2016/05/23/query-optimizer-additions-in-sql-server/">billet officiel</a>.</p>
<p>On notera comme très bienvenues :</p>
<ul>
<li>le fait de ne plus avoir à activer le drapeau de trace 2371 pour voir le ré-échantillonnage des statistiques de colonnes et d&rsquo;index se faire lorsque la table a subi 20% du nombre de ses lignes en affectation</li>
<li>le drapeau de trace est l&rsquo;un de ceux qu&rsquo;on n&rsquo;ose pas activer, parce qu&rsquo;il peut être bénéfique à certaines requêtes et pas à d&rsquo;autres : sous le mode de compatibilité 130, ce sera le cas par défaut</li>
<li>la parallélisation de la mise à jour des statistiques échantillonnées, qui vient compléter avantageusement celles qui ne l&rsquo;étaient pas (FULLSCAN)</li>
</ul>
<p>Bonne lecture et optimisation de requêtes !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comment voir le contenu complet d&#8217;une colonne de type [n]varchar(max)</title>
		<link>https://blog.developpez.com/elsuket/p13087/moteur-de-base-de-donnees-sql-server/indexation/comment-voir-le-contenu-complet-dune-colonne-de-type-nvarcharmax</link>
		<comments>https://blog.developpez.com/elsuket/p13087/moteur-de-base-de-donnees-sql-server/indexation/comment-voir-le-contenu-complet-dune-colonne-de-type-nvarcharmax#comments</comments>
		<pubDate>Wed, 03 Aug 2016 08:00:33 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>
		<category><![CDATA[SQL Server Management Studio]]></category>
		<category><![CDATA[contenu]]></category>
		<category><![CDATA[intégral]]></category>
		<category><![CDATA[SLQ Server Management Studio]]></category>
		<category><![CDATA[SMSS]]></category>
		<category><![CDATA[texte]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1287</guid>
		<description><![CDATA[S&#8217;apercevoir, alors que l&#8217;on vient de coller une valeur d&#8217;une colonne du résultat d&#8217;une requête dans SQL Server Management Studio, que le buffer est limité, est quelque peu frustrant. On peut parfois dépasser cette limite en se rendant dans le &#8230; <a href="https://blog.developpez.com/elsuket/p13087/moteur-de-base-de-donnees-sql-server/indexation/comment-voir-le-contenu-complet-dune-colonne-de-type-nvarcharmax">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>S&rsquo;apercevoir, alors que l&rsquo;on vient de coller une valeur d&rsquo;une colonne du résultat d&rsquo;une requête dans SQL Server Management Studio, que le buffer est limité, est quelque peu frustrant.<br />
On peut parfois dépasser cette limite en se rendant dans le menu Tools &gt; Options &gt; Query Results &gt; SLQ Server &gt; Results to Grid :</p>
<p><img src="http://i.imgur.com/E7x5Ysi.png" alt="" /></p>
<p>Mais souvent, cela ne suffit pas. Voyons comment contourner ce petit problème :</p>
<p><span id="more-1287"></span></p>
<p>Pour les besoins de la démonstration, créons une petite table, avec une pile d&rsquo;exécution. C&rsquo;est ce que l&rsquo;on trouve parfois dans les bases de données lorsque celles-ci sont dédiées à une seule application et écrit les erreurs rencontrées directement dans une table :</p>
<div class="codecolorer-container tsql 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 />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br />230<br />231<br />232<br />233<br />234<br />235<br />236<br />237<br />238<br />239<br />240<br />241<br />242<br />243<br />244<br />245<br />246<br />247<br />248<br />249<br />250<br />251<br />252<br />253<br />254<br />255<br />256<br />257<br />258<br />259<br />260<br />261<br />262<br />263<br />264<br />265<br />266<br />267<br />268<br />269<br />270<br />271<br />272<br />273<br />274<br />275<br />276<br />277<br />278<br />279<br />280<br />281<br />282<br />283<br />284<br />285<br />286<br />287<br />288<br />289<br />290<br />291<br />292<br />293<br />294<br />295<br />296<br />297<br />298<br />299<br />300<br />301<br />302<br />303<br />304<br />305<br />306<br />307<br />308<br />309<br />310<br />311<br />312<br />313<br />314<br />315<br />316<br />317<br />318<br />319<br />320<br />321<br />322<br />323<br />324<br />325<br />326<br />327<br />328<br />329<br />330<br />331<br />332<br />333<br />334<br />335<br />336<br />337<br />338<br />339<br />340<br />341<br />342<br />343<br />344<br />345<br />346<br />347<br />348<br />349<br />350<br />351<br />352<br />353<br />354<br />355<br />356<br />357<br />358<br />359<br />360<br />361<br />362<br />363<br />364<br />365<br />366<br />367<br />368<br />369<br />370<br />371<br />372<br />373<br />374<br />375<br />376<br />377<br />378<br />379<br />380<br />381<br />382<br />383<br />384<br />385<br />386<br />387<br />388<br />389<br />390<br />391<br />392<br />393<br />394<br />395<br />396<br />397<br />398<br />399<br />400<br />401<br />402<br />403<br />404<br />405<br />406<br />407<br />408<br />409<br />410<br />411<br />412<br />413<br />414<br />415<br />416<br />417<br />418<br />419<br />420<br />421<br />422<br />423<br />424<br />425<br />426<br />427<br />428<br />429<br />430<br />431<br />432<br />433<br />434<br />435<br />436<br />437<br />438<br />439<br />440<br />441<br />442<br />443<br />444<br />445<br />446<br />447<br />448<br />449<br />450<br />451<br />452<br />453<br />454<br />455<br />456<br />457<br />458<br />459<br />460<br />461<br />462<br />463<br />464<br />465<br />466<br />467<br />468<br />469<br />470<br />471<br />472<br />473<br />474<br />475<br />476<br />477<br />478<br />479<br />480<br />481<br />482<br />483<br />484<br />485<br />486<br />487<br />488<br />489<br />490<br />491<br />492<br />493<br />494<br />495<br />496<br />497<br />498<br />499<br />500<br />501<br />502<br />503<br />504<br />505<br />506<br />507<br />508<br />509<br />510<br />511<br />512<br />513<br />514<br />515<br />516<br />517<br />518<br />519<br />520<br />521<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> dbo.<span style="color: #202020;">application_log</span><br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; log_label <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">max</span><span style="color: #808080;">&#41;</span><br />
<span style="color: #808080;">&#41;</span><br />
GO<br />
<br />
<span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> dbo.<span style="color: #202020;">application_log</span><br />
<span style="color: #0000FF;">VALUES</span> <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'[ERROR] org.springframework.boot.context.embedded.tomcat.TomcatStarter - Error starting Tomcat context: org.springframework.beans.factory.BeanCreationException<br />
[WARN] org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt<br />
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at de.sveri.mct.Application.main(Application.java:72) [main/:na]<br />
Caused by: org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:98) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.(TomcatEmbeddedServletContainer.java:75) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:378) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:155) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:157) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 5 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:209) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:165) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:160) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:143) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.(ServletContextInitializerBeans.java:74) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:234) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:221) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:84) [spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:206) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:54) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5156) ~[tomcat-embed-core-8.0.23.jar:8.0.23]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ~[tomcat-embed-core-8.0.23.jar:8.0.23]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409) ~[tomcat-embed-core-8.0.23.jar:8.0.23]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399) ~[tomcat-embed-core-8.0.23.jar:8.0.23]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_25]<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:649) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 34 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:164) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.evaluateBeanDefinitionString(AbstractBeanFactory.java:1365) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:957) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:606) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 36 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:523) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:512) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.security.config.annotation.web.configuration.AutowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers(AutowiredWebSecurityConfigurersIgnoreParents.java:52) ~[spring-security-config-4.0.1.RELEASE.jar:4.0.1.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:112) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:161) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 40 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 62 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 64 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 75 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1477) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1222) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 77 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:444) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 90 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 98 common frames omitted<br />
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1249) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:120) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:860) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 105 common frames omitted<br />
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: de.sveri.mct.domain.Topic.topic, referenced property unknown: de.sveri.mct.domain.Topic.topic<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:160) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1697) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 113 common frames omitted<br />
[ERROR] org.springframework.boot.SpringApplication - Application startup failed<br />
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at de.sveri.mct.Application.main(Application.java:72) [main/:na]<br />
Caused by: org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:98) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.(TomcatEmbeddedServletContainer.java:75) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:378) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:155) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:157) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 5 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:209) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:165) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:160) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:143) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.(ServletContextInitializerBeans.java:74) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:234) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:221) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:84) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:206) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:54) ~[spring-boot-1.2.4.RELEASE.jar:1.2.4.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5156) ~[tomcat-embed-core-8.0.23.jar:8.0.23]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) ~[tomcat-embed-core-8.0.23.jar:8.0.23]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409) ~[tomcat-embed-core-8.0.23.jar:8.0.23]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399) ~[tomcat-embed-core-8.0.23.jar:8.0.23]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_25]<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:649) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 34 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:164) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.evaluateBeanDefinitionString(AbstractBeanFactory.java:1365) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:957) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:606) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 36 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:523) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:512) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.security.config.annotation.web.configuration.AutowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers(AutowiredWebSecurityConfigurersIgnoreParents.java:52) ~[spring-security-config-4.0.1.RELEASE.jar:4.0.1.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_25]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:112) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242) ~[spring-expression-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:161) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 40 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 62 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 64 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 75 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1477) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1222) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 77 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:444) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 90 common frames omitted<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 98 common frames omitted<br />
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1249) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:120) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:860) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318) ~[spring-orm-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 105 common frames omitted<br />
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: de.sveri.mct.domain.Topic.topic, referenced property unknown: de.sveri.mct.domain.Topic.topic<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:160) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1697) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846) ~[hibernate-core-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857) ~[hibernate-entitymanager-4.3.10.Final.jar:4.3.10.Final]<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 113 common frames omitted<br />
Exception in thread &quot;main&quot; org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at de.sveri.mct.Application.main(Application.java:72)<br />
Caused by: org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:98)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.(TomcatEmbeddedServletContainer.java:75)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:378)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:155)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:157)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 5 more<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:368)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:209)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:165)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:160)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:143)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.ServletContextInitializerBeans.(ServletContextInitializerBeans.java:74)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getServletContextInitializerBeans(EmbeddedWebApplicationContext.java:234)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.selfInitialize(EmbeddedWebApplicationContext.java:221)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.access$000(EmbeddedWebApplicationContext.java:84)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext$1.onStartup(EmbeddedWebApplicationContext.java:206)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.boot.context.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:54)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5156)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1409)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1399)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.util.concurrent.FutureTask.run(FutureTask.java:266)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.lang.Thread.run(Thread.java:745)<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:649)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 34 more<br />
Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:164)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.evaluateBeanDefinitionString(AbstractBeanFactory.java:1365)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:957)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:606)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 36 more<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'securityConfiguration'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:523)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:512)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.security.config.annotation.web.configuration.AutowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers(AutowiredWebSecurityConfigurersIgnoreParents.java:52)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at java.lang.reflect.Method.invoke(Method.java:483)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:112)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:342)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:161)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 40 more<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService de.sveri.mct.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 62 more<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userDetailsService'</span><span style="color: #FF0000;">': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1210)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 64 more<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private de.sveri.mct.repository.UserRepository de.sveri.mct.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 75 more<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'userRepository'</span><span style="color: #FF0000;">': Cannot create inner bean '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property '</span><span style="color: #FF0000;">'entityManager'</span><span style="color: #FF0000;">'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:313)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:129)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1477)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1222)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 77 more<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'(inner bean)#58e814e6'</span><span style="color: #FF0000;">': Cannot resolve reference to bean '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:444)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 90 more<br />
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '</span><span style="color: #FF0000;">'entityManagerFactory'</span><span style="color: #FF0000;">' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 98 more<br />
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1249)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:120)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:860)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 105 more<br />
Caused by: org.hibernate.AnnotationException: Unknown mappedBy in: de.sveri.mct.domain.Topic.topic, referenced property unknown: de.sveri.mct.domain.Topic.topic<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.OneToOneSecondPass.doSecondPass(OneToOneSecondPass.java:160)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1697)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)<br />
&nbsp; &nbsp; &nbsp; &nbsp; at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857)<br />
&nbsp; &nbsp; &nbsp; &nbsp; ... 113 more<br />
Disconnected from the target VM, address: '</span><span style="color: #FF0000;">'127.0.0.1:54986'</span><span style="color: #FF0000;">', transport: '</span><span style="color: #FF0000;">'socket'</span><span style="color: #FF0000;">'<br />
<br />
Process finished with exit code 1'</span><span style="color: #808080;">&#41;</span><br />
GO</div></td></tr></tbody></table></div>
<p>Consultons maintenant la longueur de cette chaîne :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; DATALENGTH<span style="color: #808080;">&#40;</span>log_label<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> byte_length<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; dbo.<span style="color: #202020;">application_log</span></div></td></tr></tbody></table></div>
<p>Nous obtenons 111640. Si nous exécutons maintenant :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; log_label<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; dbo.<span style="color: #202020;">application_log</span></div></td></tr></tbody></table></div>
<p>Puis que l&rsquo;on réalise un copier-coller de la valeur dans une nouvelle fenêtre de requête, nous allons voir que nous n&rsquo;obtenons pas l&rsquo;intégralité du texte :</p>
<p><img src="http://i.imgur.com/2OAf2Ps.png" alt="" /></p>
<p>On a remarqué cependant que les documents XML, notamment les plans de requête, sont récupérables dans leur intégralité, alors que ce sont généralement des documents sont relativement longs. Tentons donc :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>log_label <span style="color: #0000FF;">AS</span> XML<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> log_label<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; dbo.<span style="color: #202020;">application_log</span></div></td></tr></tbody></table></div>
<p>Ceci se termine directement avec l&rsquo;erreur suivante affichée dans la console :</p>
<blockquote><p>Msg 9400, Level 16, State 1, Line 526<br />
XML parsing: line 513, character 33, unexpected end of input</p></blockquote>
<p>Si l&rsquo;on en vient cependant à utiliser le marqueur de section texte CDATA, qui échappe l&rsquo;interprétation XML du document considéré, on obtient :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">''</span> <span style="color: #0000FF;">AS</span> xml<span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; dbo.<span style="color: #202020;">application_log</span></div></td></tr></tbody></table></div>
<p><img src="http://i.imgur.com/oWoUkuq.png" alt="" /></p>
<p>En cliquant sur le lien proposé, un nouvel onglet s&rsquo;ouvre, dans lequel l&rsquo;intégralité du texte est exposée :</p>
<p><img src="http://i.imgur.com/4Nbl42U.png" alt="" /></p>
<p>Bonne consultation de logs !</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>Les attentes, c&#8217;est quoi au juste ?</title>
		<link>https://blog.developpez.com/elsuket/p13086/moteur-de-base-de-donnees-sql-server/les-attentes-cest-quoi-au-juste</link>
		<comments>https://blog.developpez.com/elsuket/p13086/moteur-de-base-de-donnees-sql-server/les-attentes-cest-quoi-au-juste#comments</comments>
		<pubDate>Tue, 02 Aug 2016 20:27:40 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1239</guid>
		<description><![CDATA[Les attentes sont aux threads SQL Server ce qu&#8217;elles sont aux patients dans une salle d&#8217;attente. Voilà ! Bien entendu ce n&#8217;est pas aussi simple que cela. Démarrons donc une série de billets sur les attentes au sein du moteur &#8230; <a href="https://blog.developpez.com/elsuket/p13086/moteur-de-base-de-donnees-sql-server/les-attentes-cest-quoi-au-juste">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Les attentes sont aux threads SQL Server ce qu&rsquo;elles sont aux patients dans une salle d&rsquo;attente. Voilà !</p>
<p>Bien entendu ce n&rsquo;est pas aussi simple que cela. Démarrons donc une série de billets sur les attentes au sein du moteur de bases de données de SQL Server, en détaillant un peu le mode d&rsquo;exécution des requêtes.</p>
<p><span id="more-1239"></span></p>
<p><strong>Modes d&rsquo;exécution des processus : avant et après SQL Server 2000</strong></p>
<p>Sur les versions antérieures à SQL Server 2005, une grande partie des opérations étaient effectuées par le système d&rsquo;exploitation lui-même. Ceci fait que jusqu&rsquo;à SQL Server 2000, il était difficile de comprendre un problème de performance, c&rsquo;est à dire d&rsquo;obtenir des détails sur le traitement interne des processus par Windows. Cinq ans et une tétra-volée de lignes de code plus tard, Microsoft nous livre un nouvel opus de SQL Server, estampillé 2005, avec un nouveau composant majeur : SQL Operating System (SQLOS). Celui-ci est la fondation du succès actuel du moteur, et il nous permet, à l&rsquo;aide des vues et fonctions de gestion dynamique (DMVs, DMFs, ou DMOs dans la littérature), de mieux comprendre ce qui se passe lorsque l&rsquo;on trouve que l&rsquo;instance, la base de données, ou une requête se comportent anormalement.</p>
<p>Outre le fait que le moteur est, avec cette version, devenu hautement configurable, il implémente un mode d&rsquo;exécution simultané de processus en mode coopératif, à la différence de Windows, qui les exécute par préemption. En effet, le système d&rsquo;exploitation exécute un processus en octroyant à celui-ci un certain temps, qu&rsquo;on appelle quantum, et une priorité par rapport aux autres processus. Cette priorité varie en fonction des ressources matérielles disponibles, de l&rsquo;activité courante, &#8230; Il fait donc s&rsquo;exécuter tour à tour des processus en interrompant l&rsquo;exécution d&rsquo;autres.</p>
<p>On voit donc que cela se pose directement en opposition à la concurrence d&rsquo;accès que doit supporter un moteur de bases de données relationnelles SQL : les interruptions d&rsquo;exécutions peuvent se produire pour plusieurs processus de SQL Server, mais aussi être générés par les processus d&rsquo;autres applications s&rsquo;exécutant sur la même machine (antivirus par exemple, &#8230;). De là le mode coopératif, qui laisse le soin au moteur de gérer ses propres processus, à de rares exceptions près (création des fichiers d&rsquo;une base de données, &#8230;). Ce mode procure un excellent gain de performance observable dès la fin de la migration d&rsquo;une base SQL Server 2000 à 2005, mais pose aussi une nouvelle problématique : la concurrence d&rsquo;accès aux ressources logiques ou physiques que gère le moteur, qui doivent souvent être sérialisées.</p>
<p><strong>Planificateurs, tâches, et unités d&rsquo;exécution</strong><br />
Le mode coopératif d&rsquo;exécution de processus est supporté par un modèle de traitement différent, qui suit le schéma suivant : </p>
<p><img src="http://i.imgur.com/Rs86lka.png" alt="" /></p>
<p><strong>Les sessions</strong><br />
C&rsquo;est la connexion d&rsquo;une application cliente à l&rsquo;instance SQL Server. On peut connaître le détail de chacune des sessions ouvertes sur l&rsquo;instance en interrogeant la vue de gestion dynamique <em>sys.dm_exec_sessions</em>. Les sessions dont la colonne <em>session_id</em> ont une valeur inférieure à 50 sont des sessions ouvertes par le système lui même, pour la gestion de ses processus d&rsquo;arrière-plan. Il est possible que, lorsqu&rsquo;une charge de travail importante s&rsquo;exécute, le moteur ouvre une session dont la valeur de <em>session_id</em> est supérieur à 50. Si on veut donc être sûr de ne requêter que les sessions utilisateur, on peut filtrer par la colonne <em>is_user_process</em>.</p>
<p><strong>Les requêtes</strong><br />
Ce sont, au sens logique, les requêtes en cours d&rsquo;exécution par le moteur. Elles sont elles aussi exposées par une vue de gestion dynamique :  <em>sys.dm_exec_requests</em>. Ici aussi, on retrouve de nombreuses caractéristiques, parmi lesquelles le type et la durée d&rsquo;attente (<em>wait_type</em>, <em>last_wait_type</em>, et <em>wait_time</em>), le numéro de la session qui bloque l&rsquo;exécution de la requête (<em>blocking_session_id</em>). A ce stade du modèle d&rsquo;exécution des requêtes, on voit donc que la gestion des accès concurrentiels aux ressources est au cœur du moteur de base de données.</p>
<p>En suivant le schéma ci-dessus, on peut lier <em>sys.dm_exec_sessions</em> à <em>sys.dm_exec_requests</em> sur la colonne <em>session_id</em>, et cette dernière à <em>sys.dm_os_tasks</em> sur la colonne <em>task_address</em>. Et la colonne <em>task_address</em>, me direz-vous ? voici &#8230;</p>
<p><strong>Les tâches</strong><br />
Elles incarnent le travail qui doit être effectué par SQLOS pour résoudre une requête; à une requête peuvent correspondre plusieurs tâches. Lorsque le moteur soumet une requête à exécution, il crée une série de tâches. On peut en obtenir les détails en interrogeant la vue <em>sys.dm_os_tasks</em>. Même sur une instance où aucune requête n&rsquo;est en cours d&rsquo;exécution, l&rsquo;interrogation de cette vue nous retourne quelques lignes : comme évoqué, SQL Server exécute ses propres processus en arrière-plan; c&rsquo;est d&rsquo;ailleurs ce que l&rsquo;on peut constater en observant la colonne <em>session_id</em> : nombreuses sont les lignes pour lesquelles la valeur est inférieure à 50. Ceci correspond à ce que nous avons observé à l&rsquo;interrogation de <em>sys.dm_exec_sessions</em>. Il en va de même pour la colonne <em>request_id</em> : elle nous permet de réaliser une jointure avec la vue <em>sys.dm_exec_requests</em>. Et la colonne <em>worker_address</em>, me direz-vous ? voici &#8230;</p>
<p><strong>Les unités d&rsquo;exécution</strong><br />
Les unités d&rsquo;exécution effectuent le travail de résolution de la requête que l&rsquo;on vient de soumettre, qui leur est ordonné par les tâches. A une tâche correspond une seule unité d&rsquo;exécution.</p>
<p>Elles sont groupées dans un pool, et à tout instant, on peut (généralement !) les classer en deux catégories : soit elles sont inoccupées (elles bullent, potentiellement en regardant les copines travailler), soit elles exécutent une tâche. Lorsque toutes les unités d&rsquo;exécution sont occupées, la tâche est alors mise en attente jusqu&rsquo;à ce que l&rsquo;une d&rsquo;entre-elles devienne disponible.</p>
<p>Le nombre d&rsquo;unités d&rsquo;exécution est automatiquement calculé par SQL Server durant l&rsquo;installation. Pour connaître le nombre d&rsquo;unités d&rsquo;exécution créées par SQL Server, il suffit de s&rsquo;en remettre à la table exposée sur <a href="https://msdn.microsoft.com/en-us/library/ms190219.aspx">cette page</a> de la documentation.</p>
<p>Le nombre d&rsquo;unités d&rsquo;exécution est configurable, et est par défaut à zéro : c&rsquo;est à dire qu&rsquo;on laisse SQL Server avec la configuration d&rsquo;installation. Dans la très grande majorité des cas, il n&rsquo;y a aucun besoin de modifier le nombre d&rsquo;unités d&rsquo;exécution. Bien sûr, un fil d&rsquo;exécution nécessite un peu de mémoire pour s&rsquo;exécuter : 2 Mo sur les machines dont le CPU fonctionne avec des mots de 64 bits. </p>
<p>On peut en obtenir les détails en interrogeant la vue de gestion dynamique <em>sys.dm_os_workers</em>. Celle-ci expose plusieurs colonnes renseignant sur l&rsquo;état de l&rsquo;unité, avec ses statistiques d&rsquo;exécution, et expose deux colonnes : <em>scheduler_address</em>, qui permet de faire la jointure avec la vue <em>sys.dm_os_schedulers</em>, et <em>task_address</em> avec la vue<em> sys.dm_os_tasks</em>. La colonne la plus intéressante pour le sujet que nous traitons est <em>state</em>, qui peut prendre les valeurs suivantes :</p>
<ul>
<li>INIT : SQLOS prépare l&rsquo;unité d&rsquo;exécution</li>
<li>RUNNING : l&rsquo;unité d&rsquo;exécution exécute actuellement un travail sur un processeur</li>
<li>RUNNABLE : l&rsquo;unité d&rsquo;exécution est en attente d&rsquo;un processeur pour exécuter un travail</li>
<li>SUSPENDED : l&rsquo;unité d&rsquo;exécution est en attente de l&rsquo;accès à une ressource</li>
</ul>
<p>Comme nous le verrons plus loin dans cet article, les unités d&rsquo;exécution passent de l&rsquo;état RUNNING à SUSPENDED, puis à RUNNABLE, et de nouveau à RUNNING jusqu&rsquo;à ce que le travail qu&rsquo;elles ont à exécuter soit terminé.</p>
<p>Et la colonne <em>thread_address</em>, me direz-vous ? voici &#8230;</p>
<p><strong>Les fils d&rsquo;exécution</strong><br />
L&rsquo;unité d&rsquo;exécution ne réalise pas précisément l&rsquo;exécution elle-même : elle demande un fil au système d&rsquo;exploitation. C&rsquo;est ce qu&rsquo;expose la vue de gestion dynamique <em>sys.dm_os_threads</em>.</p>
<p><strong>Les planificateurs</strong><br />
Un planificateur est en charge de gérer les unités d&rsquo;exécution. En ce sens, c&rsquo;est un peu le chef d&rsquo;orchestre de l&rsquo;exécution concurrente des requêtes, qu&rsquo;elles proviennent d&rsquo;applications ou des processus internes à SQL Server. Lorsqu&rsquo;une tâche requiert un core pour s&rsquo;exécuter, c&rsquo;est le planificateur qui assigne la tâche à un des cores disponibles.</p>
<p>C&rsquo;est aussi ce composant qui s&rsquo;assure que les unités d&rsquo;exécution coopèrent en cédant le core auxquels elles sont attachées lorsqu&rsquo;elles atteignent leur quantum. On pourrait alors argumenter que ce mode d&rsquo;exécution n&rsquo;est pas si coopératif que son nom le laisse entendre. Le quantum est en fait en place parce que le planificateur ne permet qu&rsquo;à une seule unité d&rsquo;exécution d&rsquo;occuper un core. S&rsquo;il n&rsquo;existait pas, alors l&rsquo;unité d&rsquo;exécution pourrait occuper un core indéfiniment.</p>
<p>Chaque core de CPU, qu&rsquo;il soit logique ou physique, dispose d&rsquo;un (et d&rsquo;un seul) planificateur. Par exemple, supposons que l&rsquo;on dispose d&rsquo;une machine équipée de deux processeurs à huit cœurs chacun : il y a aura donc 16 planificateurs.</p>
<p>On peut obtenir les détails de chaque planificateur en interrogeant la vue de gestion dynamique <em>sys.dm_os_schedulers</em> :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; parent_node_id <span style="color: #0000FF;">AS</span> NUMA_node_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , scheduler_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , cpu_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , status<br />
&nbsp; &nbsp; &nbsp; &nbsp; , active_worker_address<br />
&nbsp; &nbsp; &nbsp; &nbsp; , quantum_length_us<br />
&nbsp; &nbsp; &nbsp; &nbsp; , total_cpu_usage_ms<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_os_schedulers</span></div></td></tr></tbody></table></div>
<p>On peut y voir à quel core le planificateur est attaché, son statut (VISIBLE ONLINE : utilisé pour les requêtes utilisateur, HIDDEN ONLINE : utilisé par les processus d&rsquo;arrière plan du moteur), le quantum qui lui est attribué (toujours à 4000 µs, et ce n&rsquo;est pas configurable), et le temps CPU consommé par chaque planificateur. Si l&rsquo;on rajoute les colonnes :</p>
<ul>
<li>current_workers_count</li>
<li>active_workers_count</li>
<li>current_tasks_count</li>
<li>runnable_tasks_count</li>
<li>work_queue_count</li>
</ul>
<p>On a alors une idée de la charge que supporte l&rsquo;instance SQL Server étudiée. Par exemple, si la dernière colonne de cette liste montre des nombres élevés, il est probable que SQL Server soit actuellement sous pression CPU.</p>
<p>Vous remarquerez aussi un planificateur dont le statut est VISIBLE ONLINE (DAC) : la fonctionnalité <a href="https://msdn.microsoft.com/fr-fr/library/ms189595.aspx"><em>Dedicated Administrator Connection</em></a> permet de se connecter à une instance SQL Server lorsqu&rsquo;elle ne réagit plus (surcharge CPU par exemple, &#8230;). Ce planificateur lui est dédié.</p>
<p><img src="http://i.imgur.com/yvHkTMI.png" alt="" /></p>
<p>Nous avons vu comment le moteur distribue le travail aux CPUs pour maximiser la concurrence d&rsquo;exécution des requêtes. Voyons ce qui se passe lorsque le planificateur doit placer une requête en attente, que ce soit pour l&rsquo;accès à une ressource, l&rsquo;acquisition d&rsquo;un verrou, ou tout simplement lorsque le quantum est atteint &#8230;</p>
<p><!--more--><br />
<strong>Les attentes</strong></p>
<p>Les fils d&rsquo;exécution suivent les phases et les états suivant les deux graphes suivants, qui sont superposables :</p>
<p><img src="http://i.imgur.com/eQUVIxO.png" alt="" /></p>
<p>Comme nous l&rsquo;avons vu, les unités d&rsquo;exécution passent de l&rsquo;état RUNNING à SUSPENDED à RUNNABLE, dans cet ordre (à de rares exceptions près, notamment lors de l&rsquo;utilisation de la fonctionnalité <em>Resource Governor</em>). Les attentes représentent le temps que les unités d&rsquo;exécution participant à l&rsquo;exécution d&rsquo;une requête on passé entre le passage d&rsquo;un de ces états à un autre. Ce temps est subdivisé en deux catégories :</p>
<ul>
<li>L&rsquo;attente de l&rsquo;accès à une ressource : la ressource peut être un planificateur, le gestionnaire de ressources pour les requêtes parallélisées, un objet de verrouillage (pose d&rsquo;un verrou sur base de données, fichier de base de données, un schéma, une table, une page, une clé, une étendue, les métadonnées, les unités d&rsquo;allocation, la CLR, ou pose de loquets (<em>latch</em> dans la littérature) &#8230; On l&rsquo;appelle compendieusement <strong>attente de ressource.</strong></li>
<li>L&rsquo;attente de la disponibilité d&rsquo;un processeur après que la ressource soit devenue disponible : c&rsquo;est ce qu&rsquo;on appelle de façon plus concise l&rsquo;<strong>attente de signal</strong>.</li>
</ul>
<p>Le temps d&rsquo;attente est la somme de ces deux temps. Forts de cela, votre œil avisé vous a certainement amené à vous demander : Pourquoi avoir utilisé les deux termes <em>Liste</em> et <em>Queue</em> sur le schéma ci-dessus ?</p>
<p><strong>La liste des unités d&rsquo;exécution</strong><br />
Cette liste des unités d&rsquo;exécution à l&rsquo;état SUSPENDED n&rsquo;a pas d&rsquo;ordre ni de priorité de traitement. Toute unité d&rsquo;exécution peut y rester sans limite de temps, et le nombre d’éléments que cette liste peut contenir n&rsquo;a pas non plus de limite. </p>
<p>L&rsquo;unité d&rsquo;exécution est ajoutée à cette liste lorsque son état passe de RUNNING à SUSPENDED.  Elle en est retirée lorsque son état passe de SUSPENDED à RUNNABLE : ceci se produit lorsque cette dernière est notifiée que la ressource qu&rsquo;elle attendait est maintenant disponible, et ce toujours sans ordre ni priorité de traitement.</p>
<p>Ces attentes sont exposées par la vue de gestion dynamique <em>sys.dm_os_waiting_tasks</em>.</p>
<p>Si cela vous a fait penser à l&rsquo;attente de pintes au zinc d&rsquo;un bar bondé, sachez que vous n&rsquo;êtes pas seul !</p>
<p><strong>La queue des unités d&rsquo;exécution en attente d&rsquo;un core</strong><br />
Cette queue contient la liste des unités d&rsquo;exécution dont l&rsquo;état est RUNNABLE, et fonctionne comme un FIFO. L&rsquo;unité d&rsquo;exécution qui se trouve donc être entrée la première dans la queue est la première à être attachée à un core disponible.</p>
<p>Une unité d&rsquo;exécution entre dans cette queue lorsque son état passe de SUSPENDED à RUNNABLE. Ceci se produit par exemple lorsqu&rsquo;une autre unité d&rsquo;exécution en cours de traitement par l&rsquo;un des cores alloués à l&rsquo;instance SQL Server dépasse son quantum, ou que son état devient SUSPENDED.</p>
<p>Le nombre d&rsquo;éléments de cette queue est exposé par la vue de gestion dynamique <em>sys.dm_os_schedulers</em>, à travers la colonne <em>runnable_tasks_count</em>.</p>
<p>Si cela vous a fait penser à l&rsquo;attente pour l&rsquo;accès aux toilettes d&rsquo;un bar bondé, sachez que vous n&rsquo;êtes pas seul !</p>
<p>Pour illustrer tout cela, le schéma plus haut peut être complété par les deux losanges rouges ci-dessous :</p>
<p><img src="http://i.imgur.com/mCSWcDw.png" alt="" /></p>
<p>Voilà pour la description du fonctionnement de l&rsquo;exécution des requêtes.<br />
Dans un billet à venir, nous verrons les types d&rsquo;attentes les plus communs, et comment on peut les interpréter.</p>
<p>A bientôt, et bonne gestion des attentes. N&rsquo;hésitez pas à commenter cet article !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Troubleshooting avec les événements étendus en vidéo</title>
		<link>https://blog.developpez.com/elsuket/p13085/moteur-de-base-de-donnees-sql-server/evenements-etendus/troubleshooting-avec-les-evenements-etendus-en-video</link>
		<comments>https://blog.developpez.com/elsuket/p13085/moteur-de-base-de-donnees-sql-server/evenements-etendus/troubleshooting-avec-les-evenements-etendus-en-video#comments</comments>
		<pubDate>Thu, 28 Jul 2016 08:00:08 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Evénements étendus]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1291</guid>
		<description><![CDATA[Voici la vidéo de la session que j&#8217;ai animé avec David Barbarin sur les événements étendus. Cela recoupe l&#8217;article et la partie du livre sur SQL Server 2014 consacrée à cette fonctionnalité. Bonne visualisation !]]></description>
				<content:encoded><![CDATA[<p>Voici la <a href="https://www.youtube.com/watch?v=gwZ6sD6Xkho">vidéo</a> de la session que j&rsquo;ai animé avec <a href="http://blog.developpez.com/mikedavem/">David Barbarin</a> sur les événements étendus.</p>
<p>Cela recoupe l&rsquo;<a href="http://elsuket.developpez.com/tutoriels/sqlserveur/EvenementsEtendusSQLServer2008/">article</a> et la partie du <a href="http://www.eyrolles.com/Informatique/Livre/sql-server-2014-9782212135923">livre sur SQL Server 2014</a> consacrée à cette fonctionnalité.</p>
<p>Bonne visualisation !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Résumé du SQL Saturday #501 à Paris par la célèbre Sarah Bessard</title>
		<link>https://blog.developpez.com/elsuket/p13057/moteur-de-base-de-donnees-sql-server/resume-du-sql-saturday-501-a-paris-par-la-celebre-sarah-bessard</link>
		<comments>https://blog.developpez.com/elsuket/p13057/moteur-de-base-de-donnees-sql-server/resume-du-sql-saturday-501-a-paris-par-la-celebre-sarah-bessard#comments</comments>
		<pubDate>Sun, 26 Jun 2016 18:16:41 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Annonces]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1237</guid>
		<description><![CDATA[Je me suis rendu hier au SQL Saturdays organisés à Paris par le GUSS, un bel événement, beaucoup de monde, et une vue imprenable sur Paris. J&#8217;ai eu l&#8217;honneur et l&#8217;avantage de faire la rencontre de la très célèbre Sarah &#8230; <a href="https://blog.developpez.com/elsuket/p13057/moteur-de-base-de-donnees-sql-server/resume-du-sql-saturday-501-a-paris-par-la-celebre-sarah-bessard">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Je me suis rendu hier au SQL Saturdays organisés à Paris par le <a href="http://www.concatskills.com/2016/06/26/keyser-soze-au-sqlsat2016/">GUSS</a>, un bel événement, beaucoup de monde, et une vue imprenable sur Paris.</p>
<p>J&rsquo;ai eu l&rsquo;honneur et l&rsquo;avantage de faire la rencontre de la très célèbre Sarah Bessard, dont j&rsquo;entendais régulièrement parler depuis mon rapatriement en France, sans pour autant l&rsquo;avoir encore vue de mes yeux. Elle a résumé avec un humour qui n&rsquo;a d&rsquo;égal que son talent pour l&rsquo;animation par une mise en scène d&rsquo;un excellente session sur le Query Store en compagnie de Philippe Geiger, et d&rsquo;une autre sur le processus de migration d&rsquo;une version à l&rsquo;autre de SQL Server, avec Arian Papillon, en sombrero et collier de fleurs &#8230; Preuve, s&rsquo;il en fallait encore, de la nécessité de femmes dans ce mondes de barbus !</p>
<p>Je vous laisse donc vous délecter de ce <a href="http://www.concatskills.com/2016/06/26/keyser-soze-au-sqlsat2016/">résumé</a>, car je n&rsquo;aurais pas pu l&rsquo;écrire mieux qu&rsquo;elle. Croyez-le ou non, il colle très bien à la réalité !</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>Mesurer et remédier à la fragmentation des index fulltext</title>
		<link>https://blog.developpez.com/elsuket/p13047/moteur-de-base-de-donnees-sql-server/indexation/mesurer-et-remedier-a-la-fragmentation-des-index-fulltext</link>
		<comments>https://blog.developpez.com/elsuket/p13047/moteur-de-base-de-donnees-sql-server/indexation/mesurer-et-remedier-a-la-fragmentation-des-index-fulltext#comments</comments>
		<pubDate>Mon, 06 Jun 2016 12:06:33 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Full-Text]]></category>
		<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1229</guid>
		<description><![CDATA[La fragmentation et la défragmentation des index relationnels est un sujet connu sur lequel la littérature ne manque pas. Mais on voit bien moins souvent des lignes sur les index fulltext, donc la fragmentation élevée nuit de la même façon &#8230; <a href="https://blog.developpez.com/elsuket/p13047/moteur-de-base-de-donnees-sql-server/indexation/mesurer-et-remedier-a-la-fragmentation-des-index-fulltext">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>La fragmentation et la défragmentation des index relationnels est un sujet connu sur lequel la littérature ne manque pas. Mais on voit bien moins souvent des lignes sur les index fulltext, donc la fragmentation élevée nuit de la même façon aux performances des requêtes que leurs cousins relationnels.</p>
<p>Voici donc une requête qui permet de mesurer la fragmentation des index fulltext, et qui génère l&rsquo;instruction de maintenance adéquate, le cas échéant :</p>
<p><span id="more-1229"></span></p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">WITH</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; CTE <span style="color: #0000FF;">AS</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; C.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> catalog_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , I.<span style="color: #202020;">change_tracking_state_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , S.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.'</span> <span style="color: #808080;">+</span> T.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> table_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , F.<span style="color: #202020;">fragment_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , F.<span style="color: #202020;">index_size_MB</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , F.<span style="color: #202020;">largest_fragment_size_MB</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , F.<span style="color: #202020;">avg_fragment_MB</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #000;">100.0</span> <span style="color: #808080;">*</span> <span style="color: #808080;">&#40;</span>F.<span style="color: #202020;">index_size_MB</span> <span style="color: #808080;">-</span> F.<span style="color: #202020;">avg_fragment_MB</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> <span style="color: #0000FF;">NULLIF</span><span style="color: #808080;">&#40;</span>F.<span style="color: #202020;">index_size_MB</span>, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">5</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> avg_MB_frag_pct<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #000;">100</span> <span style="color: #808080;">-</span> <span style="color: #808080;">&#40;</span><span style="color: #000;">100.0</span> <span style="color: #808080;">/</span> F.<span style="color: #202020;">fragment_count</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">5</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> avg_frag_count_pct<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">fulltext_catalogs</span> <span style="color: #0000FF;">AS</span> C<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">fulltext_indexes</span> <span style="color: #0000FF;">AS</span> I<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> I.<span style="color: #202020;">fulltext_catalog_id</span> <span style="color: #808080;">=</span> C.<span style="color: #202020;">fulltext_catalog_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Compute fragment data for each table with a full-text index</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; table_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">*</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> fragment_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">SUM</span><span style="color: #808080;">&#40;</span>data_size <span style="color: #808080;">/</span> <span style="color: #808080;">&#40;</span><span style="color: #000;">1024.0</span> <span style="color: #808080;">*</span> <span style="color: #000;">1024</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">9</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> index_size_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">AVG</span><span style="color: #808080;">&#40;</span>data_size <span style="color: #808080;">/</span> <span style="color: #808080;">&#40;</span><span style="color: #000;">1024.0</span> <span style="color: #808080;">*</span> <span style="color: #000;">1024</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">9</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> avg_fragment_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">MAX</span><span style="color: #808080;">&#40;</span>data_size <span style="color: #808080;">/</span> <span style="color: #808080;">&#40;</span><span style="color: #000;">1024.0</span> <span style="color: #808080;">*</span> <span style="color: #000;">1024</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">9</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> largest_fragment_size_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">fulltext_index_fragments</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">GROUP</span> &nbsp; <span style="color: #0000FF;">BY</span> table_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> F<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> F.<span style="color: #202020;">table_id</span> <span style="color: #808080;">=</span> I.<span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">tables</span> <span style="color: #0000FF;">AS</span> T<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> T.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> I.<span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">schemas</span> <span style="color: #0000FF;">AS</span> S<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> S.<span style="color: #202020;">schema_id</span> <span style="color: #808080;">=</span> T.<span style="color: #202020;">schema_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF0000;">'ALTER FULLTEXT CATALOG ['</span><span style="color: #808080;">+</span> &nbsp;catalog_name &nbsp;<span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> avg_frag_count_pct <span style="color: #808080;">&amp;</span>gt; <span style="color: #000;">30</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'] REBUILD'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> avg_frag_count_pct <span style="color: #808080;">BETWEEN</span> <span style="color: #000;">10</span> <span style="color: #808080;">AND</span> <span style="color: #000;">30</span> <span style="color: #808080;">AND</span> avg_frag_count_pct <span style="color: #808080;">&amp;</span>gt;<span style="color: #808080;">=</span> <span style="color: #000;">10</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'] REORGANIZE'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> &nbsp;<span style="color: #0000FF;">AS</span> maintenance_sql<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; CTE</div></td></tr></tbody></table></div>
<p>Bonne maintenance d&rsquo;index fulltext !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scripter les index fulltext</title>
		<link>https://blog.developpez.com/elsuket/p13046/moteur-de-base-de-donnees-sql-server/indexation/scripter-les-index-fulltext</link>
		<comments>https://blog.developpez.com/elsuket/p13046/moteur-de-base-de-donnees-sql-server/indexation/scripter-les-index-fulltext#comments</comments>
		<pubDate>Mon, 06 Jun 2016 10:52:13 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Full-Text]]></category>
		<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1226</guid>
		<description><![CDATA[Voici une petite requête qui permet d&#8217;extraire le script de création des index fulltext d&#8217;une base de données. Il génère également l&#8217;instruction de création du catalogue (CREATE FULLTEXT CATALOG) auquel chaque index est lié. Donc si l&#8217;on a plusieurs index &#8230; <a href="https://blog.developpez.com/elsuket/p13046/moteur-de-base-de-donnees-sql-server/indexation/scripter-les-index-fulltext">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une petite requête qui permet d&rsquo;extraire le script de création des index fulltext d&rsquo;une base de données. Il génère également l&rsquo;instruction de création du catalogue (CREATE FULLTEXT CATALOG) auquel chaque index est lié. Donc si l&rsquo;on a plusieurs index attachés au même catalogue, le script teste si le catalogue existe déjà.</p>
<p><span id="more-1226"></span></p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">DECLARE</span> @cr <span style="color: #0000FF;">char</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">13</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @tab <span style="color: #0000FF;">char</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #0000FF;">CHAR</span><span style="color: #808080;">&#40;</span><span style="color: #000;">9</span><span style="color: #808080;">&#41;</span><br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #FF0000;">'IF NOT EXISTS (SELECT * FROM sys.fulltext_catalogs WHERE name = '</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> FC.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">')'</span> <span style="color: #808080;">+</span> @cr<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">'CREATE FULLTEXT CATALOG ['</span> <span style="color: #808080;">+</span> FC.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">']'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span> FC.<span style="color: #202020;">is_default</span> <span style="color: #0000FF;">WHEN</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">' AS DEFAULT'</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">''</span> <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span> FC.<span style="color: #202020;">is_accent_sensitivity_on</span> <span style="color: #0000FF;">WHEN</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">' WITH ACCENT_SENSITIVITY = ON'</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">''</span> <span style="color: #0000FF;">END</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">';'</span> <span style="color: #808080;">+</span> @cr <span style="color: #808080;">+</span> @cr<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">'IF NOT EXISTS(SELECT * FROM sys.fulltext_indexes WHERE object_id = OBJECT_ID('</span><span style="color: #FF0000;">'['</span> <span style="color: #808080;">+</span> S.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'].['</span> <span style="color: #808080;">+</span> T.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">']'</span><span style="color: #FF0000;">'))'</span> <span style="color: #808080;">+</span> @cr<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">'CREATE FULLTEXT INDEX ON ['</span> <span style="color: #808080;">+</span> S.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'].['</span> <span style="color: #808080;">+</span> T.<span style="color: #202020;">name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">']'</span> <span style="color: #808080;">+</span> @cr <span style="color: #808080;">+</span> <span style="color: #FF0000;">'('</span> <span style="color: #808080;">+</span> @cr <span style="color: #808080;">+</span> @tab <span style="color: #808080;">+</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span>FIS.<span style="color: #202020;">column_list</span>, <span style="color: #FF00FF;">LEN</span><span style="color: #808080;">&#40;</span>FIS.<span style="color: #202020;">column_list</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">-</span> <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF0000;">','</span>, @cr <span style="color: #808080;">+</span> @tab <span style="color: #808080;">+</span> <span style="color: #FF0000;">', '</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> @cr <span style="color: #808080;">+</span> <span style="color: #FF0000;">')'</span> <span style="color: #808080;">+</span> @cr<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">'KEY INDEX ['</span> <span style="color: #808080;">+</span> I.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'] ON (['</span> <span style="color: #808080;">+</span> FC.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'], FILEGROUP ['</span> <span style="color: #808080;">+</span> FG.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'])'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span> <span style="color: #0000FF;">WHEN</span> <span style="color: #FF00FF;">LEN</span><span style="color: #808080;">&#40;</span>FIO.<span style="color: #202020;">fulltext_index_options</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">&amp;</span>gt; <span style="color: #000;">0</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'WITH '</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">RIGHT</span><span style="color: #808080;">&#40;</span>FIO.<span style="color: #202020;">fulltext_index_options</span>, <span style="color: #FF00FF;">LEN</span><span style="color: #808080;">&#40;</span>FIO.<span style="color: #202020;">fulltext_index_options</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">-</span> <span style="color: #000;">2</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">''</span> <span style="color: #0000FF;">END</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">';'</span> <span style="color: #808080;">+</span> @cr <span style="color: #808080;">+</span> @cr<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">fulltext_catalogs</span> <span style="color: #0000FF;">AS</span> FC<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">fulltext_indexes</span> <span style="color: #0000FF;">AS</span> FI<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> FI.<span style="color: #202020;">fulltext_catalog_id</span> <span style="color: #808080;">=</span> FC.<span style="color: #202020;">fulltext_catalog_id</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">indexes</span> <span style="color: #0000FF;">AS</span> I<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> I.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> FI.<span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> I.<span style="color: #202020;">index_id</span> <span style="color: #808080;">=</span> FI.<span style="color: #202020;">unique_index_id</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">tables</span> <span style="color: #0000FF;">AS</span> T<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> FI.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> T.<span style="color: #FF00FF;">object_id</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">schemas</span> <span style="color: #0000FF;">AS</span> S<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> S.<span style="color: #202020;">schema_id</span> <span style="color: #808080;">=</span> T.<span style="color: #202020;">schema_id</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">filegroups</span> <span style="color: #0000FF;">AS</span> FG<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> FG.<span style="color: #202020;">data_space_id</span> <span style="color: #808080;">=</span> FI.<span style="color: #202020;">data_space_id</span><br />
<span style="color: #808080;">CROSS</span> APPLY &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; C.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' LANGUAGE '</span> <span style="color: #808080;">+</span> FL.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">', '</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">fulltext_index_columns</span> <span style="color: #0000FF;">AS</span> FIC<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">columns</span> <span style="color: #0000FF;">AS</span> C<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> FIC.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> C.<span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> FIC.<span style="color: #202020;">column_id</span> <span style="color: #808080;">=</span> C.<span style="color: #202020;">column_id</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">fulltext_languages</span> <span style="color: #0000FF;">AS</span> FL<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> FIC.<span style="color: #202020;">language_id</span> <span style="color: #808080;">=</span> FL.<span style="color: #202020;">lcid</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FI.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> FIC.<span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FOR</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; XML <span style="color: #0000FF;">PATH</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> FIS<span style="color: #808080;">&#40;</span>column_list<span style="color: #808080;">&#41;</span><br />
<span style="color: #808080;">CROSS</span> APPLY &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CASE</span> <span style="color: #0000FF;">WHEN</span> FI.<span style="color: #202020;">change_tracking_state_desc</span> &nbsp;<span style="color: #FF0000;">'AUTO'</span> <span style="color: #0000FF;">THEN</span> &nbsp;<span style="color: #FF0000;">', CHANGE_TRACKING = '</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> FI.<span style="color: #202020;">change_tracking_state_desc</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">''</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">''</span> <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span> <span style="color: #0000FF;">WHEN</span> FI.<span style="color: #202020;">stoplist_id</span> <span style="color: #808080;">&amp;</span>gt; <span style="color: #000;">0</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">', STOPLIST = '</span> <span style="color: #808080;">+</span> FSL.<span style="color: #202020;">name</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">''</span> <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span> <span style="color: #0000FF;">WHEN</span> FI.<span style="color: #202020;">property_list_id</span> <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">', SEARCH PROPERTY LIST = '</span> <span style="color: #808080;">+</span> FRSPL.<span style="color: #202020;">name</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">''</span> <span style="color: #0000FF;">END</span> <span style="color: #0000FF;">COLLATE</span> database_default<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">fulltext_indexes</span> <span style="color: #0000FF;">AS</span> FIO<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">LEFT</span> <span style="color: #808080;">JOIN</span> &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">fulltext_stoplists</span> <span style="color: #0000FF;">AS</span> FSL<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> FI.<span style="color: #202020;">stoplist_id</span> <span style="color: #808080;">=</span> FSL.<span style="color: #202020;">stoplist_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">LEFT</span> <span style="color: #808080;">JOIN</span> &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">registered_search_property_lists</span> <span style="color: #0000FF;">AS</span> FRSPL<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> FI.<span style="color: #202020;">property_list_id</span> <span style="color: #808080;">=</span> FRSPL.<span style="color: #202020;">property_list_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FIO.<span style="color: #202020;">fulltext_catalog_id</span> <span style="color: #808080;">=</span> FI.<span style="color: #202020;">fulltext_catalog_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FIO.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> FI.<span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FOR</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; XML <span style="color: #0000FF;">PATH</span> <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> FIO<span style="color: #808080;">&#40;</span>fulltext_index_options<span style="color: #808080;">&#41;</span></div></td></tr></tbody></table></div>
<p>Bonne indexation fulltext !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Récupérer les graphes des deadlocks rétrospectivement : les requêtes adéquates aux versions</title>
		<link>https://blog.developpez.com/elsuket/p12987/moteur-de-base-de-donnees-sql-server/recuperer-les-graphes-des-deadlocks-retrospectivement-les-requetes-adequates-aux-versions</link>
		<comments>https://blog.developpez.com/elsuket/p12987/moteur-de-base-de-donnees-sql-server/recuperer-les-graphes-des-deadlocks-retrospectivement-les-requetes-adequates-aux-versions#comments</comments>
		<pubDate>Sun, 17 Jan 2016 17:00:24 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1214</guid>
		<description><![CDATA[Faisant suite au petit billet que j&#8217;ai publié il y quelques temps et qui a donc un peu pris la poussière, voici les requêtes qui permettent de récupérer les deadlocks qui se sont produits. Quelle que soit la version de &#8230; <a href="https://blog.developpez.com/elsuket/p12987/moteur-de-base-de-donnees-sql-server/recuperer-les-graphes-des-deadlocks-retrospectivement-les-requetes-adequates-aux-versions">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Faisant suite au <a href="http://blog.developpez.com/elsuket/p9234/moteur-de-base-de-donnees-sql-server/obtenir_la_liste_des_deadlocks_retrospec" title="Obtenir la liste des deadlocks rétrospectivement">petit billet</a> que j&rsquo;ai publié il y quelques temps et qui a donc un peu pris la poussière, voici les requêtes qui permettent de récupérer les deadlocks qui se sont produits.<br />
<span id="more-1214"></span></p>
<p>Quelle que soit la version de SQL Server, les caractéristiques des 256 dernières situations de blocage qui ont conduit à l&rsquo;annulation de la transaction détenant le moins de ressources (puisque la moins &laquo;&nbsp;chère&nbsp;&raquo; à annuler) sont retenus par une cible de type anneau de mémoire (qui fonctionne sur le principe d&rsquo;un FIFO) par une session d’<a href="http://blog.developpez.com/elsuket/p11065/moteur-de-base-de-donnees-sql-server/evenements_etendus_sql_server_2008" title="Les Événements Étendus avec SQL Server 2008">évènements étendus</a> que l&rsquo;on pourrait qualifier de &laquo;&nbsp;système&nbsp;&raquo;, et nommée <em>system_health</em>.</p>
<p>On peut s&rsquo;en tenir au document XML exposé par ces requêtes pour comprendre quelles ressources étaient en jeu, et procéder à l&rsquo;optimisation adéquate qui permettra d&rsquo;éviter que de telles situations se reproduisent. Néanmoins, comme un schéma vaut souvent mieux que mille mots, on peut aussi récupérer le document XML de chaque ligne généré par ces requêtes, et le sauvegarder dans un fichier de type texte, dont on changera l&rsquo;extension par &laquo;&nbsp;.xdl&nbsp;&raquo; : ceci permet de voir la situation de blocage sous la forme d&rsquo;un graphe; ce type de fichier s&rsquo;ouvre avec SQL Server Management Studio (cf. <a href="http://www.eyrolles.com/Informatique/Livre/sql-server-2014-9782212135923">Livre SQL Server 2014</a>)</p>
<p>Ces graphes ont évolué avec les sorties des opus de SQL Server, si bien que, par exemple, la requête qui permet de les récupérer sous SQL Server 2008R2 ne fonctionne pas pour les versions suivantes de SQL Server. En revanche, la structure de ce document est stable depuis SQL Server 2012.</p>
<p>Voici donc les requêtes :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-- SQL Server 2008</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; E.<span style="color: #202020;">e</span>.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'@timestamp'</span>, <span style="color: #FF0000;">'datetime'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> occurence_date_time<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>E.<span style="color: #202020;">e</span>.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(data/value)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> xml<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> deadlock_graph<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> local_date_time<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>target_data <span style="color: #0000FF;">AS</span> xml<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> target_data<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_session_targets</span> <span style="color: #0000FF;">AS</span> ST<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_sessions</span> <span style="color: #0000FF;">AS</span> S<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> S.<span style="color: #202020;">address</span> <span style="color: #808080;">=</span> ST.<span style="color: #202020;">event_session_address</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S.<span style="color: #202020;">name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'system_health'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> TD<br />
<span style="color: #808080;">CROSS</span> APPLY &nbsp; &nbsp; TD.<span style="color: #202020;">target_data</span>.<span style="color: #202020;">nodes</span> <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'//RingBufferTarget/event'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> E<span style="color: #808080;">&#40;</span>e<span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; E.<span style="color: #202020;">e</span>.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'@name'</span>, <span style="color: #FF0000;">'varchar(4000)'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'xml_deadlock_report'</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">--SQL Server 2008 R2</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; occurence_date_time<br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>T.<span style="color: #202020;">event_data</span>.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data/value)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> xml<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> deadlock_graph<br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> local_date_time<br />
<span style="color: #0000FF;">FROM</span> &nbsp; &nbsp;<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; XDR.<span style="color: #202020;">xdr</span>.<span style="color: #202020;">query</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'.'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> event_data<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , XDR.<span style="color: #202020;">xdr</span>.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'@timestamp'</span>, <span style="color: #FF0000;">'datetime'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> occurence_date_time<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Cast the target_data to XML </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>target_data <span style="color: #0000FF;">AS</span> XML<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> target_data<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_session_targets</span> <span style="color: #0000FF;">AS</span> ST<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_sessions</span> <span style="color: #0000FF;">AS</span> S<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> s.<span style="color: #202020;">address</span> <span style="color: #808080;">=</span> st.<span style="color: #202020;">event_session_address</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S.<span style="color: #202020;">name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'system_health'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ST.<span style="color: #202020;">target_name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ring_buffer'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> TD <span style="color: #008080;">-- Split out the Event Nodes </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">CROSS</span> APPLY &nbsp; &nbsp; TD.<span style="color: #202020;">target_data</span>.<span style="color: #202020;">nodes</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'RingBufferTarget/event[@name=&quot;xml_deadlock_report&quot;]'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> XDR<span style="color: #808080;">&#40;</span>xdr<span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> T<span style="color: #808080;">&#40;</span>event_data, occurence_date_time<span style="color: #808080;">&#41;</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-- SQL Server 2012, 2014, 2016</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; SRC.<span style="color: #202020;">occurence_date_time</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , SRC.<span style="color: #202020;">deadlock_graph</span>.<span style="color: #202020;">query</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data/value/deadlock)[1]'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> deadlock_graph<br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> local_date_time<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; XDR.<span style="color: #202020;">xdr</span>.<span style="color: #202020;">query</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'.'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> deadlock_graph<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , XDR.<span style="color: #202020;">xdr</span>.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'@timestamp'</span>, <span style="color: #FF0000;">'datetime'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> occurence_date_time<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>ST.<span style="color: #202020;">target_data</span> <span style="color: #0000FF;">AS</span> xml<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> target_data<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_session_targets</span> <span style="color: #0000FF;">AS</span> ST<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_sessions</span> <span style="color: #0000FF;">AS</span> S<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> S.<span style="color: #202020;">address</span> <span style="color: #808080;">=</span> ST.<span style="color: #202020;">event_session_address</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S.<span style="color: #202020;">name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'system_health'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ST.<span style="color: #202020;">target_name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ring_buffer'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> TD<span style="color: #808080;">&#40;</span>target_data<span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">CROSS</span> APPLY &nbsp; &nbsp; TD.<span style="color: #202020;">target_data</span>.<span style="color: #202020;">nodes</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'RingBufferTarget/event[@name=&quot;xml_deadlock_report&quot;]'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> XDR<span style="color: #808080;">&#40;</span>xdr<span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> SRC;</div></td></tr></tbody></table></div>
<p>Bonne lecture et déblocage !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La CTP 3 de SQL Server 2016 disponible au téléchargement</title>
		<link>https://blog.developpez.com/elsuket/p12924/moteur-de-base-de-donnees-sql-server/la-ctp-3-de-sql-server-2016-disponible-au-telechargement</link>
		<comments>https://blog.developpez.com/elsuket/p12924/moteur-de-base-de-donnees-sql-server/la-ctp-3-de-sql-server-2016-disponible-au-telechargement#comments</comments>
		<pubDate>Thu, 29 Oct 2015 20:29:02 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1170</guid>
		<description><![CDATA[C&#8217;est par ici, y compris en Français. Pour la documentation relative à cette version, c&#8217;est par ici : fr / en. Bonne évaluation!]]></description>
				<content:encoded><![CDATA[<p>C&rsquo;est par <a href="https://technet.microsoft.com/fr-fr/evalcenter/mt130694">ici</a>, y compris en Français.</p>
<p>Pour la documentation relative à cette version, c&rsquo;est par ici : <a href="https://msdn.microsoft.com/fr-fr/library/ms130214.aspx">fr</a> / <a href="https://msdn.microsoft.com/en-us/library/ms130214.aspx">en</a>.</p>
<p>Bonne évaluation!</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Capture manuelle de plans de requête</title>
		<link>https://blog.developpez.com/elsuket/p12879/moteur-de-base-de-donnees-sql-server/capture-manuelle-de-plans-de-requete</link>
		<comments>https://blog.developpez.com/elsuket/p12879/moteur-de-base-de-donnees-sql-server/capture-manuelle-de-plans-de-requete#comments</comments>
		<pubDate>Fri, 26 Jun 2015 17:03:50 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1134</guid>
		<description><![CDATA[Plusieurs des participants au forum SQL Server de Développez demandent comment optimiser une requête : ce billet leur est particulièrement destiné, puisqu&#8217;une optimisation de requête ne peut réellement se faire sans son plan d&#8217;exécution, le mieux étant aussi d&#8217;avoir la &#8230; <a href="https://blog.developpez.com/elsuket/p12879/moteur-de-base-de-donnees-sql-server/capture-manuelle-de-plans-de-requete">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Plusieurs des participants au forum SQL Server de Développez demandent comment optimiser une requête : ce billet leur est particulièrement destiné, puisqu&rsquo;une optimisation de requête ne peut réellement se faire sans son plan d&rsquo;exécution, le mieux étant aussi d&rsquo;avoir la sortie de l&rsquo;option de session SET STATISTICS IO, TIME ON, et le DDL (ordre CREATE TABLE) de la table et de ses index.<br />
<span id="more-1134"></span></p>
<p>Un plan de requête expose la façon dont l&rsquo;optimiseur de requêtes de SQL Server a calculé la résolution d&rsquo;une requête que nous lui avons soumis. Ce dernier fait un excellent travail dans la très grande majorité des cas, et pour les autres, il a parfois besoin de l&rsquo;aide d&rsquo;un DBA lorsque l&rsquo;indexation n&rsquo;est pas l&rsquo;origine du problème.</p>
<p>SQL Server Management Studio (SSMS) expose les plans de requête estimés et réels.<br />
Le plan de requête estimé expose la suite d&rsquo;opérateurs logiques et physiques que le moteur a trouvé optimale pour résoudre une requête, c&rsquo;est à dire celle qui consommera le moins de ressources. Ce plan est basé sur les statistiques de colonnes et d&rsquo;index. La maintenance et la qualité des statistiques est un un sujet vaste que nous n&rsquo;aborderons pas ici. On peut obtenir le plan de requête estimé sans exécuter celle-ci en pressant CTRL+L, ou en cliquant sur le bouton ci-dessous, après avoir surligné la requête en question s&rsquo;il y en a plusieurs dans la fenêtre de requêtes de SSMS.</p>
<p><img src="http://i.imgur.com/a9Z1vpE.png" alt="" /></p>
<p>Le DBA peut se servir du plan de requête estimé pour comprendre un problème de performances, mais il arrive qu&rsquo;un autre type de plan, dit réel, soit nécessaire. Ce plan peut être généré juste après la fin de l&rsquo;exécution d&rsquo;une requête, et permet d&rsquo;exposer les différences entre le plan estimé et ce qui s&rsquo;est passé lors de son exécution. De façon similaire au plan de requête estimé, on peut obtenir ce plan de requête en pressant CTRL+M, ou en pressant le bouton suivant dans SSMS <strong>avant</strong> l&rsquo;exécution de la requête à étudier.</p>
<p><img src="http://i.imgur.com/P6eGGkx.png" alt="" /></p>
<p>Visuellement, avec SSMS, aussi bien avec le plan de requête estimé que réel, nous obtenons, pour la requête suivante exécutée sur la base de données exemple <em>AdventureWorks2012</em> proposée par Microsoft <a href="http://msftdbprodsamples.codeplex.com/releases/view/55330">ici</a> (voir les détails de l&rsquo;installation <a href="http://blog.developpez.com/elsuket/p11188/moteur-de-base-de-donnees-sql-server/attacher_base_donnees_sans_tran_log" title="Attacher une base de données qui n’a pas de fichier du journal des transactions">ici</a>) :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span><br />
<span style="color: #008080;">-- Expose le nombre de lectures effectué sur chaque table,</span><br />
<span style="color: #008080;">-- ainsi que le temps CPU consommé. On retrouve ces données dans l'onglet</span><br />
<span style="color: #008080;">-- Messages du panneau des résultats de requête, après exécution de celle-ci.</span><br />
<span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">STATISTICS</span> IO, <span style="color: #0000FF;">TIME</span> <span style="color: #0000FF;">ON</span> <br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PP.<span style="color: #202020;">LastName</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , PP.<span style="color: #202020;">FirstName</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">*</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> sales_count<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Person.<span style="color: #202020;">Person</span> <span style="color: #0000FF;">AS</span> PP<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; HumanResources.<span style="color: #202020;">Employee</span> <span style="color: #0000FF;">AS</span> E<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> PP.<span style="color: #202020;">BusinessEntityID</span> <span style="color: #808080;">=</span> E.<span style="color: #202020;">BusinessEntityID</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; Sales.<span style="color: #202020;">SalesOrderHeader</span> <span style="color: #0000FF;">AS</span> SOH<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> SOH.<span style="color: #202020;">SalesPersonID</span> <span style="color: #808080;">=</span> PP.<span style="color: #202020;">BusinessEntityID</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; Sales.<span style="color: #202020;">SalesOrderDetail</span> <span style="color: #0000FF;">AS</span> SOD<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> SOH.<span style="color: #202020;">SalesOrderID</span> <span style="color: #808080;">=</span> SOD.<span style="color: #202020;">SalesOrderID</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; Production.<span style="color: #202020;">Product</span> <span style="color: #0000FF;">AS</span> P<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> SOD.<span style="color: #202020;">ProductID</span> <span style="color: #808080;">=</span> P.<span style="color: #202020;">ProductID</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; P.<span style="color: #202020;">ProductNumber</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'BK-M18B-44'</span><br />
<span style="color: #0000FF;">GROUP</span> <span style="color: #0000FF;">BY</span>&nbsp; &nbsp; &nbsp; &nbsp; PP.<span style="color: #202020;">LastName</span>, PP.<span style="color: #202020;">FirstName</span><br />
<span style="color: #0000FF;">ORDER</span> <span style="color: #0000FF;">BY</span>&nbsp; &nbsp; &nbsp; &nbsp; sales_count <span style="color: #0000FF;">DESC</span></div></td></tr></tbody></table></div>
<p><img src="http://i.imgur.com/E0xY7jS.png" alt="" /></p>
<p>Bien qu&rsquo;utile, le fait d&rsquo;avoir à constamment déplacer les curseurs de parcours, surtout lorsque le plan est constitué de nombreux opérateurs, devient vite peu confortable.</p>
<p>Alternativement, SQL Sentry nous offre la possibilité d&rsquo;utiliser la version gratuite de son outil Plan Explorer, que j&rsquo;avais exposé <a href="http://blog.developpez.com/elsuket/p10724/utilitaires/sql_sentry_plan_explorer" title="Analyse de plans de requête : SQL Sentry Plan Explorer" target="_blank">ici</a>, et qui continue d&rsquo;évoluer. On peut télécharger le logiciel <a href="http://www.sqlsentry.com/products/plan-explorer/sql-server-query-view" title="SQL Sentry Plan Explorer">ici</a> (en toute fin de page), et il s&rsquo;intègre automatiquement à SSMS. En effet, il suffit d&rsquo;effectuer un clic-droit dans une zone vierge du plan et de sélectionner l&rsquo;option <em>View in SQL Sentry Plan Explorer</em> &#8230;</p>
<p><img src="http://i.imgur.com/pEuO946.png" alt="" /></p>
<p>&#8230; pour voir l&rsquo;interface de SQL Sentry Plan Explorer s&rsquo;ouvrir, et observer une façon différente de disséquer un plan de requête :</p>
<p><img src="http://i.imgur.com/vHMve4w.png" alt="" /></p>
<p>Le nombre de lignes échangé entre les opérateurs est exposé directement dans le plan, exposé de façon plus compacte. Par ailleurs, le coût relatif des opérateurs est affiché directement au-dessus de ceux-ci, avec une couleur qui s&rsquo;assombrit suivant la dépense de ressources qu&rsquo;ils engendrent. Outre le fait que l&rsquo;on puisse zoomer sur le plan (utile lorsque le plan de requête est tentaculaire, ou en conférence), les divers onglets présents au bas du panneau du plan d&rsquo;exécution graphique décrivent des informations souvent utiles, notamment :</p>
<ul>
<li>le document XML sous-jacent au plan graphique</li>
<li>L&rsquo;arbre du plan, similaire à la sortie que l&rsquo;on obtient avec SSMS lorsque l&rsquo;option de session SHOWPLAN_TEXT est positionnée à ON</li>
<li>Les opérations les plus consommatrices de ressources, comparées à toutes les autres opérations du plan</li>
<li>Les colonnes spécifiées dans la requête, quel opérateur elles subissent et à travers quel index elles sont accédées</li>
<li>Le diagramme de jointure, qui permet bien souvent de se rentre compte d&rsquo;une auto-jointure inopportune</li>
<li>Les paramètres de la requêtes et leur valeur au moment de la compilation et au moment de l&rsquo;exécution</li>
<li>Les expressions (par exemple <em>Expr10NN</em>, où N est un entier, que l&rsquo;on rencontre parfois dans le plan graphique dans SSMS comme substitut à une expression dans la requête, et que l&rsquo;on arrive à comprendre seulement en décortiquant le plan XML. Cela permet aussi de détecter les conversions implicites, parfois néfastes aux performances d&rsquo;exécution d&rsquo;une requête.)</li>
</ul>
<p>Les diverses requêtes sont exposées une à une, avec leur coût relatif au coût total du plan : il suffit de cliquer sur l&rsquo;une des requêtes dans le panneau <em>Results</em> pour les parcourir. Enfin, si l&rsquo;optimiseur suggère d&rsquo;ajouter un index (fonctionnalité de suggestion d&rsquo;<a href="http://blog.developpez.com/elsuket/p6345/moteur-de-base-de-donnees-sql-server/indexation/title_107" title="Recherche d’indexes manquants sous SQL Server 2005">index manquants</a>), il suffit de cliquer sur l&rsquo;opérateur final du plan (le plus en haut et à gauche) pour que l&rsquo;outil ouvre une fenêtre séparée qui donne, comme dans SSMS, l&rsquo;instruction de création de l&rsquo;index.</p>
<p>Passons maintenant au plan d&rsquo;exécution réel :</p>
<p><img src="http://i.imgur.com/IukvKAb.png" alt="" /></p>
<p>Avec la possibilité de montrer l&rsquo;estimation du nombre de lignes (cardinalité) par rapport au nombre de lignes manipulé par les opérateurs lors de l&rsquo;exécution de la requête par un simple clic-droit, on détecte très rapidement les problèmes d&rsquo;estimation de cardinalités : c&rsquo;est bien souvent à cause de cela que la requête étudiée s&rsquo;exécute lentement ou consomme beaucoup de ressources. Dans ce cas, l&rsquo;épaisseur des flèches est largement affectée, et c&rsquo;est l&rsquo;effet visuel généré par le passage d&rsquo;un plan à l&rsquo;autre qui permet la détection visuelle.</p>
<p>Cerise sur le gâteau : SQL Sentry Plan Explorer permet aussi d&rsquo;anonymiser un plan de requête, c&rsquo;est à dire de remplacer le nom réel des tables et autres objets exposés par le plan par un nom générique, et ce en conservant toute la logique du plan. Après un clic sur le bouton suivant, qui se trouve dans la barre d&rsquo;outils de SQL Sentry Plan Explorer &#8230;</p>
<p><img src="http://i.imgur.com/svPkywh.png" alt="" /></p>
<p>&#8230; une autre fenêtre s&rsquo;ouvre, exposant le plan anonymisé : au lieu de trouver le nom des objets réels, on trouve par exemple <em>ObjectN.IndexP</em>, où N et P sont des entiers.</p>
<p><img src="http://i.imgur.com/zYaebnr.png" alt="" /></p>
<p>On peut ensuite sauvegarder un tel plan (qu&rsquo;il soit anonymisé ou non) en vue de le partager sur le <a href="www.developpez.net/forums/f49/bases-donnees/ms-sql-server/" title="Développez.com - Forum SQL Server" target="_blank">forum Développez.com dédié à SQL Server</a> sans exposer d&rsquo;informations sensibles : un clic sur File &gt; Save As ouvre la fenêtre suivante :</p>
<p><img src="http://i.imgur.com/1QQD1wP.png" alt="" /></p>
<ul>
<li>L&rsquo;extension <em>.queryplananalysis</em> est le format propriétaire de SQL Sentry. Si vous sauvegardez sous ce type, assurez-vous que la personne avec qui vous partagez le plan de requête dispose aussi de SQL Sentry Plan Explorer.</li>
<li>L&rsquo;extension <em>.sqlplan</em> est le format propriétaire de SQL Server Management Studio. Après la sauvegarde, si vous double-cliquez sur un tel document, il s&rsquo;ouvrira automatiquement avec ce dernier</li>
<li>L&rsquo;extension <em>.xml</em> est le format générique de description de documents bien connu. Le document résultant est identique à son homologue .sqlplan. On peut l&rsquo;utiliser pour automatiser l&rsquo;extraction de données de plusieurs plans.</li>
</ul>
<p>Bonne capture de plans !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Où trouver la définition des objets et attributs de plans de requêtes ?</title>
		<link>https://blog.developpez.com/elsuket/p12803/moteur-de-base-de-donnees-sql-server/ou-trouver-la-definition-des-objects-et-attributs-de-plans-de-requetes</link>
		<comments>https://blog.developpez.com/elsuket/p12803/moteur-de-base-de-donnees-sql-server/ou-trouver-la-definition-des-objects-et-attributs-de-plans-de-requetes#comments</comments>
		<pubDate>Tue, 09 Dec 2014 00:56:06 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1099</guid>
		<description><![CDATA[Après quelques mois d&#8217;absence et avoir assisté au Microsoft MVP Summit et au PASS Summit 2014, et m&#8217;être enfin replongé dans un peu de lecture dense sur SQL Server, voici quelques liens utiles en ce qui concerne les plans de &#8230; <a href="https://blog.developpez.com/elsuket/p12803/moteur-de-base-de-donnees-sql-server/ou-trouver-la-definition-des-objects-et-attributs-de-plans-de-requetes">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Après quelques mois d&rsquo;absence et avoir assisté au Microsoft MVP Summit et au PASS Summit 2014, et m&rsquo;être enfin replongé dans un peu de lecture dense sur SQL Server, voici quelques liens utiles en ce qui concerne les plans de requête :</p>
<ul>
<li>Définition des plans XML : <a href="http://schemas.microsoft.com/sqlserver/2004/07/showplan/">schémas XSD</a> : expose le schéma XSD des plans de requête XML, ce qui permet de trouver les améliorations au niveau de l&rsquo;optimiseur en comparant le schéma de deux versions de SQL Server</li>
<li><a href="http://msdn.microsoft.com/fr-fr/library/ms191158.aspx">Guide de référence</a> des opérateurs Showplan : une liste exhaustive de tous les opérateurs que l&rsquo;on peut trouver dans un plan de requête graphique</li>
<li>Une autre liste, publiée par <a href="https://www.simple-talk.com/books/sql-books/complete-showplan-operators/">Fabiano Amorim</a>, avec la liste des opérateurs de plan d&rsquo;exécution graphique les plus communs, expliquant leur fonctionnement, et pourquoi ils sont choisis par l&rsquo;optimiseur de requêtes
</ul>
<p>Bonne lecture !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sauvegardes cryptées et dans Azure avec SQL Server 2014</title>
		<link>https://blog.developpez.com/elsuket/p12640/moteur-de-base-de-donnees-sql-server/sauvegardes-cryptees-et-dans-azure</link>
		<comments>https://blog.developpez.com/elsuket/p12640/moteur-de-base-de-donnees-sql-server/sauvegardes-cryptees-et-dans-azure#comments</comments>
		<pubDate>Fri, 13 Jun 2014 02:28:29 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Annonces]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[cryptage]]></category>
		<category><![CDATA[sauvegarde]]></category>
		<category><![CDATA[SQL Server 2014]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1071</guid>
		<description><![CDATA[Microsoft a publié un article que j&#8217;ai terminé d&#8217;écrire au début de ce mois sur ce sujet. En plus du fonctionnement du cryptage des sauvegardes, j&#8217;y détaille les étapes pour : Sauvegarder une base de données en cryptant le fichier &#8230; <a href="https://blog.developpez.com/elsuket/p12640/moteur-de-base-de-donnees-sql-server/sauvegardes-cryptees-et-dans-azure">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Microsoft a publié un <a href="http://blogs.msdn.com/b/mvpawardprogram/archive/2014/06/02/sql-server-2014-backup-encryption.aspx">article</a> que j&rsquo;ai terminé d&rsquo;écrire au début de ce mois sur ce sujet.</p>
<p>En plus du fonctionnement du cryptage des sauvegardes, j&rsquo;y détaille les étapes pour :</p>
<ol>
<li>Sauvegarder une base de données en cryptant le fichier de sauvegarde</li>
<li>Restaurer une base de données à partir d&rsquo;une fichier de sauvegarde crypté</li>
<li>Réaliser des sauvegardes cryptées dans Azure</li>
<li>Restaurer une base de données à partir d&rsquo;une sauvegarde cryptée stockée dans Azure</li>
</ol>
<p>Finalement, j&rsquo;y aborde l&rsquo;impact des divers algorithmes de cryptage sur l&rsquo;utilisation CPU et la taille des fichiers de sauvegarde.</p>
<p>L&rsquo;article est en Anglais, et je vais le traduire en Français.</p>
<p>Bonne lecture !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sauvegardes de bases de données et envoi d&#8217;email avec SQL Server Express</title>
		<link>https://blog.developpez.com/elsuket/p12612/snippets/sauvegardes-de-bases-de-donnees-et-envoi-demail-avec-sql-server-express</link>
		<comments>https://blog.developpez.com/elsuket/p12612/snippets/sauvegardes-de-bases-de-donnees-et-envoi-demail-avec-sql-server-express#comments</comments>
		<pubDate>Sun, 11 May 2014 10:01:01 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[Utilitaires]]></category>
		<category><![CDATA[assembly]]></category>
		<category><![CDATA[BACKUP]]></category>
		<category><![CDATA[sauvegarde]]></category>
		<category><![CDATA[SQL Server Express]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1006</guid>
		<description><![CDATA[Windows Server Update Services (WSUS) est une application qui permet de gérer et distribuer les patch que Microsoft publie pour ses produits. Elle est supportée par SQL Server Express (with Adanced Services), et de ce fait : On ne dispose &#8230; <a href="https://blog.developpez.com/elsuket/p12612/snippets/sauvegardes-de-bases-de-donnees-et-envoi-demail-avec-sql-server-express">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><em>Windows Server Update Services</em> (WSUS) est une application qui permet de gérer et distribuer les patch que Microsoft publie pour ses produits. Elle est supportée par SQL Server Express (with Adanced Services), et de ce fait :</p>
<ul>
<li>On ne dispose pas de l&rsquo;Agent SQL Server</li>
<li>On ne peut pas utiliser des plans de maintenance pour gérer les sauvegardes</li>
<li>On ne peut pas envoyer d&rsquo;emails</li>
<li>La compression des fichiers de backup, introduite avec SQL Server 2008, n&rsquo;est pas prise en charge</li>
</ul>
<p>Si donc on souhaite planifier les sauvegardes de base de données, et envoyer un email en cas d&rsquo;échec, on peut :</p>
<ul>
<li>Remplacer un job de l&rsquo;Agent SQL Server par une tâche du Planificateur de Tâches de Windows</li>
<li>Écrire une procédure stockée d&rsquo;assembly pour envoyer des emails</li>
</ul>
<p>Cet article détaille les étapes à suivre pour ce faire.<br />
<span id="more-1006"></span></p>
<p><span style="font-weight:bold;font-family:Verdana;font-size:18px">Une procédure stockée d&rsquo;assembly pour envoyer des emails</span></p>
<p>Si l&rsquo;Agent SQL Server n&rsquo;est pas disponible, l&rsquo;intégration CLR l&rsquo;est. Ainsi en quelques lignes de code C#, on peut envoyer des e-mails de façon assez similaire à ce qu&rsquo;on peut faire sous les éditions non-Express de SQL Server avec la procédure stockée système <em>msdb.dbo.sp_send_dbmail</em>.</p>
<p>Pour créer une procédure stockée d&rsquo;assembly sous Visual Studio 2012 ou ultérieur, il faut tout d&rsquo;abord installer <em>SQL Server Data Tools</em>. Pour ce faire, vous pouvez lire <a href="http://blog.developpez.com/elsuket/p12610/utilitaires/ssdt-bi-et-ssdt-ou-lun-ou-lautre-et-aussi-les-deux" title="SSDT-BI et SSDT : ou l’un, ou l’autre, et aussi les deux !">ce billet</a>. Notez qu&rsquo;il n&rsquo;est pas nécessaire d&rsquo;avoir Visual Studio déjà installé.</p>
<p>Une fois Visual Studio démarré, il suffit de créer un nouveau projet à partir de la page de démarrage, ou bien de suivre <em>File</em> &gt; <em>New</em> &gt; <em>Project</em>, et de choisir un projet SQL Server :</p>
<p><img src="http://i.imgur.com/3Doxf4q.png" alt="" /></p>
<p>Il faut faire attention à la version du framework .NET. Par exemple, si l&rsquo;on souhaite que l&rsquo;assembly soit exécutable par SQL Server 2008, il faut spécifier la version 3.5. Une fois que l&rsquo;on a validé le tout par OK, nous pouvons ajouter une procédure stockée :</p>
<p><img src="http://i.imgur.com/YbADCND.png" alt="" /></p>
<p>Comme je préfère C# à VB.NET, j&rsquo;ai choisi une procédure stockée C#, mais si vous préférez VB.NET, rien ne s&rsquo;y oppose. Notons que par défaut, le langage de la procédure stockée n&rsquo;est pas pré-sélectionné.</p>
<p><img src="http://i.imgur.com/Fb6O7pN.png" alt="" /></p>
<p>Une fois que l&rsquo;on a validé le tout par un clic sur <em>Add</em>, on peut écrire :</p>
<div class="codecolorer-container csharp 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="csharp codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Net</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Net.Mail</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Data</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Data.SqlClient</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">System.Data.SqlTypes</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF; font-weight: bold;">using</span> <span style="color: #008080;">Microsoft.SqlServer.Server</span><span style="color: #008000;">;</span><br />
<br />
<span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">partial</span> <span style="color: #6666cc; font-weight: bold;">class</span> StoredProcedures<br />
<span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#91;</span>Microsoft<span style="color: #008000;">.</span><span style="color: #0000FF;">SqlServer</span><span style="color: #008000;">.</span><span style="color: #0000FF;">Server</span><span style="color: #008000;">.</span><span style="color: #0000FF;">SqlProcedure</span><span style="color: #008000;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF; font-weight: bold;">public</span> <span style="color: #0600FF; font-weight: bold;">static</span> <span style="color: #6666cc; font-weight: bold;">void</span> spasb_mail_send <span style="color: #008000;">&#40;</span><span style="color: #6666cc; font-weight: bold;">string</span> sender, <span style="color: #6666cc; font-weight: bold;">string</span> recipients, <span style="color: #6666cc; font-weight: bold;">string</span> subject, <span style="color: #6666cc; font-weight: bold;">string</span> body<span style="color: #008000;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; SmtpClient mailServer <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> SmtpClient<span style="color: #008000;">&#40;</span><span style="color: #666666;">&quot;mail.myCompany.com&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; MailMessage mail <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> MailMessage<span style="color: #008000;">&#40;</span>sender, recipients, subject, body<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; mail<span style="color: #008000;">.</span><span style="color: #0000FF;">IsBodyHtml</span> <span style="color: #008000;">=</span> <span style="color: #0600FF; font-weight: bold;">true</span><span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; mailServer<span style="color: #008000;">.</span><span style="color: #0000FF;">Send</span><span style="color: #008000;">&#40;</span>mail<span style="color: #008000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">&#125;</span><br />
<span style="color: #008000;">&#125;</span></div></td></tr></tbody></table></div>
<p>Ce qui, même pour l&rsquo;ultra-débutant C# que je suis, est loin d&rsquo;être complexe. Avant de builder le projet, il nous faut configurer l&rsquo;assembly pour lui permettre d&rsquo;accéder à des ressources externes, ce qui se fait après un clic-droit sur le projet, et choisi <em>Properties</em> (ou pour les aficionados du raccourci clavier, ALT + Entrée). Dans la page <em>SQLCLR</em>, nous commutons donc la liste déroulante <em>Permission Level</em> sur EXTERNAL_ACCESS. De la même façon, dans la page <em>SQLCLR Build</em>, nous commutons la liste déroulante <em>Configuration</em> sur <em>Release</em>, ce qui permet un léger gain de performances. Ce n&rsquo;est pas très important dans notre cas, mais si l&rsquo;assembly est plus complexe, cela peut le devenir.</p>
<p><img src="http://i.imgur.com/TW1gYM4.png" alt="" /></p>
<p>Après un clic sur <em>Build</em> &gt; <em>Build Solution</em>, nous pouvons aller chercher le fichier dll dans le dossier de la solution. Dans cet exemple, il s&rsquo;agit de <em>D:\SQLServer\Assemblies\SQLServerExpressDatabaseMail\SQLServerExpressDatabaseMail\bin\Debug</em>, et le fichier est nommé <em>SQLServerExpressDatabaseMail.dll</em>.</p>
<p><img src="http://i.imgur.com/vjePpel.png" alt="" /></p>
<p>De retour dans <em>SQL Server Management Studio</em>, une fois connecté à l&rsquo;instance SQL Server Express, il est tout d&rsquo;abord nécessaire d&rsquo;activer la prise en charge de la CLR par cette dernière. Cela se fait sans redémarrage de l&rsquo;instance, en quelques instruction :</p>
<div class="codecolorer-container tsql 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="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'clr enabled'</span>, <span style="color: #000;">1</span><br />
GO<br />
<span style="color: #0000FF;">RECONFIGURE</span><br />
GO</div></td></tr></tbody></table></div>
<p>Il est maintenant requis de déclarer la base de données dans laquelle nous allons enregistrer la procédure stockée d&rsquo;assembly comme &laquo;&nbsp;digne de confiance&nbsp;&raquo;. Ceci nous permet d&rsquo;emprunter l&rsquo;identité de SQL Server pour exécuter cette procédure qui va accéder à des ressources en dehors de la base de données : en l’occurrence, un serveur de mails (mais ce peut être le système de fichiers, un webservice, &#8230;). Là encore, une simple commande suffit :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">ALTER</span> <span style="color: #0000FF;">DATABASE</span> DBA<br />
<span style="color: #0000FF;">SET</span> TRUSTW<span style="color: #808080;">OR</span>THY <span style="color: #0000FF;">ON</span><br />
GO</div></td></tr></tbody></table></div>
<p>Nous devons maintenant enregistrer l&rsquo;assembly dans la base de données, ce que l&rsquo;on peut faire une fois que l&rsquo;on a copié l&rsquo;assembly dans un dossier de notre choix, sur le serveur hébergeant l&rsquo;instance SQL Server Express / WSUS. Dans cet exemple, nous utilisons le dossier C:\SQLServer\.</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">USE</span> DBA<br />
GO<br />
<br />
<span style="color: #0000FF;">CREATE</span> ASSEMBLY SQLServerExpressDatabaseMail<br />
<span style="color: #0000FF;">FROM</span> <span style="color: #FF0000;">'C:\SQLServer\SQLServerExpressDatabaseMail.dll'</span><br />
<span style="color: #0000FF;">WITH</span> PERMISSION_SET <span style="color: #808080;">=</span> EXTERNAL_ACCESS<br />
GO</div></td></tr></tbody></table></div>
<p>On peut vérifier l&rsquo;enregistrement de l&rsquo;assembly en interrogeant la vue système <em>sys.assemblies</em>. En ce point, on n&rsquo;a plus besoin du fichier dll : le binaire de celle-ci est maintenant enregistré dans la base de données (de nom DBA dans cet exemple).<br />
Créons maintenant la procédure stockée :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">PROCEDURE</span> dbo.<span style="color: #202020;">spasb_mail_send</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @_sender <span style="color: #0000FF;">nvarchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">256</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @_recipients <span style="color: #0000FF;">nvarchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">256</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @_subject <span style="color: #0000FF;">nvarchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">256</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @_body <span style="color: #0000FF;">nvarchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">4000</span><span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">EXTERNAL</span> NAME SQLServerExpressDatabaseMail.<span style="color: #202020;">StoredProcedures</span>.<span style="color: #202020;">spasb_mail_send</span><br />
GO</div></td></tr></tbody></table></div>
<p>Et testons enfin :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">EXEC</span> dbo.<span style="color: #202020;">spasb_mail_send</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #FF0000;">'it@myCompany.com'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF0000;">'me@myCompany.com'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF0000;">'Test Mail from Assembly Stored Procedure'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF0000;">'Hey Hey !'</span></div></td></tr></tbody></table></div>
<p><span style="font-weight:bold;font-family:Verdana;font-size:18px">Une procédure stockée pour gérer les sauvegardes</span></p>
<p>Voici une procédure stockée générique qui permet de sauvegarder une base de données en particulier, ou toutes les bases de données hébergées par une instance SQL Server. Dans le second cas, les sauvegardes du fichier du journal des transactions n&rsquo;est pas supportée. En revanche, on peut exécuter cette procédure stockée sur toutes les versions de SQL Server, à partir de 2005. Enfin, le cryptage des sauvegardes, introduit avec SQL Server 2014 n&rsquo;est pas supporté non plus. Cela exige que quelques prérequis soient en place, et ceux-là sortent du cadre de cet article.</p>
<p>La procédure stockée d&rsquo;assembly est référencée dans le bloc CATCH final : pour toute erreur, on envoie un email.</p>
<div class="codecolorer-container tsql 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 />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">PROCEDURE</span> dbo.<span style="color: #202020;">databaseBackup_manage</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @_backup_type <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">12</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @_database_name <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">128</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @_backup_server_network_path <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">256</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @_print_only <span style="color: #0000FF;">bit</span> <span style="color: #808080;">=</span> <span style="color: #000;">0</span><br />
<span style="color: #0000FF;">AS</span><br />
<span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @<span style="color: #0000FF;">sql</span> <span style="color: #0000FF;">nvarchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">4000</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @err_msg <span style="color: #0000FF;">nvarchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">2048</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @compression <span style="color: #0000FF;">bit</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @checkum <span style="color: #0000FF;">bit</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @mail_subject <span style="color: #0000FF;">nvarchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">4000</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">=</span> <span style="color: #FF00FF;">@@SERVERNAME</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' Backups'</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- SQL Server 2005 ne supporte pas l'affectation directe de valeurs*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- à des variables lors de la déclaration</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; @compression <span style="color: #808080;">=</span> <span style="color: #000;">0</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span> TRY<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Gestion de la compression des sauvegardes</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- SQL Server 2008 Enterprise et Developer</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">SERVERPROPERTY</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'ProductVersion'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">32</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'10.0%'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">SERVERPROPERTY</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'Edition'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">64</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'Enterprise%'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">OR</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">SERVERPROPERTY</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'Edition'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">64</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'Developer%'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">OR</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- SQL Server 2008 R2 Enterprise, Standard et Developer</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Et toute version après celle-ci</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">SERVERPROPERTY</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'ProductVersion'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">32</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'10.50%'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">OR</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">SERVERPROPERTY</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'ProductVersion'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">32</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>, <span style="color: #000;">2</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF0000;">'.'</span>, <span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">tinyint</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">&amp;</span>gt; <span style="color: #000;">10</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">SERVERPROPERTY</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'Edition'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">64</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'Enterprise%'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">OR</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">SERVERPROPERTY</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'Edition'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">64</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'Standard%'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">OR</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">SERVERPROPERTY</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'Edition'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">64</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'Developer%'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @compression <span style="color: #808080;">=</span> <span style="color: #000;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Vérifie que le chemin réseau commence par un double anti-slash</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> @_backup_server_network_path <span style="color: #808080;">NOT</span> <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'\\%'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @err_msg <span style="color: #808080;">=</span> <span style="color: #FF0000;">'The network path '</span> <span style="color: #808080;">+</span> @_backup_server_network_path <span style="color: #808080;">+</span> <span style="color: #FF0000;">' is not valid.'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RAISERROR</span><span style="color: #808080;">&#40;</span>@err_msg, <span style="color: #000;">16</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Ajoute l'anti-slash à la fin du chemin réseau, le cas échéant</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span> @_backup_server_network_path <span style="color: #808080;">=</span> @_backup_server_network_path <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> <span style="color: #FF00FF;">CHARINDEX</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'\'</span>, <span style="color: #FF00FF;">REVERSE</span><span style="color: #808080;">&#40;</span>@_backup_server_network_path<span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">&amp;</span>gt; <span style="color: #000;">1</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'\'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">''</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> @_database_name <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">--------------------------------------------------</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Sauvegarde d'une base de données en particulier</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">--------------------------------------------------</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">EXISTS</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">databases</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; name <span style="color: #808080;">=</span> @_database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @err_msg <span style="color: #808080;">=</span> <span style="color: #FF0000;">'La base de données '</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @_database_name <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">' n'</span><span style="color: #FF0000;">'existe pas.'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RAISERROR</span><span style="color: #808080;">&#40;</span>@err_msg, <span style="color: #000;">16</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">EXISTS</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">databases</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; name <span style="color: #808080;">=</span> @_database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; state_desc <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ONLINE'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; user_access_desc <span style="color: #808080;">=</span> <span style="color: #FF0000;">'MULTI_USER'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; source_database_id <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span> <span style="color: #008080;">-- La base de données n'est pas un snapshot</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; database_id &nbsp;<span style="color: #000;">2</span> <span style="color: #008080;">-- La base de données n'est pas TempDB</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @err_msg <span style="color: #808080;">=</span> <span style="color: #FF0000;">'La base de données '</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @_database_name <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">' n'</span><span style="color: #FF0000;">'est pas disponible ou est une capture intantanée.'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RAISERROR</span><span style="color: #808080;">&#40;</span>@err_msg, <span style="color: #000;">16</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Vérifie le type de backup</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> @_backup_type <span style="color: #808080;">NOT</span> <span style="color: #808080;">IN</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'FULL'</span>, <span style="color: #FF0000;">'DIFFERENTIAL'</span>, <span style="color: #FF0000;">'LOG'</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @err_msg <span style="color: #808080;">=</span> <span style="color: #FF0000;">'The backup type '</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @_backup_type <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">' is invalid.'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RAISERROR</span><span style="color: #808080;">&#40;</span>@err_msg, <span style="color: #000;">16</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @<span style="color: #0000FF;">sql</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'BACKUP '</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> @_backup_type <span style="color: #808080;">IN</span> <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'FULL'</span>, <span style="color: #FF0000;">'DIFFERENTIAL'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'DATABASE '</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> @_backup_type <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LOG'</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'LOG '</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> <span style="color: #808080;">+</span> @_database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">' TO DISK = '</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @_backup_server_network_path <span style="color: #808080;">+</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@SERVERNAME</span>, <span style="color: #FF0000;">'\'</span>, <span style="color: #FF0000;">'_'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'\'</span> <span style="color: #808080;">+</span> @_database_name <span style="color: #808080;">+</span> <span style="color: #FF0000;">'_'</span> <span style="color: #808080;">+</span> @_backup_type <span style="color: #808080;">+</span> <span style="color: #FF0000;">'_'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">char</span><span style="color: #808080;">&#40;</span><span style="color: #000;">19</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #000;">120</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF0000;">':'</span>, <span style="color: #FF0000;">'-'</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF0000;">' '</span>, <span style="color: #FF0000;">'_'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.bak'</span><span style="color: #FF0000;">''</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">' WITH '</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span> @_backup_type<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> <span style="color: #FF0000;">'DIFFERENTIAL'</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'DIFFERENTIAL, '</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> <span style="color: #FF0000;">'FULL'</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'INIT, '</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">''</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span> @compression <span style="color: #0000FF;">WHEN</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'COMPRESSION, '</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">''</span> <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">'CHECKSUM'</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> @_print_only <span style="color: #808080;">=</span> <span style="color: #000;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">PRINT</span> @<span style="color: #0000FF;">sql</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span> TRY<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">sp_executesql</span> @<span style="color: #0000FF;">sql</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> TRY<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span> CATCH<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @err_msg <span style="color: #808080;">=</span> @_database_name <span style="color: #808080;">+</span> <span style="color: #FF0000;">' | '</span> <span style="color: #808080;">+</span> ERR<span style="color: #808080;">OR</span>_MESSAGE<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RAISERROR</span><span style="color: #808080;">&#40;</span>@err_msg, <span style="color: #000;">16</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> CATCH<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">--------------------------------------------------------</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Sauvegarde de toutes les bases de données disponibles</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">--------------------------------------------------------</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> @_backup_type <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LOG'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @err_msg <span style="color: #808080;">=</span> <span style="color: #FF0000;">'On ne prend pas une sauvegarde du fichier du journal des transactions de toutes les bases de données.'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RAISERROR</span><span style="color: #808080;">&#40;</span>@err_msg, <span style="color: #000;">16</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @database_list <span style="color: #0000FF;">TABLE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; database_name <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">128</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @database_list<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span>name, <span style="color: #FF0000;">' '</span>, <span style="color: #FF0000;">''</span><span style="color: #808080;">&#41;</span> <span style="color: #008080;">-- Certaines bases de données ne respectent pas la convention de nommage SQL ANSI.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">databases</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; source_database_id <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span> <span style="color: #008080;">-- La base de données n'est pas un snapshot</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; state_desc <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ONLINE'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; user_access_desc <span style="color: #808080;">=</span> <span style="color: #FF0000;">'MULTI_USER'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; database_id &nbsp;<span style="color: #000;">2</span> <span style="color: #008080;">-- On exclut TempDB</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHILE</span> <span style="color: #808080;">EXISTS</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; @database_list<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span> @_database_name <span style="color: #808080;">=</span> database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; @database_list<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @<span style="color: #0000FF;">sql</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'BACKUP DATABASE '</span> <span style="color: #808080;">+</span> @_database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">' TO DISK = '</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @_backup_server_network_path <span style="color: #808080;">+</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">@@SERVERNAME</span>, <span style="color: #FF0000;">'\'</span>, <span style="color: #FF0000;">'_'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'\'</span> <span style="color: #808080;">+</span> @_database_name <span style="color: #808080;">+</span> <span style="color: #FF0000;">'_'</span> <span style="color: #808080;">+</span> @_backup_type <span style="color: #808080;">+</span> <span style="color: #FF0000;">'_'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">REPLACE</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">CONVERT</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">char</span><span style="color: #808080;">&#40;</span><span style="color: #000;">19</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #000;">120</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF0000;">':'</span>, <span style="color: #FF0000;">'-'</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF0000;">' '</span>, <span style="color: #FF0000;">'_'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.bak'</span><span style="color: #FF0000;">''</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">' WITH '</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span> @_backup_type<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> <span style="color: #FF0000;">'DIFFERENTIAL'</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'DIFFERENTIAL, '</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> <span style="color: #FF0000;">'FULL'</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'INIT, '</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CASE</span> @compression <span style="color: #0000FF;">WHEN</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'COMPRESSION, '</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">''</span> <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">+</span> <span style="color: #FF0000;">'CHECKSUM'</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> @_print_only <span style="color: #808080;">=</span> <span style="color: #000;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">PRINT</span> @<span style="color: #0000FF;">sql</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span> TRY<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">sp_executesql</span> @<span style="color: #0000FF;">sql</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> TRY<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span> CATCH<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @err_msg <span style="color: #808080;">=</span> @_database_name <span style="color: #808080;">+</span> <span style="color: #FF0000;">' | '</span> <span style="color: #808080;">+</span> ERR<span style="color: #808080;">OR</span>_MESSAGE<span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RAISERROR</span><span style="color: #808080;">&#40;</span>@err_msg, <span style="color: #000;">16</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> CATCH<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DELETE</span>&nbsp; <span style="color: #0000FF;">FROM</span> @database_list<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; database_name <span style="color: #808080;">=</span> @_database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> TRY<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span> CATCH<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Envoie un email en cas d'erreur</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span> dbo.<span style="color: #202020;">spasb_mail_send</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @_sender <span style="color: #808080;">=</span> <span style="color: #FF0000;">'it@myCompany.com'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @_recipients <span style="color: #808080;">=</span> <span style="color: #FF0000;">'it@myCompany.com'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @_subject <span style="color: #808080;">=</span> @mail_subject<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @_body <span style="color: #808080;">=</span> @err_msg<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> CATCH<br />
<span style="color: #0000FF;">END</span></div></td></tr></tbody></table></div>
<p><span style="font-weight:bold;font-family:Verdana;font-size:18px">Remplacer l&rsquo;Agent SQL Server par le Planificateur de Tâches de Windows</span></p>
<p>Nous voilà à l&rsquo;étape finale : prendre des sauvegardes de base de données régulièrement. Pour ce faire, on peut tout à fait utiliser le <em>Planificateur de Tâches de Windows</em> : en effet, on peut appeler l&rsquo;utilitaire en ligne de commandes <em>SQLCMD</em> (la <a href="http://technet.microsoft.com/fr-fr/library/ms162773.aspx">documentation</a>, l&rsquo;<a href="http://technet.microsoft.com/fr-fr/library/ms180944.aspx">utilisation</a>, et un <a href="http://technet.microsoft.com/fr-fr/library/ms170207%28v=sql.105%29.aspx">exemple</a>), qui permet d&rsquo;interagir avec une instance SQL Server. Cet outil permet de passer en paramètre un script, d&rsquo;exécuter une requête, mais surtout d&rsquo;enregistrer la sortie dans un fichier. Cette dernière fonctionnalité facilite la tâche d&rsquo;investigation sur l&rsquo;échec d&rsquo;exécution de code.</p>
<p>Une fois l&rsquo;application <em>Planificateur de Tâches</em> démarrée, on créé une tâche assez simplement :</p>
<p><img src="http://i.imgur.com/ZSHAIHP.png" alt="" /></p>
<p>Une fois passé la première page ou nous nommons la tâche, un clic sur <em>Next</em> nous amène à la planification. Pour <em>Windows Server Update Services</em>, on peut estimer qu&rsquo;une sauvegarde complète par jour est suffisante. Évidemment, cela varie avec la criticité de l&rsquo;application. Nous spécifions donc une exécution quotidienne :</p>
<p><img src="http://i.imgur.com/QdAUdsn.png" alt="" /></p>
<p>Nous planifions l&rsquo;exécution à minuit et une minute :</p>
<p><img src="http://i.imgur.com/JXOESBU.png" alt="" /></p>
<p>Et nous choisissons de démarrer une application :</p>
<p><img src="http://i.imgur.com/ImwrMln.png" alt="" /></p>
<p>Dans la saisie texte <em>Program / Script</em>, nous spécifions l&rsquo;invite de commandes. En ce qui concerne les arguments, nous écrivons :</p>
<ul>
<li>Pour SQL Server 2008 :<br />
<code class="codecolorer dos default"><span class="dos">&quot;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE&quot;</span></code></li>
<li>Pour SQL Server 2012 :<br />
<code class="codecolorer dos default"><span class="dos">&quot;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\SQLCMD.EXE&quot;</span></code></li>
<li>Pour SQL Server 2014 :<br />
<code class="codecolorer dos default"><span class="dos">&quot;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn\SQLCMD.EXE&quot;</span></code></li>
</ul>
<p>En ce qui concerne les arguments, nous passons :</p>
<p><code class="codecolorer dos default"><span class="dos">sqlcmd -E -S WSUS -i &quot;C:\SQLServer\WSUSBackup.sql&quot; -o &quot;C:\SQLServerBackup\FullBackupLog.txt&quot;</span></code></p>
<p>Attention, la casse des options est importante.</p>
<ul>
<li>-E pour spécifier une connexion approuvée</li>
<li>-S : l&rsquo;instance SQL Server à laquelle on souhaite se connecter</li>
<li>-i : le chemin et le nom du fichier de script T-SQL</li>
<li>-o : le fichier qui capturera les libellés des messages d&rsquo;information, d&rsquo;avertissement ou d&rsquo;erreurs, le cas échéant</li>
</ul>
<p>Ce qui donne :</p>
<p><img src="http://i.imgur.com/6I12ozL.png" alt="" /></p>
<p>Un clic sur <em>Next</em> nous offre une fenêtre de résumé, et on peut valider le tout. Si l&rsquo;on souhaite ajouter des planifications ou modifier d&rsquo;autres options pour cette tâche, il suffit de cocher la case <em>Open the Properties dialog for this task when I click Finish</em>.</p>
<p>Nous créons ensuite un fichier <em>WSUSBackup.sql</em> dans un répertoire <em>C:\SQLServer\</em> sur la machine qui héberge l&rsquo;application WSUS. Ce fichier appelle la procédure stockée <em>DBA.dbo.databaseBackup_manage</em> comme suit :</p>
<p><code class="codecolorer text default"><span class="text">EXEC DBA.dbo.databaseBackup_manage 'FULL', NULL, '\\monPartageDeBackup\', 0</span></code></p>
<p>Et voilà nos sauvegardes de base de données en place.</p>
<p><span style="font-weight:bold;font-family:Verdana;font-size:18px">Utiliser PowerShell pour supprimer les fichiers de sauvegardes trop anciens</span></p>
<p>Dans la liste des actions de la tâche que nous venons de créer, nous pouvons en ajouter une qui aura :</p>
<ul>
<li>Pour programme : <code class="codecolorer text default"><span class="text">powershell</span></code></li>
<li>Pour arguments : <code class="codecolorer text default"><span class="text">-file &quot;C:\SQLServer\DeleteOldBackupFiles.ps1&quot;</span></code></li>
</ul>
<p>Le fichier <em>DeleteOldBackupFiles.ps1</em> contient la commande suivante, qui supprime tous les fichiers créés il y a plus de 7 jours, y compris dans les sous-dossiers du partage de backup (-Recurse) :</p>
<p><code class="codecolorer powershell default"><span class="powershell"><span style="color: #008080; font-weight: bold;">Get-ChildItem</span> <span style="color: #800000;">'\\monPartageDeBackup\'</span> <span style="color: #008080; font-style: italic;">-Recurse</span> <span style="color: pink;">|</span> <span style="color: #0000FF;">Where</span> <span style="color: #000000;">&#123;</span><span style="color: #000080;">$_</span>.CreationTime <span style="color: #FF0000;">-lt</span> <span style="color: #000000;">&#40;</span><span style="color: #008080; font-weight: bold;">Get-Date</span><span style="color: #000000;">&#41;</span>.AddDays<span style="color: #000000;">&#40;</span><span style="color: pink;">-</span><span style="color: #804000;">7</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#125;</span> <span style="color: pink;">|</span> <span style="color: #008080; font-weight: bold;">Remove-Item</span> <span style="color: #008080; font-style: italic;">-Force</span></span></code></p>
<p>Par défaut, PowerShell ne permet pas l&rsquo;exécution de scripts. Pour l&rsquo;autoriser, il faut démarrer l&rsquo;interface PowerShell, et exécuter <code class="codecolorer powershell default"><span class="powershell"><span style="color: #008080; font-weight: bold;">Set-ExecutionPolicy</span> RemoteSigned</span></code> (en accord avec votre Administrateur Systèmes !).</p>
<p>Retenons également que les statistiques de colonne et d&rsquo;index de la base de données supportant WSUS ne sont pas maintenues. Ce sera probablement suffisant pour générer une lenteur après quelques mois d&rsquo;exploitation, dont votre Administrateur Systèmes vous demandera l&rsquo;origine <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>SSDT-BI et SSDT : ou l&#8217;un, ou l&#8217;autre, et aussi les deux !</title>
		<link>https://blog.developpez.com/elsuket/p12610/utilitaires/ssdt-bi-et-ssdt-ou-lun-ou-lautre-et-aussi-les-deux</link>
		<comments>https://blog.developpez.com/elsuket/p12610/utilitaires/ssdt-bi-et-ssdt-ou-lun-ou-lautre-et-aussi-les-deux#comments</comments>
		<pubDate>Fri, 09 May 2014 17:40:23 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Assembly & CLR]]></category>
		<category><![CDATA[SQL Server Analysis Services]]></category>
		<category><![CDATA[SQL Server Integration Services]]></category>
		<category><![CDATA[SQL Server Reporting Services]]></category>
		<category><![CDATA[Utilitaires]]></category>
		<category><![CDATA[Business Intelligence]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[SQL Server Data Tools]]></category>
		<category><![CDATA[SSDT]]></category>
		<category><![CDATA[Support Décisionnel]]></category>
		<category><![CDATA[Visual Studio]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=1000</guid>
		<description><![CDATA[SQL Server Business Intelligence Studio a été remplacé par SQL Server Data Tools (SSDT). SSDT a été mis en ligne pour la première fois pour Visual Studio 2010, qu&#8217;il installait en mode Shell. Cette version n&#8217;est maintenant plus disponible, mais &#8230; <a href="https://blog.developpez.com/elsuket/p12610/utilitaires/ssdt-bi-et-ssdt-ou-lun-ou-lautre-et-aussi-les-deux">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><em>SQL Server Business Intelligence Studio</em> a été remplacé par <a href="http://blog.developpez.com/elsuket/p12489/indexation/pivot-ssdt-attention-ordre" title="La transformation Pivot avec SQL Server Data Tools (ex SSIS) : attention à l’ordre !">SQL Server Data Tools</a> (SSDT).</p>
<p>SSDT a été mis en ligne pour la première fois pour Visual Studio 2010, qu&rsquo;il installait en mode Shell. Cette version n&rsquo;est maintenant plus disponible, mais on la trouve bien entendu pour Visual Studio 2012 (<a href="http://www.microsoft.com/fr-fr/download/details.aspx?id=36843">fr</a>/<a href="http://www.microsoft.com/en-us/download/details.aspx?id=36843">en</a>) et 2013 (<a href="http://www.microsoft.com/fr-fr/download/details.aspx?id=42313">fr</a>/<a href="http://www.microsoft.com/en-us/download/details.aspx?id=42313">en</a>).</p>
<p>Ce dernier est en fait décliné en deux opus, l&rsquo;un dédié à la Business Intelligence, abrévié en SSDT-BI, et l&rsquo;autre SSDT tout court. Les deux versions installent toujours Visual Studio en mode Shell, mais la version BI n&rsquo;installe pas les composants nécessaires au développement d&rsquo;un projet d&rsquo;assembly SQL Server. Et inversement.</p>
<p>J&rsquo;avais donc installé SSDT-BI 2012 sans noter que le projet de type SQL Server n&rsquo;était pas présent. J&rsquo;ai donc installé SSDT 2012 (téléchargeable <a href="http://msdn.microsoft.com/en-us/data/hh297027">ici</a> en version 2012 et 2013), et j&rsquo;ai maintenant ce qui me manquait :</p>
<p><img src="http://i.imgur.com/JNW6bZz.png" alt="" /></p>
<p>Bon développement SQL Server !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La transformation Pivot avec SQL Server Data Tools (ex SSIS) : attention à l&#8217;ordre !</title>
		<link>https://blog.developpez.com/elsuket/p12489/moteur-de-base-de-donnees-sql-server/indexation/pivot-ssdt-attention-ordre</link>
		<comments>https://blog.developpez.com/elsuket/p12489/moteur-de-base-de-donnees-sql-server/indexation/pivot-ssdt-attention-ordre#comments</comments>
		<pubDate>Sat, 15 Feb 2014 10:08:17 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=870</guid>
		<description><![CDATA[SQL Server Data Tools (SSDT) est le nouveau nom de SQL Server Integration Services (SSIS). Je ne suis pas un supporter des opérateurs T-SQL PIVOT et UNPIVOT, pour la simple et bonne raison qu&#8217;il ne sont pas ensemblistes, et servent &#8230; <a href="https://blog.developpez.com/elsuket/p12489/moteur-de-base-de-donnees-sql-server/indexation/pivot-ssdt-attention-ordre">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>SQL Server Data Tools (SSDT) est le nouveau nom de SQL Server Integration Services (SSIS).<br />
Je ne suis pas un supporter des opérateurs T-SQL PIVOT et UNPIVOT, pour la simple et bonne raison qu&rsquo;il ne sont pas ensemblistes, et servent seulement à la présentation de données. Néanmoins, on conçoit aisément que ce sont des opérateurs utiles pour du chargement de données, surtout dans un environnement d&rsquo;entrepôt de données. J&rsquo;ai donc décidé de savoir ce qu&rsquo;il faut faire sous SSDT pour &laquo;&nbsp;pivoter&nbsp;&raquo; un jeu de données.<br />
<span id="more-870"></span><br />
Pour avoir un jeu de données à pivoter, j&rsquo;ai installé la base de données AdventureWorksDW2012, que l&rsquo;on trouve sur <a href="http://msftdbprodsamples.codeplex.com/releases/view/55330">CodePlex</a>. Pour voir comment installer cette base de données dans une instance de SQL Server, suivez le <a href="http://blog.developpez.com/elsuket/p11188/moteur-de-base-de-donnees-sql-server/attacher_base_donnees_sans_tran_log">guide</a>.</p>
<p>Nous démarrons donc en ajoutant une <em>Tâche de Flux de Données</em> dans le <em>Contrôle de Flux</em> par simple glisser-déposer (je débute avec SSDT / SSIS !) :</p>
<p><img src="http://imageshack.com/a/img835/2359/ptji.png" alt="" /></p>
<p>Dans le panneau Flux de Données, nous ajoutons maintenant une source de données ADO.NET de la même façon, puis double-cliquons dessus pour la configurer.<br />
Il nous faut tout d&rsquo;abord créer une connexion à la base de données AdventureWorksDW2012. Pour cela, nous cliquons sur <em>Nouveau &#8230;</em></p>
<p><img src="http://imageshack.com/a/img132/6080/5ou3.png" alt="" /></p>
<p>Comme nous n&rsquo;avons pas encore de connexion, nous cliquons une nouvelle fois sur le bouton <em>Nouveau</em> dans la fenêtre &laquo;&nbsp;Configurer un Gestionnaire de Connexion ADO.NET&nbsp;&raquo;, et nous obtenons la fenêtre suivante :</p>
<p><img src="http://imageshack.com/a/img69/1426/qou3.png" alt="" /></p>
<p><img src="http://imageshack.com/a/img706/1686/nckp.png" alt="" /></p>
<p>Nous validons alors le tout, et nous retrouvons dans l&rsquo;éditeur de Source ADO.NET, ou nous pouvons choisir de traiter les données extraites directement d&rsquo;une table ou d&rsquo;une vue, ou bien de spécifier une requête. Nous choisissons cette dernière option :</p>
<p><img src="http://imageshack.com/a/img594/5356/7ypz.png" alt="" /></p>
<p>Voici donc la requête, que nous collons dans l&rsquo;éditeur de Source ADO.NET, et son résultat sous SQL Server Management Studio :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PC.<span style="color: #202020;">EnglishProductCategoryName</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span>F.<span style="color: #202020;">OrderDateKey</span>, <span style="color: #000;">4</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> OrderYear<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">SUM</span><span style="color: #808080;">&#40;</span>F.<span style="color: #202020;">SalesAmount</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> SalesAmount<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbo.<span style="color: #202020;">FactResellerSales</span> <span style="color: #0000FF;">AS</span> F<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; dbo.<span style="color: #202020;">DimProduct</span> <span style="color: #0000FF;">AS</span> P<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> F.<span style="color: #202020;">ProductKey</span> <span style="color: #808080;">=</span> P.<span style="color: #202020;">ProductKey</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; dbo.<span style="color: #202020;">DimProductSubcategory</span> <span style="color: #0000FF;">AS</span> PS<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> P.<span style="color: #202020;">ProductSubcategoryKey</span> <span style="color: #808080;">=</span> PS.<span style="color: #202020;">ProductSubcategoryKey</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; dbo.<span style="color: #202020;">DimProductCategory</span> <span style="color: #0000FF;">AS</span> PC<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> PS.<span style="color: #202020;">ProductCategoryKey</span> <span style="color: #808080;">=</span> PC.<span style="color: #202020;">ProductCategoryKey</span><br />
<span style="color: #0000FF;">GROUP</span> <span style="color: #0000FF;">BY</span>&nbsp; &nbsp; &nbsp; &nbsp; PC.<span style="color: #202020;">EnglishProductCategoryName</span>, <span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span>F.<span style="color: #202020;">OrderDateKey</span>, <span style="color: #000;">4</span><span style="color: #808080;">&#41;</span></div></td></tr></tbody></table></div>
<p><img src="http://imageshack.com/a/img812/7338/80pd.png" alt="" /></p>
<p>Notre but des donc d&rsquo;obtenir une jeu de données avec les colonnes suivantes :</p>
<p>&#8211; 4 lignes, dont la colonne contiendra des valeurs uniques suivantes (<em>Components</em>, <em>Bikes</em>, <em>Clothing</em> et <em>Accessories</em>)<br />
&#8211; 5 colonnes, dont 4 pour les années 2005 à 2008, et une pour le volume de vente (<em>SalesAmount</em>)</p>
<p>Nous obtenons l&rsquo;interface suivante, qui nous permet de spécifier les caractéristiques de l&rsquo;opération de pivot :</p>
<p><img src="http://imageshack.com/a/img843/6627/7cxz.png" alt="" /></p>
<p>Nous validons par le bouton <em>OK</em>, puis passons sous l&rsquo;éditeur avancé :</p>
<p><img src="http://imageshack.com/a/img850/1875/5lut.png" alt="" /></p>
<p>En basculant sous l&rsquo;onglet <em>Propriétés d&rsquo;entrée / sortie</em>, on s&rsquo;aperçoit qu&rsquo;il va manquer des colonnes. En effet, les colonnes des années ne sont pas dans la sortie du pivot :</p>
<p><img src="http://imageshack.com/a/img69/8035/yp60.png" alt="" /></p>
<p>Notons ici la valeur <em>LineageID</em>, qui nous permettra d&rsquo;indiquer par la suite la colonne de la source de données pour la sortie du pivot. Dans cet exemple, c&rsquo;est 22. Nous ajoutons donc 4 colonnes, 2005, 2006, 2007 et 2008, avec le modèle suivant :</p>
<p><img src="http://imageshack.com/a/img703/1378/8phu.png" alt="" /></p>
<p>Nous obtenons donc :</p>
<p><img src="http://imageshack.com/a/img713/5834/nrse.png" alt="" /></p>
<p>Comme nous ne souhaitons pas stocker les données en sortie, mais seulement voir ce que le moteur fait, nous pouvons ajouter comme destination un compteur de lignes :</p>
<p><img src="http://imageshack.com/a/img706/2964/fof8.png" alt="" /></p>
<p>Comme le libellé de l&rsquo;erreur l&rsquo;indique, nous devons créer une variable pour stocker le nombre de lignes retournés en sortie de l&rsquo;opérateur pivot. Pour ce faire, il suffit d&rsquo;utiliser la fenêtre des variables (<em>Affichage</em> &gt; <em>Autres fenêtres</em> &gt; <em>Variables</em>) du paquetage, que nous appelons <em>rowCount</em>.</p>
<p><img src="http://imageshack.com/a/img541/2246/johz.png" alt="" /></p>
<p>Une fois fait, il nous suffit de double-cliquer sur la destination pour pouvoir spécifier la variable :</p>
<p><img src="http://imageshack.com/a/img835/2987/mfhf.png" alt="" /></p>
<p>Après avoir validé par <em>OK</em>, nous pouvons activer la visionneuse de données sur les deux pipelines, par un simple clic-droit sur chacun d&rsquo;entre-eux- Ceci nous permettra de visualiser la transformation :</p>
<p><img src="http://imageshack.com/a/img834/8379/zybt.png" alt="" /></p>
<p>Voici ce qui se passe à l&rsquo;exécution du paquetage :</p>
<p><img src="http://imageshack.com/a/img845/1959/lkw4.png" alt="" /></p>
<p>La visionneuse de gauche nous montre les données avant le pivot, et celle de droite après. On voit bien que la transformation est plus proche d&rsquo;une matrice que d&rsquo;un pivot. Ceci est dû au fait que l&rsquo;on n&rsquo;a pas ordonné les données suivant le libellé de la catégorie : dès lors, le groupement des lignes suivant ce critère n&rsquo;est pas fait. Nous cliquons sur le bouton Lecture, et comme le tampon ne contient que quelques lignes, l&rsquo;exécution du paquetage continue et se termine presque immédiatement, sans erreur.</p>
<p>Comme bien souvent dans l&rsquo;environnement SQL Server, on dispose de plusieurs possibilités pour remédier à ceci : soit ajouter une clause ORDER BY	PC.EnglishProductCategoryName à la requête, soit ajouter un opérateur de tri dans SSIS. C&rsquo;est cette dernière option que nous choisissons, puisqu&rsquo;en SQL, il n&rsquo;y a normalement pas d&rsquo;ordre.</p>
<p>Nous intercalons donc un opérateur de tri :</p>
<p><img src="http://imageshack.com/a/img809/460/u56o.png" alt="" /></p>
<p>Et nous le configurons pour que le tri se fasse suivant la colonne <em>EnglishProductCategoryName</em>; par défaut le tri est ascendant :</p>
<p><img src="http://imageshack.com/a/img268/9697/5iw5.png" alt="" /></p>
<p>Nous ré-exécutons le paquetage, dont il ne nous reste plus que la visionneuse de données en sortie du pivot. Nous obtenons alors le résultat escompté :</p>
<p><img src="http://imageshack.com/a/img850/2084/ulzv.png" alt="" /></p>
<p>Bons pivots de données avec SSDT !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trouver le port d&#8217;écoute d&#8217;une instance SQL Server (avec une requête)</title>
		<link>https://blog.developpez.com/elsuket/p12285/moteur-de-base-de-donnees-sql-server/trouver-le-port-decoute-dune-instance-sql-server-avec-une-requete</link>
		<comments>https://blog.developpez.com/elsuket/p12285/moteur-de-base-de-donnees-sql-server/trouver-le-port-decoute-dune-instance-sql-server-avec-une-requete#comments</comments>
		<pubDate>Fri, 18 Oct 2013 09:51:13 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=839</guid>
		<description><![CDATA[Le service SQL Browser permet d&#8217;obtenir la liste des instances SQL Server ainsi que leur port d&#8217;écoute. Pour des raisons de sécurité, on peut donc vouloir désactiver ce service, mais il nous faut auparavant connaître le port d&#8217;écoute de chacune &#8230; <a href="https://blog.developpez.com/elsuket/p12285/moteur-de-base-de-donnees-sql-server/trouver-le-port-decoute-dune-instance-sql-server-avec-une-requete">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Le service SQL Browser permet d&rsquo;obtenir la liste des instances SQL Server ainsi que leur port d&rsquo;écoute. Pour des raisons de sécurité, on peut donc vouloir désactiver ce service, mais il nous faut auparavant connaître le port d&rsquo;écoute de chacune d&rsquo;entre elles : par défaut, le port d&rsquo;écoute de l&rsquo;instance par défaut est 1433. Si l&rsquo;on dispose de plusieurs instances SQL Server installées sur une même machine, chacune dispose d&rsquo;un port qui lui est dédié. Voici donc une requête qui vous permet de retrouver le port d&rsquo;écoute d&rsquo;une instance SQL Server en particulier.<br />
<span id="more-839"></span><br />
Cette requête n&rsquo;est pas des plus orthodoxes puisqu&rsquo;elle fait appel à la procédure stockée étendue système xp_regread. Cela étant, elle permet de retrouver le port d&rsquo;écoute d&rsquo;une instance SQL Server instantanément :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">DECLARE</span> @TCP_port <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">5</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @registry_path <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">100</span><span style="color: #808080;">&#41;</span><br />
<br />
<span style="color: #0000FF;">SELECT</span> @registry_path <span style="color: #808080;">=</span> <span style="color: #0000FF;">CASE</span> <span style="color: #FF00FF;">@@SERVICENAME</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> <span style="color: #FF0000;">'MSSQLSERVER'</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'SOFTWARE\Microsoft\MSSQLSERVER\MSSQLSERVER\SuperSocketNetLib\TCP'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">'SOFTWARE\Microsoft\Microsoft SQL Server\'</span> <span style="color: #808080;">+</span> <span style="color: #FF00FF;">@@SERVICENAME</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'\MSSQLServer\SuperSocketNetLib\TCP'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<br />
<span style="color: #0000FF;">EXEC</span> master.<span style="color: #202020;">dbo</span>.<span style="color: #202020;">xp_regread</span><br />
&nbsp; &nbsp; @rootkey <span style="color: #808080;">=</span> <span style="color: #FF0000;">'HKEY_LOCAL_MACHINE'</span><br />
&nbsp; &nbsp; , @<span style="color: #0000FF;">key</span> <span style="color: #808080;">=</span> @registry_path<br />
&nbsp; &nbsp; , @value_name <span style="color: #808080;">=</span> <span style="color: #FF0000;">'TcpPort'</span><br />
&nbsp; &nbsp; , @<span style="color: #0000FF;">value</span> <span style="color: #808080;">=</span> @TCP_port <span style="color: #0000FF;">OUTPUT</span><br />
<br />
<span style="color: #0000FF;">SELECT</span> @TCP_port <span style="color: #0000FF;">AS</span> PortNumber<br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">@@SERVERNAME</span> <span style="color: #0000FF;">AS</span> ServerName<br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">@@SERVICENAME</span> <span style="color: #0000FF;">AS</span> ServiceName</div></td></tr></tbody></table></div>
<p>Lorsque l&rsquo;on a le service SQL Browser désactivé, on peut se connecter à une instance nommée en précisant le nom du serveur + virgule + le numéro de port. Par exemple, si nous disposons d&rsquo;un serveur ELSUKETW8 doté d&rsquo;une instance nommée SQL2012 qui écoute les connexions sur le port 62549, alors dans la chaîne de connexion de nos applications, nous devons remplacer Server=ELSUKETW8\SQL2012 par Server=ELSUKETW8,62549.</p>
<p>Bon routage à 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>L&#8217;escalade de verrous</title>
		<link>https://blog.developpez.com/elsuket/p12108/moteur-de-base-de-donnees-sql-server/lescalade-de-verrous</link>
		<comments>https://blog.developpez.com/elsuket/p12108/moteur-de-base-de-donnees-sql-server/lescalade-de-verrous#comments</comments>
		<pubDate>Sun, 07 Jul 2013 12:09:41 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[1204]]></category>
		<category><![CDATA[CACHESTORE_OBJCP]]></category>
		<category><![CDATA[CACHESTORE_SQLCP]]></category>
		<category><![CDATA[escalade]]></category>
		<category><![CDATA[escalation]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[lock_escalation_desc]]></category>
		<category><![CDATA[OBJECTSTORE_LOCK_MANAGER]]></category>
		<category><![CDATA[sys.dm_os_memory_clerks]]></category>
		<category><![CDATA[verrou]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=709</guid>
		<description><![CDATA[Quoi de plus naturel pour un moteur de base de données relationnelles SQL que le verrouillage ? En effet, toute exécution de requête entraîne l&#8217;acquisition de verrous. Comme je me rends compte que c&#8217;est un sujet quelque peu méconnu, je &#8230; <a href="https://blog.developpez.com/elsuket/p12108/moteur-de-base-de-donnees-sql-server/lescalade-de-verrous">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Quoi de plus naturel pour un moteur de base de données relationnelles SQL que le verrouillage ? En effet, toute exécution de requête entraîne l&rsquo;acquisition de verrous. Comme je me rends compte que c&rsquo;est un sujet quelque peu méconnu, je vous propose ici d&rsquo;explorer dans quelles conditions une escalade de verrous se produit, après avoir succinctement décrit ce qu&rsquo;est le verrouillage.</p>
<p><span id="more-709"></span></p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Qu&rsquo;est-ce que le verrouillage ?</strong></p>
<p>Le verrouillage est un mécanisme qui permet à plusieurs utilisateurs d&rsquo;accéder à des ressources, tout en évitant que cela résulte en des incohérences de données. Des verrous sont acquis lorsque le moteur de base de données a besoin d&rsquo;accéder à une ressource pour la lire ou la modifier. Sous SQL Server, cette opération est purement logique, et sert le support de l&rsquo;<a href="http://fr.wikipedia.org/wiki/Propri%C3%A9t%C3%A9s_ACID">ACIDité</a> de toute transaction.</p>
<p>Ce mécanisme est entièrement géré par le moteur de stockage de SQL Server, avec lequel l&rsquo;utilisateur n&rsquo;a que peu de moyens d&rsquo;interagir (et tant mieux !).<br />
On peut bien sûr affecter le comportement d&rsquo;une transaction en indiquant le <a href="http://msdn.microsoft.com/fr-fr/library/ms173763.aspx">niveau d&rsquo;isolation de transaction</a> sous lequel elle doit être traitée. Il est rarement nécessaire d&rsquo;indiquer à SQL Server quel doit être le type de verrouillage à choisir à l&rsquo;aide d&rsquo;indicateurs <a href="http://msdn.microsoft.com/fr-fr/library/ms187373%28v=sql.110%29.aspx">de table</a> ou <a href="http://msdn.microsoft.com/fr-fr/library/ms181714.aspx">de requête</a>. SQL Server a de toute façon la primauté sur ce choix, puisqu&rsquo;il outrepasse parfois les recommandations du développeur ou du DBA. Globalement, le moteur de base de données SQL Server effectue le meilleur choix.</p>
<p>Tout ceci fait qu&rsquo;outre le niveau d&rsquo;isolation de transaction, lorsqu&rsquo;on code pour SQL Server, on n&rsquo;a pas à se soucier de ce que telle ou telle opération DML va produire en termes de verrouillage. Cependant, l&rsquo;accès concurrent à une même ressource provoque parfois des situations de <a href="http://blog.developpez.com/elsuket/p12049/snippets/auditer-les-processus-bloques-levenement-blocked-process-report" title="Auditer les processus bloqués : l’événement blocked process report" target="_blank">blocage</a>, voire d&rsquo;<a href="http://blog.developpez.com/elsuket/p7610/moteur-de-base-de-donnees-sql-server/origine_des_verrous_mortels_deadlocks">étreinte mortelle</a> (<a href="http://blog.developpez.com/elsuket/p9234/moteur-de-base-de-donnees-sql-server/obtenir_la_liste_des_deadlocks_retrospec">deadlock</a>) : il est alors nécessaire de comprendre ce qui a provoqué cette situation pour pouvoir orienter les choix de SQL Server, de sorte à éviter qu&rsquo;un tel phénomène se reproduise. A ce titre, il est nécessaire de savoir :</p>
<p>&#8211; quelles sont les ressources sur lesquelles les transactions acquièrent des verrous (ligne ou clé ou page, partition, table, schéma, base de données)<br />
&#8211; quel est le type de verrou qui a été acquis sur la ressource (intentionnel, partagé, de mise à jour, exclusif, de copie en bloc)</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Dans quelles conditions une escalade de verrou se produit-elle ?</strong></p>
<p>SQL Server choisit toujours d&rsquo;acquérir des verrous de faible granularité, de façon à maximiser la concurrence d&rsquo;accès. Donc la plupart du temps, SQL Server acquiert des verrous de ligne/clé, ou de page. Il faut noter que l&rsquo;acquisition de verrous se fait directement soit au niveau ligne/clé, soit au niveau page : l&rsquo;escalade de verrous ne se fait jamais de ligne/clé à page. En effet, si le moteur de base de données a calculé qu&rsquo;il devra accéder à toutes les lignes d&rsquo;un jeu de pages, autant qu&rsquo;il acquière un unique verrou sur chacune desdites pages. Tout verrou, quelle que soit sa granularité, consomme 96 octets de mémoire, et est une structure purement logique.</p>
<p>Le principe général de l&rsquo;escalade de verrou est de remplacer un grand nombre de verrous par un verrou de plus forte granularité, de façon à consommer moins de mémoire. Cela se fait au détriment de la concurrence d&rsquo;accès, mais en faveur :</p>
<p>&#8211; de la vitesse d&rsquo;exécution : un verrous a forte granularité est acquis pour une durée plus courte<br />
&#8211; mais aussi et surtout de la consommation de mémoire : moins on acquiert de verrous, moins on consomme de mémoire.</p>
<p>Au niveau requête, l&rsquo;escalade est réalisée dès qu&rsquo;elle acquiert ou requiert plus de 5000 verrous.</p>
<p>Au  niveau instance, lorsque SQL Server détecte que la gestion des verrous consomme 24% de la taille du cache de données (à l&rsquo;exclusion de la mémoire AWE sur les systèmes x86), il va scruter les sessions qui en détiennent en grand nombre, et escalader les verrous de celles-ci. Par ailleurs, l&rsquo;option de configuration <em>locks</em> permet de contrôler l&rsquo;escalade de verrous : si la valeur configurée est différente zéro (valeur par défaut), alors SQL Server réalisera une escalade de verrous dès que 40% de cette valeur en nombre de verrous acquis ou requis est dépassée. Il réalisera ensuite une nouvelle escalade de verrous après chaque bloc de 1250 verrous acquis ou requis dans ces conditions. L&rsquo;utilisateur n&rsquo;a aucun contrôle sur les sessions que SQL Server va sélectionner pour l&rsquo;escalade de verrous, mais gageons que comme pour bien d&rsquo;autres fonctionnalités, il n&rsquo;ait pas besoin d&rsquo;aide.</p>
<p>Enfin, si la gestion des verrous consomme 60% de la mémoire allouée à SQL Server à travers l&rsquo;option <em>max server memory (MB)</em>, ce dernier peut prendre la décision d&rsquo;annuler une ou plusieurs requêtes responsables de cette grande consommation. Dans ce cas, les requêtes impactées lèvent une exception de numéro 1204, dont le libellé est le suivant :</p>
<p><em>L&rsquo;instance du moteur de base de données SQL Server ne peut pas obtenir une ressource LOCK en ce moment. Réexécutez votre instruction lorsque le nombre d&rsquo;utilisateurs actifs est moindre. Demandez à l&rsquo;administrateur de base de données de vérifier la configuration du verrou et de la mémoire pour cette instance, ou de vérifier les longues transactions.</em></p>
<p>ou en Anglais :</p>
<p><em>The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions.</em></p>
<p>Cette erreur est aussi écrite dans les journaux de SQL Server.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Quelques requêtes</strong></p>
<p>La DMV <em>sys.dm_os_memory_clerks</em> nous permet de trouver la taille du gestionnaire de verrous. Voici la requête pour jusqu&rsquo;à SQL Server 2008 R2 inclus :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">TRANSACTION</span> <span style="color: #0000FF;">ISOLATION</span> <span style="color: #0000FF;">LEVEL</span> <span style="color: #0000FF;">READ</span> <span style="color: #0000FF;">UNCOMMITTED</span><br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; type<br />
&nbsp; &nbsp; &nbsp; &nbsp; , name<br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">SUM</span><span style="color: #808080;">&#40;</span>single_pages_kb<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> cache_size_from_buffer_pool_KB<br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">SUM</span><span style="color: #808080;">&#40;</span>multi_pages_kb<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> cache_size_out_buffer_pool_KB<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_os_memory_clerks</span><br />
<span style="color: #008080;">--WHERE name LIKE 'Lock Manager%'</span><br />
<span style="color: #0000FF;">GROUP</span> &nbsp; <span style="color: #0000FF;">BY</span> type, name<br />
<span style="color: #0000FF;">ORDER</span> &nbsp; <span style="color: #0000FF;">BY</span> security_token_cache_size_from_buffer_pool_KB DESC<span style="color: #808080;">&lt;/</span>code<span style="color: #808080;">&gt;</span><br />
<br />
Et dès <span style="color: #0000FF;">SQL</span> Server <span style="color: #000;">2012</span> :<br />
<br />
<span style="color: #808080;">&lt;</span>code<span style="color: #808080;">&gt;</span><span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">TRANSACTION</span> <span style="color: #0000FF;">ISOLATION</span> <span style="color: #0000FF;">LEVEL</span> <span style="color: #0000FF;">READ</span> <span style="color: #0000FF;">UNCOMMITTED</span><br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; type<br />
&nbsp; &nbsp; &nbsp; &nbsp; , name<br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">SUM</span><span style="color: #808080;">&#40;</span>pages_kb<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> cache_size_KB<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_os_memory_clerks</span><br />
<span style="color: #008080;">--WHERE name LIKE 'Lock Manager%'</span><br />
<span style="color: #0000FF;">GROUP</span> &nbsp; <span style="color: #0000FF;">BY</span> type, name<br />
<span style="color: #0000FF;">ORDER</span> &nbsp; <span style="color: #0000FF;">BY</span> cache_size_KB <span style="color: #0000FF;">DESC</span></div></td></tr></tbody></table></div>
<p>On trouve un gestionnaire de verrous par <a href="http://blog.developpez.com/elsuket/p11951/moteur-de-base-de-donnees-sql-server/mise-au-point-a-propos-du-compteur-de-performance-page-life-expectancy" title="Mise au point à propos du compteur de performance Page Life Expectancy">noeud NUMA</a>. Si nous laissons la clause WHERE de ces deux requêtes en commentaire, on doit trouver CACHESTORE_SQLCP et CACHESTORE_OBJCP sur les deux premières lignes du résultat de la requête, puisque le premier représente le cache de plan de requêtes ad-hoc ou en SQL dynamique, et le second celui des procédures stockées et déclencheurs. Si on y trouve OBJECTSTORE_LOCK_MANAGER, c&rsquo;est que le gestionnaire de verrous consomme probablement une trop grande quantité de mémoire.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>LOCK_ESCALATION : cas des tables partitionnées</strong></p>
<p>Dès SQL Server 2008, il est possible de réaliser l&rsquo;escalade de verrous au niveau partition, avant que celle-ci se produise au niveau table. Mais pour ce faire, il est nécessaire que celle-ci soit positionnée à AUTO : or par défaut, elle est à TABLE. On trouve les tables candidates à ce changement à l&rsquo;aide de la requête suivante :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">;<span style="color: #0000FF;">WITH</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; PARTITIONNED_TABLE <span style="color: #0000FF;">AS</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #0000FF;">DISTINCT</span> <span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_db_partition_stats</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; partition_number <span style="color: #808080;">&amp;</span>gt; <span style="color: #000;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.'</span> <span style="color: #808080;">+</span> T.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> table_or_indexed_view_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , T.<span style="color: #202020;">lock_escalation_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CASE</span> T.<span style="color: #202020;">lock_escalation_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> <span style="color: #FF0000;">'TABLE'</span> <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'ALTER TABLE '</span> <span style="color: #808080;">+</span> S.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">'.'</span> <span style="color: #808080;">+</span> T.<span style="color: #202020;">name</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' SET (LOCK_ESCALATION = AUTO)'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> <span style="color: #0000FF;">AS</span> sql_change_lock_escalation_level<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">schemas</span> <span style="color: #0000FF;">AS</span> S<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">tables</span> <span style="color: #0000FF;">AS</span> T<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> S.<span style="color: #202020;">schema_id</span> <span style="color: #808080;">=</span> T.<span style="color: #202020;">schema_id</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; PARTITIONNED_TABLE <span style="color: #0000FF;">AS</span> PT<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> PT.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> T.<span style="color: #FF00FF;">object_id</span><br />
<span style="color: #008080;">--WHERE &nbsp; &nbsp; &nbsp; &nbsp; T.lock_escalation_desc = 'TABLE'</span></div></td></tr></tbody></table></div>
<p>Bon verrouillage à tous !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Auditer les processus bloqués : l&#8217;événement blocked process report</title>
		<link>https://blog.developpez.com/elsuket/p12049/snippets/auditer-les-processus-bloques-levenement-blocked-process-report</link>
		<comments>https://blog.developpez.com/elsuket/p12049/snippets/auditer-les-processus-bloques-levenement-blocked-process-report#comments</comments>
		<pubDate>Sat, 15 Jun 2013 10:46:31 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Non documenté]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Utilitaires]]></category>
		<category><![CDATA[%%lockres%%]]></category>
		<category><![CDATA[blocage]]></category>
		<category><![CDATA[blocked process report]]></category>
		<category><![CDATA[blocked process threshold]]></category>
		<category><![CDATA[blocking]]></category>
		<category><![CDATA[deadlock]]></category>
		<category><![CDATA[événements étendus]]></category>
		<category><![CDATA[Extended Events]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[lock monitor]]></category>
		<category><![CDATA[Profiler]]></category>
		<category><![CDATA[sp_configure]]></category>
		<category><![CDATA[timeout]]></category>
		<category><![CDATA[verrou]]></category>
		<category><![CDATA[waitresource]]></category>
		<category><![CDATA[XE]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=604</guid>
		<description><![CDATA[SQL Server 2005 a introduit un évènement capturable par SQL Profiler et par les Notifications d’évènements, qui permet de retrouver les processus qui ont été bloqués. Avec la sortie de SQL Server 2008 et l&#8217;introduction des Évènements Étendus, il nous &#8230; <a href="https://blog.developpez.com/elsuket/p12049/snippets/auditer-les-processus-bloques-levenement-blocked-process-report">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>SQL Server 2005 a introduit un évènement capturable par <em><a href="http://elsuket.developpez.com/tutoriels/sqlserveur/fichier-trace-cote-serveur/">SQL Profiler</a></em> et par les <em>Notifications d’évènements</em>, qui permet de retrouver les processus qui ont été bloqués. Avec la sortie de SQL Server 2008 et l&rsquo;introduction des <em><a href="http://elsuket.developpez.com/tutoriels/sqlserveur/EvenementsEtendusSQLServer2008/">Évènements Étendus</a></em>, il nous est également possible de capturer cet évènement.</p>
<p>Dans cet article, je vous propose de voir comment paramétrer SQL Server pour capturer cet évènement, puis de vous aider à interpréter le document XML qui décrit la situation de blocage.<br />
<span id="more-604"></span><br />
Toute exécution de requête résulte en l&rsquo;acquisition de verrous, dont la granularité (ligne, page, clé, partition, table, base de données, ou encore et plus rarement compilation) et le mode (partagé, exclusif, de mise à jour, ou d&rsquo;intention) varient. Le verrouillage de ressources est une opération de base pour le moteur de stockage de tout moteur de bases de données SQL, qui garantit l&rsquo;intégrité de la base de données à travers toutes les opérations de manipulation de données que celle-ci supporte. Cependant, il arrive que lorsqu&rsquo;un processus a posé un verrou sur une ressource, d&rsquo;autres processus doivent simultanément accéder à cette même ressource : ces processus sont alors bloqués. Comme il est possible que le processus bloquant ne libère ledit verrou qu&rsquo;après une durée relativement longue, les effets possibles d&rsquo;une telle situation sur nos applications peuvent aller de requêtes dont la durée d&rsquo;exécution est élevée jusqu&rsquo;à l&rsquo;expiration du délai d&rsquo;attente d&rsquo;une réponse pour l&rsquo;exécution d&rsquo;un requête : le fameux <em>timeout</em>.</p>
<p>Il est néanmoins possible, à l&rsquo;aide d&rsquo;une trace SQL Profiler ou des Évènements Étendus, de capturer ces situations, qui sont décrites par un document XML.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Configurer l&rsquo;instance SQL Server</strong></p>
<p>Le seuil de durée de blocage à partir de laquelle on souhaite capturer un tel évènement est configurable à l&rsquo;aide de l&rsquo;option d&rsquo;instance <em>blocked process threshold</em>. On accède à ce paramètre :</p>
<p>&#8211; soit à l&rsquo;aide de <em>SQL Server Management Studio</em> (SSMS), après un clic-droit sur l&rsquo;instance dans l&rsquo;Explorateur d&rsquo;Objets (F8), et avoir choisi l&rsquo;option <em>Propriétés</em> :</p>
<p><img src="http://img855.imageshack.us/img855/6901/gq2.png" alt="" /></p>
<p>&#8211; soit à l&rsquo;aide de la procédure stockée système <em>sp_configure</em> :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">configurations</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; name <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'%block%'</span></div></td></tr></tbody></table></div>
<p><img src="http://img836.imageshack.us/img836/9273/zx81.png" alt="" /></p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-- Activation de la modification d'options d'instance avancées</span><br />
<span style="color: #0000FF;">EXEC</span> sys.<span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'show advanced options'</span>, <span style="color: #000;">1</span> <br />
GO<br />
<span style="color: #0000FF;">RECONFIGURE</span><br />
GO<br />
<br />
<span style="color: #008080;">-- Configuration du seuil de durée de blocage à 5 secondes</span><br />
<span style="color: #0000FF;">EXEC</span> sys.<span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'blocked process threshold'</span>, <span style="color: #000;">5</span><br />
GO <br />
<span style="color: #0000FF;">RECONFIGURE</span>; <br />
GO<br />
<br />
<span style="color: #008080;">-- Désactivation de la modification d'options d'instance avancées</span><br />
<span style="color: #0000FF;">EXEC</span> sys.<span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'show advanced options'</span>, <span style="color: #000;">0</span><br />
GO<br />
<span style="color: #0000FF;">RECONFIGURE</span><br />
GO</div></td></tr></tbody></table></div>
<p>La console de SSMS affiche, à l&rsquo;exécution de ce lot de requêtes :</p>
<p><img src="http://img28.imageshack.us/img28/4259/1ug.png" alt="" /></p>
<p>Veillez à ne pas mettre un seuil trop bas : sans cela, on aurait le processus d&rsquo;arrière plan LOCK MONITOR qui s&rsquo;exécuterait constamment. Or ce dernier, qui est aussi en charge de détecter les deadlocks, est gourmand en ressources CPU. En s&rsquo;exécutant fréquemment, il pourrait donc impacter négativement les performances générales de l&rsquo;instance SQL Server. D&rsquo;un autre côté, 5 secondes est une durée très longue sur une base de données qui supporte une charge de travail OLTP conséquente. On trouve ce processus avec la requête suivante :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; session_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , status<br />
&nbsp; &nbsp; &nbsp; &nbsp; , command<br />
&nbsp; &nbsp; &nbsp; &nbsp; , wait_type<br />
&nbsp; &nbsp; &nbsp; &nbsp; , wait_time<br />
&nbsp; &nbsp; &nbsp; &nbsp; , last_wait_type<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_exec_requests</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; command <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LOCK MONITOR'</span></div></td></tr></tbody></table></div>
<p>Si l&rsquo;on exécute maintenant cette requête de façon répétée, on voit que la valeur de la colonne <em>wait_time</em> croit jusqu&rsquo;à atteindre 5000, mais ne dépasse jamais cette valeur : cette colonne affiche sa valeur en millisecondes, et montre bien que le processus cherche les processus bloqués toutes les 5 secondes.</p>
<p>Il faut aussi noter qu&rsquo;avec cette configuration, si un processus reste bloqué 15 secondes, l’évènement sera généré 3 fois pour la même situation de blocage.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Capture avec SQL Profiler</strong></p>
<p>Une fois cela fait, nous démarrons SQL Profiler, et dans l&rsquo;onglet de sélection des évènements, dans la catégorie <em>Errors and Warnings</em> (et non pas dans la catégorie <em>Locks</em>), nous trouvons l’évènement <em>Blocked process report</em> :</p>
<p><img src="http://img546.imageshack.us/img546/5205/hptk.png" alt="" /></p>
<p>Nous configurons l’évènement comme suit, où le champ <em>TextData</em> contiendra le document XML décrivant la situation de blocage :</p>
<p><img src="http://img19.imageshack.us/img19/2305/n66.png" alt="" /></p>
<p><strong>N.B.</strong> : N&rsquo;oubliez pas le champ <em>Mode</em>, qui procure le type de verrou acquis.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Capture avec les Évènements Étendus (XE)</strong></p>
<p>Pour les lecteurs qui n&rsquo;ont pas encore eu le temps de se familiariser avec cette fonctionnalité, qui est vouée au remplacement futur de SQL Profiler, et dont la puissance en fait mon outil de diagnostic favori, vous pouvez vous aider de l&rsquo;<a href="http://elsuket.developpez.com/tutoriels/sqlserveur/EvenementsEtendusSQLServer2008/">article</a> que j&rsquo;ai publié sur le sujet.</p>
<p>Si l&rsquo;on souhaite capturer en permanence toute situation de blocage, l&rsquo;avantage revient à XE, puisqu&rsquo;on peut stocker ces évènements dans une cible dite anneau de mémoire (ring buffer). Cette structure consomme très peu de mémoire et fonctionne à l&rsquo;image d&rsquo;un FIFO : lorsqu&rsquo;il est plein, la capture d&rsquo;un nouvel évènement donne lieu à l&rsquo;éviction du plus vieil évènement pour le stockage de celui-ci. Avec SQL Profiler, il est nécessaire de mettre en place une trace côté serveur et de gérer le fichier de trace et l&rsquo;espace disque. En revanche, une fois que l&rsquo;on a démarré la session XE, on peut &laquo;&nbsp;l&rsquo;oublier&nbsp;&raquo;.</p>
<p>Pour les lecteurs familiers de XE et de Profiler, sachez que le document XML produit par ces deux fonctionnalités pour un même évènement de blocage est identique, ce qui n&rsquo;est pas le cas avec les deadlocks (XE produit un document XML mal formé, qui rend impossible son enregistrement en document de type .xdl en vue de son interprétation graphique dans SSMS).</p>
<p>La définition d&rsquo;une telle session est simple :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-- Définition de la session</span><br />
<span style="color: #0000FF;">CREATE</span> EVENT <span style="color: #0000FF;">SESSION</span> blocked_process_report_RB <span style="color: #0000FF;">ON</span> SERVER<br />
<span style="color: #0000FF;">ADD</span> EVENT sqlserver.<span style="color: #202020;">blocked_process_report</span><br />
<span style="color: #0000FF;">ADD</span> TARGET package0.<span style="color: #202020;">ring_buffer</span> <span style="color: #808080;">&#40;</span><span style="color: #0000FF;">SET</span> MAX_MEM<span style="color: #808080;">OR</span>Y <span style="color: #808080;">=</span> <span style="color: #000;">4096</span><span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">WITH</span> <span style="color: #808080;">&#40;</span>MAX_DISPATCH_LATENCY <span style="color: #808080;">=</span> <span style="color: #000;">5</span> SECONDS<span style="color: #808080;">&#41;</span><br />
GO<br />
<br />
<span style="color: #008080;">-- Démarrage de la session</span><br />
<span style="color: #0000FF;">ALTER</span> EVENT <span style="color: #0000FF;">SESSION</span> blocked_process_report_RB <span style="color: #0000FF;">ON</span> SERVER<br />
<span style="color: #0000FF;">STATE</span> <span style="color: #808080;">=</span> <span style="color: #0000FF;">START</span><br />
<br />
<span style="color: #008080;">-- Vérification</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; name<br />
&nbsp; &nbsp; &nbsp; &nbsp; , create_time<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_sessions</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; name <span style="color: #808080;">=</span> <span style="color: #FF0000;">'blocked_process_report_RB'</span></div></td></tr></tbody></table></div>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Le test</strong></p>
<p>Pour l&rsquo;exemple, nous avons la trace SQL Profiler et la session XE ci-dessus actifs.<br />
Nous créons la table suivante :</p>
<div class="codecolorer-container tsql 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="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> blocked_process_report_test<br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cle <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">16</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CONSTRAINT</span> UQ_blocked_process_report_test <span style="color: #0000FF;">UNIQUE</span> <span style="color: #0000FF;">CLUSTERED</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , valeur <span style="color: #0000FF;">tinyint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
<span style="color: #808080;">&#41;</span></div></td></tr></tbody></table></div>
<p>Puis, dans une première fenêtre de requête (A) sous SSMS, nous ajoutons la ligne suivante, sans valider la transaction :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">BEGIN</span> <span style="color: #0000FF;">TRANSACTION</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> dbo.<span style="color: #202020;">blocked_process_report_test</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cle<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , valeur<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">VALUES</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #FF0000;">'TEST'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #000;">12</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span></div></td></tr></tbody></table></div>
<p>Dans une seconde fenêtre de requête (B), nous exécutons :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">UPDATE</span>&nbsp; dbo.<span style="color: #202020;">blocked_process_report_test</span><br />
<span style="color: #0000FF;">SET</span> &nbsp; &nbsp; valeur <span style="color: #808080;">=</span> <span style="color: #000;">15</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; cle <span style="color: #808080;">=</span> <span style="color: #FF0000;">'TEST'</span></div></td></tr></tbody></table></div>
<p>Ceci fait que la requête B doit attendre que la requête A soit terminée pour réaliser l&rsquo;UPDATE, ce qui ne peut se faire que si l&rsquo;on valide (COMMIT) ou annule (ROLLBACK) la transaction : nous ne le faisons pas ici, pour l&rsquo;exemple. Nous laissons aussi la requête B s&rsquo;exécuter 10 secondes, de façon à bien voir que l’évènement est capturé deux fois pour la même situation de blocage.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Ce que capture SQL Profiler</strong></p>
<p>L&rsquo;interface affiche bien deux captures de l’évènement :</p>
<p><img src="http://img705.imageshack.us/img705/8171/5kt.png" alt="" /></p>
<p>Notez que les valeurs pour la colonne <em>Duration</em> sont données ici en microsecondes : on voit donc qu&rsquo;il y a un léger décalage entre la détection du blocage et sa capture. Toutes les informations dont nous avons besoin sont donc sous nos yeux: la ressource à la source de la situation de blocage, ainsi que les requêtes impliquées dans celle-ci.</p>
<p>Il est possible de charger le fichier de trace dans une table à l&rsquo;aide de la fonction <a href="http://msdn.microsoft.com/fr-fr/library/ms188425.aspx">sys.fn_trace_gettable()</a>. Cela permet l&rsquo;écriture d&rsquo;une requête utilisant les méthodes SQLXML, qui extrait directement les informations intéressantes de chaque document XML. La requête est similaire à celle que je donne dans la section suivante.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Ce que capture la session XE</strong></p>
<p>Ici il nous est nécessaire d&rsquo;écrire une requête faisant appel aux fonctions SQLXML pour dépouiller le document XML sans se fatiguer :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #FF00FF;">DATEADD</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">hour</span>, <span style="color: #FF00FF;">DATEDIFF</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">hour</span>, <span style="color: #FF00FF;">GETUTCDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span>, <span style="color: #FF00FF;">GETDATE</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span>, doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/@timestamp)[1]'</span>, <span style="color: #FF0000;">'datetime'</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> log_date_time<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;transaction_id&quot;]/value)[1]'</span>, <span style="color: #FF0000;">'bigint'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> transaction_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;database_name&quot;]/value)[1]'</span>, <span style="color: #FF0000;">'nvarchar(128)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;duration&quot;]/value)[1]'</span>, <span style="color: #FF0000;">'int'</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> <span style="color: #000;">1000</span> <span style="color: #0000FF;">AS</span> duration_ms<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;resource_owner_type&quot;]/text)[1]'</span>, <span style="color: #FF0000;">'varchar(10)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> resource_owner_type<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;lock_mode&quot;]/text)[1]'</span>, <span style="color: #FF0000;">'varchar(10)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> lock_mode<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;blocked_process&quot;]/value/blocked-process-report/blocked-process/process/@waitresource)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> wait_resource<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;blocked_process&quot;]/value/blocked-process-report/blocked-process/process/@isolationlevel)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> blocked_tran_iso_level<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;blocked_process&quot;]/value/blocked-process-report/blocking-process/process/@isolationlevel)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> blocking_tran_iso_level<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;blocked_process&quot;]/value/blocked-process-report/blocked-process/process/inputbuf)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> blocked_statement<br />
&nbsp; &nbsp; &nbsp; &nbsp; , doc.<span style="color: #0000FF;">value</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'(event/data[@name=&quot;blocked_process&quot;]/value/blocked-process-report/blocking-process/process/inputbuf)[1]'</span>, <span style="color: #FF0000;">'varchar(max)'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> blocking_statement<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; <span style="color: #808080;">&#40;</span> &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">n</span>.<span style="color: #202020;">query</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'.'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> doc<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>target_data <span style="color: #0000FF;">AS</span> xml<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">data</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_sessions</span> <span style="color: #0000FF;">AS</span> S &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_xe_session_targets</span> <span style="color: #0000FF;">AS</span> ST<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> S.<span style="color: #202020;">address</span> <span style="color: #808080;">=</span> ST.<span style="color: #202020;">event_session_address</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S.<span style="color: #202020;">name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'blocked_process_report_RB'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ST.<span style="color: #202020;">target_name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ring_buffer'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> sub<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">CROSS</span> APPLY &nbsp; &nbsp; <span style="color: #0000FF;">data</span>.<span style="color: #202020;">nodes</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'RingBufferTarget/event'</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> D<span style="color: #808080;">&#40;</span>n<span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> T</div></td></tr></tbody></table></div>
<p>La capture d&rsquo;écran du résultat a été coupée en deux pour faciliter un peu la lecture :</p>
<p><img src="http://img827.imageshack.us/img827/7796/91d.png" alt="" /></p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Interprétation du résultat</strong></p>
<p>Notre intérêt dans l&rsquo;interprétation de ce document se portera sur la propriété waitresource, que l&rsquo;on peut décrypter à l&rsquo;aide de la <a href="http://support.microsoft.com/kb/224453">documentation</a> (Voir la section <strong><em>Waitresource</em></strong>).</p>
<p>Ici, waitresource est : KEY: 5:72057594039107584 (2158b2b5a6d5), ce qui signifie :</p>
<p>&#8211; Database ID : 5<br />
&#8211; Partition ID : 72057594039107584<br />
&#8211; (2158b2b5a6d5) : le hash de la clé d&rsquo;index</p>
<p>Sur ce dernier point, il faut savoir que SQL Server utilise le hash, stocké sur 6 octets, de la clé de l&rsquo;index qui supporte la requête. Ceci conduit SQL Server à générer des valeurs de hash identiques pour des valeurs de clé différentes, ce qui peut causer d&rsquo;autre problèmes de concurrence d&rsquo;accès. C&rsquo;est une raison de plus pour choisir des clés d&rsquo;index les plus &laquo;&nbsp;étroites&nbsp;&raquo; possible, de façon à éviter ce type de collisions.</p>
<p>Voyons comment retrouver la ressource qui a été verrouillée :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">USE</span> ELSUKET<br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; O.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> table_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , I.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> index_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , P.<span style="color: #202020;">partition_number</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , P.<span style="color: #0000FF;">rows</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">partitions</span> <span style="color: #0000FF;">AS</span> p<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">objects</span> <span style="color: #0000FF;">AS</span> O<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> O.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> P.<span style="color: #FF00FF;">object_id</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">indexes</span> <span style="color: #0000FF;">AS</span> I<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> P.<span style="color: #FF00FF;">object_id</span> <span style="color: #808080;">=</span> I.<span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> P.<span style="color: #202020;">index_id</span> <span style="color: #808080;">=</span> I.<span style="color: #202020;">index_id</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p.<span style="color: #202020;">partition_id</span> <span style="color: #808080;">=</span> <span style="color: #000;">72057594039107584</span></div></td></tr></tbody></table></div>
<p><img src="http://img818.imageshack.us/img818/5617/zsbe.png" alt="" /></p>
<p>Voyons maintenant comment retrouver la clé qui a été utilisée :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; dbo.<span style="color: #202020;">blocked_process_report_test</span> <span style="color: #0000FF;">WITH</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">INDEX</span> <span style="color: #808080;">=</span> UQ_blocked_process_report_test<span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; <span style="color: #808080;">%%</span>lockres<span style="color: #808080;">%%</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'(2158b2b5a6d5)'</span></div></td></tr></tbody></table></div>
<p><img src="http://img268.imageshack.us/img268/5628/5xt.png" alt="" /></p>
<p>La fonction %%lockres%% n&rsquo;est pas documentée : il est donc recommandé de l&rsquo;utiliser avec parcimonie. La même méthodologie est utilisable dans le diagnostic des deadlocks.</p>
<p>Bon déblocage à tous !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server 2014 : c&#8217;est pour bientôt !</title>
		<link>https://blog.developpez.com/elsuket/p12044/moteur-de-base-de-donnees-sql-server/sql-server-2014-cest-pour-bientot</link>
		<comments>https://blog.developpez.com/elsuket/p12044/moteur-de-base-de-donnees-sql-server/sql-server-2014-cest-pour-bientot#comments</comments>
		<pubDate>Thu, 13 Jun 2013 15:18:27 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Annonces]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=592</guid>
		<description><![CDATA[Un an après avoir sorti SQL Server 2012, le 2 Avril 2012, Microsoft a annoncé le 6 Avril la sortie de SQL Server 2014. Voici donc que la semaine dernière, à l&#8217;occasion du TechEd North America, Microsoft a annoncé la &#8230; <a href="https://blog.developpez.com/elsuket/p12044/moteur-de-base-de-donnees-sql-server/sql-server-2014-cest-pour-bientot">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Un an après avoir sorti SQL Server 2012, le 2 Avril 2012, Microsoft a annoncé le 6 Avril la sortie de SQL Server 2014.<br />
Voici donc que la semaine dernière, à l&rsquo;occasion du <em>TechEd North America</em>, Microsoft a annoncé la sortie en avant-première de SQL Server 2014 dans les semaines à venir, même si une date définitive de commercialisation n&rsquo;a pas encore été fixée.</p>
<p>On notera parmi les fonctionnalités les plus attendues :<br />
<span id="more-592"></span><br />
&#8211; <em>Hekaton</em>, le nom de code du moteur de base de données entièrement in-memory : la mécanique repose sur le contrôle de concurrence multi-version, ce qui permet de traiter les données sans lock, latch ou blocage. Il est bien sûr possible de choisir les tables qui utiliseront cette fonctionnalité, mais aussi de compiler les procédures stockées directement en code machine pour obtenir des gains de performance supplémentaires.</p>
<p>&#8211; SQL Server 2014 sera encore plus proche du cloud encore que SQL Server 2012, avec la possibilité, entre autres, de prendre une sauvegarde de base de données sur un compte de stockage Azure, et de la référencer par une URL. La fonctionnalité <em>Smart Backup</em> laisse SQL Server décider s&rsquo;il est temps de prendre une sauvegarde différentielle de la base de données, ou encore une sauvegarde du fichier du journal des transactions. Il sera aussi possible de créer une base de données localement, tout en ayant ses fichiers stockés dans le cloud. Enfin la fonctionnalité <em>AlwaysOn</em> sera étendue à <em>Azure</em>, avec la possibilité de créer un groupe de disponibilité dont le réplica peut se trouver dans les nuages.</p>
<p>&#8211; La mémoire pourra être étendue à l&rsquo;usage des disques SSD<br />
&#8211; Les tables utilisant des index <em>ColumnStore</em> seront dorénavant actualisables, ce qui n&rsquo;était pas encore le cas sous SQL Server 2012<br />
&#8211; Le <em>Gouverneur de Ressources</em> permettra l’accélération des IO<br />
&#8211; Les statistiques de colonnes et d&rsquo;index seront disponible au niveau partition, tandis que l&rsquo;estimation de cardinalités a été améliorée<br />
&#8211; La reconstruction en ligne d&rsquo;une partition d&rsquo;index sera désormais possible, après que SQL Server 2012 ait permis la reconstruction en ligne des index portant sur des colonnes de type LOB.</p>
<p>Il est à noter que toutes ces améliorations ont été apportés dans un cycle de développement relativement court pour SQL Server : 18 mois. Espérons que ce ne soit que le début d&rsquo;une tendance !</p>
<p>Quelques liens :</p>
<p>&#8211; <a href="http://blogs.technet.com/b/dataplatforminsider/archive/2013/06/03/sql-server-2014-unlocking-real-time-insights.aspx">le blog SQL Server</a><br />
&#8211; <a href="http://www.microsoft.com/en-us/sqlserver/sql-server-2014.aspx">S&rsquo;enregistrer pour être notifié de la disponibilité de l&rsquo;évaluation de SQL Server 2014</a><br />
&#8211; <a href="http://visualstudiomagazine.com/blogs/data-driver/2013/06/microsoft-announces-sql-server-2014.aspx">Visual Studio Magazine</a><br />
&#8211; <a href="http://redmondmag.com/articles/2012/04/02/sql-server-2012-released.aspx">RedmondMag</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quelles statistiques l&#8217;Optimiseur a-t-il utilisées pour calculer le plan de requête ?</title>
		<link>https://blog.developpez.com/elsuket/p12023/moteur-de-base-de-donnees-sql-server/quelles-statistiques-loptimiseur-a-t-il-utilisees-pour-calculer-le-plan-de-requete</link>
		<comments>https://blog.developpez.com/elsuket/p12023/moteur-de-base-de-donnees-sql-server/quelles-statistiques-loptimiseur-a-t-il-utilisees-pour-calculer-le-plan-de-requete#comments</comments>
		<pubDate>Thu, 06 Jun 2013 16:19:44 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Non documenté]]></category>
		<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[8666]]></category>
		<category><![CDATA[drapeau de trace]]></category>
		<category><![CDATA[plan d'exécution]]></category>
		<category><![CDATA[statistiques]]></category>
		<category><![CDATA[trace flag]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=559</guid>
		<description><![CDATA[Si une bonne partie de votre temps de travail est consacrée à l&#8217;optimisation de requête et à la compréhension du fonctionnement de l&#8217;Optimiseur de Requêtes, vous vous êtes probablement demandé sur quelles statistiques celui-ci se base pour calculer le plan &#8230; <a href="https://blog.developpez.com/elsuket/p12023/moteur-de-base-de-donnees-sql-server/quelles-statistiques-loptimiseur-a-t-il-utilisees-pour-calculer-le-plan-de-requete">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Si une bonne partie de votre temps de travail est consacrée à l&rsquo;optimisation de requête et à la compréhension du fonctionnement de l&rsquo;Optimiseur de Requêtes, vous vous êtes probablement demandé sur quelles statistiques celui-ci se base pour calculer le plan d&rsquo;une requête.</p>
<p>Il existe un drapeau de trace <strong>non-documenté</strong>, n° 8666, qui permet d&rsquo;ajouter au document XML qui décrit le plan de requête les statistiques utilisées par l&rsquo;optimiseur pour générer le plan de requêtes.</p>
<p>Voyons comment l&rsquo;utiliser avec une requête sur la base de données <a href="http://blog.developpez.com/elsuket/p11188/moteur-de-base-de-donnees-sql-server/attacher_base_donnees_sans_tran_log">AdventureWorks2012</a> :</p>
<p><span id="more-559"></span></p>
<p>Avant toute chose, notez que ce drapeau de trace n&rsquo;est pas documenté. Comme toute fonctionnalité non-documentée, on ne doit <strong>JAMAIS</strong> utiliser celui-ci sur une base de données ou une instance qui sert une charge de production. <strong>Si tel devait être le cas, je ne peux en aucun cas être tenu pour responsable des conséquences. Vous devez limiter strictement l’usage de cette instruction aux environnements de test.</strong></p>
<p>Utilisons la requête suivante :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">DBCC</span> TRACEON <span style="color: #808080;">&#40;</span><span style="color: #000;">8666</span><span style="color: #808080;">&#41;</span><br />
GO<br />
<br />
<span style="color: #0000FF;">USE</span> AdventureWorks2012<br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SOH.<span style="color: #202020;">OrderDate</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SOH.<span style="color: #202020;">DueDate</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SOH.<span style="color: #202020;">ShipDate</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SOH.<span style="color: #202020;">AccountNumber</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SOD.<span style="color: #202020;">OrderQty</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SOD.<span style="color: #202020;">UnitPrice</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Sales.<span style="color: #202020;">SalesOrderHeader</span> <span style="color: #0000FF;">AS</span> SOH<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; Sales.<span style="color: #202020;">SalesOrderDetail</span> <span style="color: #0000FF;">AS</span> SOD<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> SOH.<span style="color: #202020;">SalesOrderID</span> <span style="color: #808080;">=</span> SOD.<span style="color: #202020;">SalesOrderID</span></div></td></tr></tbody></table></div>
<p>Demandons maintenant à SQL Server de générer le plan de requête estimé. Celui-ci s&rsquo;obtient soit en pressant CTRL + L, soit par un clic sur l&rsquo;icône suivante, présente dans la barre d&rsquo;outils : </p>
<p><img src="http://img199.imageshack.us/img199/605/estimatedexecutionplan.png" alt="" /></p>
<p>On obtiendra aussi les informations ajoutées par le drapeau de trace 8666 avec le plan d&rsquo;exécution réel, que l&rsquo;on obtient soit en pressant CTRL + M, soit par un clic sur l&rsquo;icône, suivante présente elle aussi dans la barre d&rsquo;outils : </p>
<p><img src="http://img41.imageshack.us/img41/2989/actualexecutionplan.png" alt="" /></p>
<p>Nous devons maintenant explorer le document XML à l&rsquo;origine du plan d&rsquo;exécution graphique, ce qui se fait par un simple clic droit dans une zone vierge de ce dernier :</p>
<p><img src="http://img546.imageshack.us/img546/1588/tf866601.png" alt="" /></p>
<p>Il nous suffit maintenant de chercher la chaîne de caractères <em>wszStatName</em>, et nous obtenons :</p>
<p><img src="http://img9.imageshack.us/img9/3892/tf866602.png" alt="" /></p>
<p>On voit clairement les détails de ce que SQL Server utilise comme métriques pour calculer le plan, notamment :</p>
<p>&#8211; le nom de la statistique (ici c&rsquo;est la statistiques sous-jacente à l&rsquo;index qui supporte la clé primaire)<br />
&#8211; le nom de la colonne la plus à gauche dans cette statistique (wszColName)<br />
&#8211; le nombre de lignes échantillonnées lors de la génération de la statique (m_ullSnapShotModCtr)<br />
&#8211; le nombre de lignes présentes dans la table (m_ullRowCount)<br />
&#8211; le seuil de recalcul automatique de la statistique (ullThreshold)</p>
<p>Pour cette dernière valeur, on peut d&rsquo;ailleurs faire le calcul suivant :</p>
<blockquote><p>100.0 * 24,763 / 121,317 = 20.41181367821492</p></blockquote>
<p>Soit environ 20%. Prenons la partie décimale de ce pourcentage : </p>
<blockquote><p>(0.41181367821492 / 100.0) * 121,317 = 499.5999999999945</p></blockquote>
<p>Soit environ 500 lignes. Ceci vérifie bien la règle du seuil de recalcul automatique des statistiques pour les tables de plus de 8MB : 500 lignes + 20% du nombre de lignes de la table.</p>
<p>Bons calculs de plans de requêtes et estimations de cardinalités !</p>
<p>ElSüket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reprendre le contrôle d&#8217;une instance SQL Server lorsqu&#8217;on a perdu le mot de passe de la connexion sa ou lorsque tous les DBAs en ont perdu l&#8217;accès</title>
		<link>https://blog.developpez.com/elsuket/p12007/moteur-de-base-de-donnees-sql-server/reprendre-le-controle-dune-instance-sql-server-lorsquon-a-perdu-le-mot-de-passe-de-la-connexion-sa-ou-lorsque-tous-les-dbas-en-ont-perdu-lacces</link>
		<comments>https://blog.developpez.com/elsuket/p12007/moteur-de-base-de-donnees-sql-server/reprendre-le-controle-dune-instance-sql-server-lorsquon-a-perdu-le-mot-de-passe-de-la-connexion-sa-ou-lorsque-tous-les-dbas-en-ont-perdu-lacces#comments</comments>
		<pubDate>Fri, 31 May 2013 00:36:28 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Sécurité]]></category>
		<category><![CDATA[Utilitaires]]></category>
		<category><![CDATA[instance]]></category>
		<category><![CDATA[mot de passe]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[sa]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=524</guid>
		<description><![CDATA[Comment faire lorsqu&#8217;on a perdu le mot de passe de la connexion sa pour se connecter à l&#8217;instance ? Ou comment est-il possible de prendre le contrôle d&#8217;une instance SQL Server installée par une personne avec son propre compte, et &#8230; <a href="https://blog.developpez.com/elsuket/p12007/moteur-de-base-de-donnees-sql-server/reprendre-le-controle-dune-instance-sql-server-lorsquon-a-perdu-le-mot-de-passe-de-la-connexion-sa-ou-lorsque-tous-les-dbas-en-ont-perdu-lacces">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Comment faire lorsqu&rsquo;on a perdu le mot de passe de la connexion sa pour se connecter à l&rsquo;instance ?<br />
Ou comment est-il possible de prendre le contrôle d&rsquo;une instance SQL Server installée par une personne avec son propre compte, et qui a quitté l&rsquo;entreprise depuis une durée plus grande que celle de l&rsquo;expiration des mots de passe ?<br />
<span id="more-524"></span><br />
Il est pour cela nécessaire d&rsquo;avoir accès à la machine avec un compte d’administrateur local : en effet dans ce cas, le démarrage en mode mono-utilisateur d&rsquo;une instance de SQL Server autorise l&rsquo;accès à un tel compte. Cela permet donc de créer une nouvelle connexion, à laquelle on octroie le privilège et sésame d&rsquo;appartenance au rôle fixe de serveur <em>sysadmin</em>.</p>
<p>Voyons tout d&rsquo;abord quelles sont les connexions qui disposent du privilège d&rsquo;appartenance au rôle <em>sysadmin</em>. La requête suivante liste l&rsquo;ensemble des connexions inscrites aux rôles d&rsquo;instance :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SPR.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> server_role_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SPM.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> server_role_member_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , SPR.<span style="color: #202020;">type_desc</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">server_role_members</span> <span style="color: #0000FF;">AS</span> SRM<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">server_principals</span> <span style="color: #0000FF;">AS</span> SPR<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> SRM.<span style="color: #202020;">role_principal_id</span> <span style="color: #808080;">=</span> SPR.<span style="color: #202020;">principal_id</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">server_principals</span> <span style="color: #0000FF;">AS</span> SPM<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> SRM.<span style="color: #202020;">member_principal_id</span> <span style="color: #808080;">=</span> SPM.<span style="color: #202020;">principal_id</span></div></td></tr></tbody></table></div>
<p><img src="http://img689.imageshack.us/img689/5329/restartsqlserversingleu.png" alt="" /></p>
<p>La connexion <em>ELSUKET8\Nicolas</em> est celle d&rsquo;administrateur local de mon PC : je la supprime :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">DROP</span> LOG<span style="color: #808080;">IN</span> <span style="color: #808080;">&#91;</span>ELSUKET8\Nicolas<span style="color: #808080;">&#93;</span></div></td></tr></tbody></table></div>
<p>A l&rsquo;ouverture d&rsquo;une nouvelle fenêtre de requête, nous obtenons bien l&rsquo;erreur :</p>
<p><img src="http://img836.imageshack.us/img836/5329/restartsqlserversingleu.png" alt="" /></p>
<p>Rendons-nous maintenant dans le <a href="http://blog.developpez.com/elsuket/p7723/moteur-de-base-de-donnees-sql-server/configurer_les_protocoles_de_connexion_a">gestionnaire de configuration de SQL Server</a>. Si l&rsquo;instance est sous SQL Server 2012 et que l&rsquo;on souhaite ouvrir cette console à partir d&rsquo;une fenêtre de ligne de commandes, il faudra saisir <em>SQLServerManager11.msc</em>. Une fois la console ouverte, on peut double-cliquer sur SQL Server Services dans l&rsquo;un des deux panneaux, et on obtient la liste des services SQL Server installés :</p>
<p><img src="http://img248.imageshack.us/img248/5329/restartsqlserversingleu.png" alt="" /></p>
<p>Un clic-droit sur le service SQL Server nous permet d&rsquo;accéder, en outre, aux paramètres de démarrage du service. Sous SQL Server 2005 et 2008, ils se trouvent dans l&rsquo;onglet <em>Avancé</em>, mais sous SQL Server 2012, l&rsquo;onglet <em>Paramètres de démarrage</em> a fait son apparition :</p>
<p><img src="http://img22.imageshack.us/img22/5329/restartsqlserversingleu.png" alt="" /></p>
<p>Nous ajoutons ici le paramètre l&rsquo;option <em>-m</em>, qui permet de démarrer une instance en mode mono-utilisateur. Sous SQL Server 2005 et 2008, dans l&rsquo;onglet <em>Avancé</em>, il est nécessaire de placer le curseur à la fin de la chaîne du paramètre <em>Paramètres de démarrage</em>, et d&rsquo;ajouter <em>;-m</em> après la fin de cette chaîne. Une fois fait, nous sommes avertis qu&rsquo;il est évidemment nécessaire de redémarrer le service :</p>
<p><img src="http://img545.imageshack.us/img545/5329/restartsqlserversingleu.png" alt="" /></p>
<p>On peut redémarrer le service toujours à partir de la même console, par un clic-droit sur le service. Une fois fait, nous démarrons SQL Server Management Studio (SSMS) <strong>en tant qu&rsquo;administrateur</strong>. Cette option est accessible par un simple clic-droit sur le raccourci. Attention : comme nous sommes en mode mono-utilisateur, il n&rsquo;est pas possible d&rsquo;ouvrir une connexion pour l&rsquo;explorateur d&rsquo;objets. Donc si l&rsquo;on ne ferme pas la connexion de ce dernier (par clic-droit sur le nom de l&rsquo;instance dans celui-ci), il est impossible d&rsquo;ouvrir une fenêtre de requête.</p>
<p>Nous nous octroyons maintenant le droit de connexion et d&rsquo;appartenance au rôle de serveur <em>sysadmin</em> :</p>
<div class="codecolorer-container tsql 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="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">CREATE</span> LOG<span style="color: #808080;">IN</span> <span style="color: #808080;">&#91;</span>ELSUKET8\ElSuket<span style="color: #808080;">&#93;</span><br />
<span style="color: #0000FF;">FROM</span> W<span style="color: #808080;">IN</span>DOWS<br />
GO<br />
<br />
<span style="color: #008080;">-- SQL Server 2012</span><br />
<span style="color: #0000FF;">ALTER</span> SERVER <span style="color: #0000FF;">ROLE</span> sysadmin <span style="color: #0000FF;">ADD</span> MEMBER <span style="color: #808080;">&#91;</span>ELSUKET8\ElSuket<span style="color: #808080;">&#93;</span><br />
<br />
<span style="color: #008080;">-- SQL Server 2000, 2005 et 2008</span><br />
<span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">sp_addsrvrolemember</span> <span style="color: #FF0000;">'ELSUKET8\ElSuket'</span>, <span style="color: #FF0000;">'sysadmin'</span></div></td></tr></tbody></table></div>
<p>Nous devons maintenant retourner dans la console de configuration des services de SQL Server, retirer le paramètre -m, et redémarrer à nouveau le service, de sorte que l&rsquo;instance soit de nouveau accessible par plusieurs connexions. Une fois fait, on peut démarrer SSMS normalement (i.e. pas en tant qu&rsquo;administrateur), et nous pouvons de nouveau accéder à l&rsquo;instance SQL Server :</p>
<p><img src="http://img835.imageshack.us/img835/5329/restartsqlserversingleu.png" alt="" /></p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Changer le mot de passe de la connexion <em>sa</em></strong></p>
<p>Cela se fait de la même façon, en suivant les étapes suivantes :</p>
<p>1. Ajouter le paramètre -m aux paramètres de démarrage du service SQL Server, puis redémarrer le service;<br />
2. Se connecter à l&rsquo;instance SQL Server avec SSMS en tant qu’administrateur;<br />
3. Changer le mot de passe de la connexion <em>sa</em> avec l&rsquo;instruction suivante :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">ALTER</span> LOG<span style="color: #808080;">IN</span> sa <span style="color: #0000FF;">WITH</span> PASSW<span style="color: #808080;">OR</span>D <span style="color: #808080;">=</span> <span style="color: #FF0000;">'unMotDePasseRobuste'</span></div></td></tr></tbody></table></div>
<p>4. Supprimer le paramètre -m des paramètres de démarrage du service SQL Server, puis redémarrer le service une nouvelle fois;<br />
5. Se connecter normalement avec SSMS, le nom de connexion <em>sa</em> et le nouveau mot de passe.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Effectuer ces mêmes opérations en ligne de commande avec l&rsquo;utilitaire SQLCMD</strong></p>
<p>Il est pour cela nécessaire d&rsquo;ouvrir un fenêtre de lignes de commande en tant qu&rsquo;administrateur. On peut tout simplement créer une raccourci qui pointe sur <em>cmd</em>, puis par clic-droit sur celui-ci, choisir de mode :</p>
<p><img src="http://img689.imageshack.us/img689/5316/restartsqlserversingleux.png" alt="" /></p>
<p>Une fois fait, on démarre l&rsquo;utilitaire en lignes de commande SQLCMD très simplement :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sqlcmd <span style="color: #808080;">-</span>S <span style="color: #808080;">&#91;</span>uneInstance<span style="color: #808080;">&#93;</span></div></td></tr></tbody></table></div>
<p><img src="http://img823.imageshack.us/img823/5329/restartsqlserversingleu.png" alt="" /></p>
<p>Puis, par exemple, changer le mot de passe de la connexion <em>sa</em> :</p>
<p><img src="http://img577.imageshack.us/img577/5329/restartsqlserversingleu.png" alt="" /></p>
<p>Après chaque ligne de code tapée sous SQLCMD, si l&rsquo;on appuie sur <em>Entrée</em>, la commande n&rsquo;est pas exécutée : il faut pour cela utiliser la marqueur de fin de lot GO (qui n&rsquo;est pas une instruction SQL ou T-SQL !). Enfin, pour sortir de l&rsquo;utilitaire SQLCMD, il suffit de taper <em>exit</em>.</p>
<p>Bonne récupération d&rsquo;accès à tous !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dedicated administrator connections are not supported via SSMS as it establishes multiple connections by design : que faire ?</title>
		<link>https://blog.developpez.com/elsuket/p12003/moteur-de-base-de-donnees-sql-server/dedicated-administrator-connections-are-not-supported-via-ssms-as-it-establishes-multiple-connections-by-design-que-faire</link>
		<comments>https://blog.developpez.com/elsuket/p12003/moteur-de-base-de-donnees-sql-server/dedicated-administrator-connections-are-not-supported-via-ssms-as-it-establishes-multiple-connections-by-design-que-faire#comments</comments>
		<pubDate>Wed, 29 May 2013 00:38:53 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[DAC]]></category>
		<category><![CDATA[Dedicated Administrator Connection]]></category>
		<category><![CDATA[remote admin connections]]></category>
		<category><![CDATA[sp_configure]]></category>
		<category><![CDATA[sys.configurations]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=511</guid>
		<description><![CDATA[Lorsqu&#8217;on tente d&#8217;ouvrir une connexion d&#8217;administrateur dédiée (DAC dans le jargon) à partir de l&#8217;explorateur d&#8217;objets de SQL Server Management Studio (SSMS), on obtient l&#8217;erreur suivante : Cependant si l&#8217;on se connecte à partir du menu Fichier &#62; Nouveau &#62; &#8230; <a href="https://blog.developpez.com/elsuket/p12003/moteur-de-base-de-donnees-sql-server/dedicated-administrator-connections-are-not-supported-via-ssms-as-it-establishes-multiple-connections-by-design-que-faire">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Lorsqu&rsquo;on tente d&rsquo;ouvrir une connexion d&rsquo;administrateur dédiée (DAC dans le jargon) à partir de l&rsquo;explorateur d&rsquo;objets de SQL Server Management Studio (SSMS), on obtient l&rsquo;erreur suivante :<br />
<span id="more-511"></span><br />
<img src="http://img843.imageshack.us/img843/6505/dac01.png" alt="" /></p>
<p>Cependant si l&rsquo;on se connecte à partir du menu <em>Fichier</em> &gt; <em>Nouveau</em> &gt; <em>Requête de moteur de base de données</em>, nous parvenons à nous connecter avec succès :</p>
<p><img src="http://img22.imageshack.us/img22/1714/dac02.png" alt="" /></p>
<p>L&rsquo;icône de la barre d&rsquo;outils permet de réaliser exactement la même chose :</p>
<p><img src="http://img585.imageshack.us/img585/7820/dac03.png" alt="" /></p>
<p>Cela tient au fait que lorsqu&rsquo;on ouvre une connexion avec l&rsquo;explorateur d&rsquo;objets, SSMS ouvre deux connexions :<br />
&#8211; une pour l&rsquo;explorateur d&rsquo;objets<br />
&#8211; une pour la fenêtre de requête</p>
<p>Or il n&rsquo;est possible d&rsquo;ouvrir qu&rsquo;une seule connexion DAC sur une instance SQL Server.</p>
<p>Petit rappel : une connexion DAC permet de se connecter en UDP sur le port 1434 (par défaut) à une instance SQL Server indisponible (surchage, &#8230;). Pour pouvoir se connecter de cette façon depuis une machine distincte de celle qui héberge l&rsquo;instance SQL Server, il est nécessaire d&rsquo;activer cette fonctionnalité par l&rsquo;option d&rsquo;instance &laquo;&nbsp;remote admin connections&nbsp;&raquo;. Ceci se fait simplement à l&rsquo;aide de la procédure stockée système <em>sp_configure</em> :</p>
<div class="codecolorer-container tsql 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="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">EXEC</span> <span style="color: #AF0000;">sp_configure</span> <span style="color: #FF0000;">'remote admin connections'</span>, <span style="color: #000;">1</span><br />
GO<br />
<span style="color: #0000FF;">RECONFIGURE</span><br />
GO</div></td></tr></tbody></table></div>
<p>Pour savoir si la fonctionnalité est activée, il suffit d&rsquo;interroger la vue système <em>sys.configurations</em>, et de consulter la colonne <em>value_in_use</em> :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">configurations</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; name <span style="color: #808080;">LIKE</span> <span style="color: #FF0000;">'%admin%'</span></div></td></tr></tbody></table></div>
<p><img src="http://img14.imageshack.us/img14/1389/dac04.png" alt="" /></p>
<p>Bonne administration à tous !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vous êtes sûr d&#8217;avoir les BACKUP avec CHECKSUM parce que vous utilisez l&#8217;option COMPRESSION ? Vérifiez une seconde fois !</title>
		<link>https://blog.developpez.com/elsuket/p11990/snippets/backup_checksum_compression</link>
		<comments>https://blog.developpez.com/elsuket/p11990/snippets/backup_checksum_compression#comments</comments>
		<pubDate>Sun, 26 May 2013 13:32:34 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[BACKUP]]></category>
		<category><![CDATA[CHECKSUM]]></category>
		<category><![CDATA[COMPRESSION]]></category>
		<category><![CDATA[DBCC]]></category>
		<category><![CDATA[DBCC IND]]></category>
		<category><![CDATA[DBCC PAGE]]></category>
		<category><![CDATA[maintenance plan]]></category>
		<category><![CDATA[plan de maintenance]]></category>
		<category><![CDATA[sauvegarde]]></category>
		<category><![CDATA[sys.dm_db_database_page_allocations]]></category>
		<category><![CDATA[sys.messages]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=427</guid>
		<description><![CDATA[Après avoir vu comment compresser toutes les sauvegardes de base de données dès SQL Server 2008, il est intéressant de trouver comment activer l&#8217;option CHECKSUM de l&#8217;instruction BACKUP. A ce sujet, la documentation indique : Indique que l&#8217;opération de sauvegarde &#8230; <a href="https://blog.developpez.com/elsuket/p11990/snippets/backup_checksum_compression">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Après avoir vu comment <a href="http://blog.developpez.com/elsuket/p9040/moteur-de-base-de-donnees-sql-server/compresser_tous_les_backups_sans_modifie_2008">compresser toutes les sauvegardes de base de données</a> dès SQL Server 2008, il est intéressant de trouver comment activer l&rsquo;option CHECKSUM de l&rsquo;instruction BACKUP.</p>
<p>A ce sujet, la documentation indique :</p>
<blockquote><p> Indique que l&rsquo;opération de sauvegarde vérifie dans chaque page les informations de somme de contrôle et de page endommagée, si elles sont activées et disponibles, et génère une somme de contrôle pour l&rsquo;ensemble de la sauvegarde. <strong>Ceci est le comportement par défaut pour une sauvegarde compressée</strong>.</p></blockquote>
<p>Vérifions donc si cela est vrai : nous allons créer une base de données de test, et nous allons corrompre une de ses pages afin de vérifier le comportement de la sauvegarde. En effet, l&rsquo;option CHECKSUM permet de détecter la corruption de données au moment de la sauvegarde. Cela permet en plus de ne pas se retrouver dans l’inconfortable situation de devoir restaurer une base de données à partir d&rsquo;un fichier de sauvegarde corrompu.<br />
<span id="more-427"></span><br />
<img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>La vérification de l&rsquo;intégrité des pages au niveau de la base de données</strong></p>
<p>Par défaut, lorsqu&rsquo;on crée une nouvelle base de données sous SQL Server 2005 et suivants, la vérification de l&rsquo;intégrité des pages lues à partir du disque se fait à l&rsquo;aide d&rsquo;une somme de contrôle. Celle-ci est calculée à partir du contenu de la page, puis écrite dans l&rsquo;en-tête de celle-ci au moment de l&rsquo;écriture sur disque. Lorsque la page est ensuite lue à partir du disque, la somme de contrôle est recalculée, puis comparée à celle qui est dans l&rsquo;en-tête de la page : si les valeurs sont identiques, alors la page est intègre; à l&rsquo;inverse, on obtient l&rsquo;erreur 824, qui est écrite à la fois dans les journaux de SQL Server et dans le journal d&rsquo;événements de Windows.<br />
Enfin lorsqu&rsquo;on restaure une base de données qui a été créée sous une version antérieure à 2005, il est important de changer cette option de TORN_PAGE_DETECTION à PAGE_VERIFY, car la première est conservée par défaut. L&rsquo;option TORN_PAGE_DETECTION stocke deux bits pour chaque secteur de 512 octets de toute page, dont la taille est 8192 octets. De la même façon, ces 16 * 2 bits sont stockés dans l&rsquo;en-tête de la page, et comparés à la relecture de la page. Comme cette option est moins stricte que CHECKSUM, il est donc recommandé d&rsquo;utiliser cette dernière option.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Le test</strong></p>
<p>Nous créons donc la base de données sous SQL Server 2012, puis nous vérifions l&rsquo;option du contrôle de l&rsquo;intégrité des pages :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">DATABASE</span> TEST_CHECKSUM;<br />
GO<br />
<br />
<span style="color: #0000FF;">USE</span> TEST_CHECKSUM<br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; name<br />
&nbsp; &nbsp; &nbsp; &nbsp; , page_verify_option_desc<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">databases</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; name <span style="color: #808080;">=</span> <span style="color: #FF0000;">'TEST_CHECKSUM'</span></div></td></tr></tbody></table></div>
<p><img src="http://img843.imageshack.us/img843/1872/backupchecksum01.png" alt="" /></p>
<p>Nous créons ensuite une table dans cette base de données, à laquelle nous ajoutons une ligne :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">USE</span> TEST_CHECKSUM<br />
GO<br />
<br />
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">TABLE</span> test_backup_checksum<br />
<span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; id <span style="color: #0000FF;">tinyint</span> <span style="color: #0000FF;">IDENTITY</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , nom <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">16</span><span style="color: #808080;">&#41;</span><br />
<span style="color: #808080;">&#41;</span><br />
GO<br />
<br />
<span style="color: #0000FF;">INSERT</span> <span style="color: #0000FF;">INTO</span> dbo.<span style="color: #202020;">test_backup_checksum</span> <span style="color: #808080;">&#40;</span>nom<span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">VALUES</span> <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'test_checksum'</span><span style="color: #808080;">&#41;</span><br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; dbo.<span style="color: #202020;">test_backup_checksum</span></div></td></tr></tbody></table></div>
<p>Nous forçons ensuite l&rsquo;écriture des pages sur disque, à l&rsquo;aide de l&rsquo;instruction <a href="http://blog.developpez.com/elsuket/p9529/moteur-de-base-de-donnees-sql-server/lazywriter_checkpoint_aamp_ghost_cleanup">CHECKPOINT</a>, puis nous vidons le cache de données, de sorte que la prochaine fois que nous exécuterons une requête sur cette table, ses pages seront lues à partir du disque, à l&rsquo;aide de l&rsquo;instruction DBCC DROPCLEANBUFFERS.</p>
<p><strong>N.B. : </strong>N&rsquo;exécutez <strong>JAMAIS</strong> une instruction non-documentée sur une base de données qui sert une charge de production. Si tel devait être le cas, je ne peux <strong>en aucun cas être tenu pour responsable des conséquences. Vous devez limiter strictement l&rsquo;usage de cette instruction aux environnements de test</strong>.</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">CHECKPOINT</span><br />
GO<br />
<br />
<span style="color: #0000FF;">DBCC</span> DROPCLEANBUFFERS<br />
GO</div></td></tr></tbody></table></div>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>L&rsquo;instruction DBCC IND, ou la DMF sys.dm_db_database_page_allocations</strong></p>
<p>Encore deux options d&rsquo;exploration de la mécanique interne de SQL Server, qui permettent de lister les pages d&rsquo;une table ou d&rsquo;un index, et qui ne sont pas documentées. Voici le prototype d&rsquo;utilisation de ces deux alternatives :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">DBCC</span> <span style="color: #808080;">IN</span>D <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'TEST_CHECKSUM'</span>, <span style="color: #FF0000;">'dbo.test_backup_checksum'</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #008080;">-- le dernier argument est l'index id</span><br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span>&nbsp; allocated_page_file_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , allocated_page_page_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , allocated_page_iam_file_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , allocated_page_iam_page_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">object_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , index_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , partition_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , allocation_unit_type_desc <span style="color: #0000FF;">AS</span> iam_chain_type<br />
&nbsp; &nbsp; &nbsp; &nbsp; , page_type_desc<br />
&nbsp; &nbsp; &nbsp; &nbsp; , page_level<br />
&nbsp; &nbsp; &nbsp; &nbsp; , rowset_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , next_page_file_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; , next_page_page_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , previous_page_file_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , previous_page_page_id<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_db_database_page_allocations</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #FF00FF;">DB_ID</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'TEST_CHECKSUM'</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">OBJECT_ID</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'dbo.test_backup_checksum'</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #000;">0</span> <span style="color: #008080;">-- index id : 0 pour un tas, 1 pour un index cluster, plus grand pour un index non-cluster</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #808080;">NULL</span> <span style="color: #008080;">-- partition id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF0000;">'DETAILED'</span> <span style="color: #008080;">-- niveau de détail</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; is_allocated <span style="color: #808080;">=</span> <span style="color: #000;">1</span>;</div></td></tr></tbody></table></div>
<p>On remarque tout de suite que la DMF produit bien plus d&rsquo;informations que l&rsquo;instruction DBCC (nous ne donnons pas ici toutes les colonnes), et que ses arguments sont similaires à la DMF <em>sys.dm_db_index_physical_stats</em>.</p>
<p><img src="http://img689.imageshack.us/img689/1618/backupchecksum02.png" alt="" /></p>
<p>Voyons donc ce que contient la page 272, puisque c&rsquo;est elle qui contient les données (page_type_desc = DATA_PAGE) :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-- Activation de la sortie de la commande DBCC</span><br />
<span style="color: #0000FF;">DBCC</span> TRACEON <span style="color: #808080;">&#40;</span><span style="color: #000;">3604</span><span style="color: #808080;">&#41;</span><br />
GO<br />
<br />
<span style="color: #008080;">-- DBCC PAGE ([database_name_or_id], [file_id], [page_id], [option])</span><br />
<span style="color: #008080;">-- option = 0 montre seulement l'en-tête de la page</span><br />
<span style="color: #0000FF;">DBCC</span> PAGE <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'TEST_CHECKSUM'</span>, <span style="color: #000;">1</span>, <span style="color: #000;">272</span>, <span style="color: #000;">0</span><span style="color: #808080;">&#41;</span>;<br />
GO</div></td></tr></tbody></table></div>
<p>Nous obtenons :</p>
<blockquote><p>PAGE: (1:272)</p>
<p>BUFFER:</p>
<p>BUF @0x000000027407BB80</p>
<p>bpage = 0x00000002649F4000          bhash = 0x0000000000000000          bpageno = (1:272)<br />
bdbid = 8                           breferences = 0                     bcputicks = 0<br />
bsampleCount = 0                    bUse1 = 33295                       bstat = 0x9<br />
blog = 0x2121215a                   bnext = 0x0000000000000000          </p>
<p>PAGE HEADER:</p>
<p>Page @0x00000002649F4000</p>
<p>m_pageId = (1:272)                  m_headerVersion = 1                 m_type = 1<br />
m_typeFlagBits = 0x0                m_level = 0                         <strong>m_flagBits = 0x8200</strong><br />
m_objId (AllocUnitId.idObj) = 84    m_indexId (AllocUnitId.idInd) = 256<br />
Metadata: AllocUnitId = 72057594043432960<br />
Metadata: PartitionId = 72057594039042048                                Metadata: IndexId = 0<br />
Metadata: ObjectId = 245575913      m_prevPage = (0:0)                  m_nextPage = (0:0)<br />
pminlen = 5                         m_slotCnt = 1                       m_freeCnt = 8069<br />
m_freeData = 121                    m_reservedCnt = 0                   m_lsn = (30:345:30)<br />
m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0<br />
<strong>m_tornBits = 1209479828</strong>             DB Frag ID = 1</p></blockquote>
<p>Si nous nous en référons à la <a href="http://www.sqlskills.com/blogs/paul/inside-the-storage-engine-anatomy-of-a-page/">documentation donnée par Paul Randal</a>, nous avons bien :</p>
<p>&#8211; <em>m_flagBits = 0x8200</em>, qui indique que l&rsquo;intégrité de la page est vérifiée par somme de contrôle<br />
&#8211; <em>m_tornBits</em> est la somme de contrôle de cette page</p>
<p>Nous allons maintenant mettre la base de données hors-ligne, puis éditer le fichier de données avec un éditeur hexadécimal, de façon à vérifier si SQL Server vérifie bien la somme à la lecture de la page :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">ALTER</span> <span style="color: #0000FF;">DATABASE</span> <span style="color: #0000FF;">SET</span> OFFL<span style="color: #808080;">IN</span>E<br />
GO</div></td></tr></tbody></table></div>
<p>En ce qui concerne la lecture en hexadécimal, j&rsquo;utilise le logiciel <a href="http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm">Hex Editor XVI32</a>. Une fois l&rsquo;outil ouvert en tant qu&rsquo;administrateur, il suffit de chercher la chaîne que nous avons ajouté comme ligne dans la table, en suivant le menu <em>Search</em> / <em>Find</em> :</p>
<p><img src="http://img850.imageshack.us/img850/1565/backupchecksum03.png" alt="" /></p>
<p>Un clic sur le bouton OK nous amène directement à l&rsquo;emplacement, où l&rsquo;on est alors libre de changer la chaîne, où j&rsquo;ai changé le &laquo;&nbsp;k&nbsp;&raquo; en &laquo;&nbsp;d&nbsp;&raquo;, puis sauvé le fichier :</p>
<p><img src="http://img833.imageshack.us/img833/341/backupchecksum04.png" alt="" /></p>
<p>Nous remettons la base de données en ligne :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">ALTER</span> <span style="color: #0000FF;">DATABASE</span> TEST_CHECKSUM<br />
<span style="color: #0000FF;">SET</span> ONL<span style="color: #808080;">IN</span>E<br />
GO</div></td></tr></tbody></table></div>
<p>Aucun problème. Exécutons un SELECT * FROM dbo.test_backup_checksum. Nous obtenons le message suivant :</p>
<blockquote><p>
Msg 824, Level 24, State 2, Line 1<br />
SQL Server detected a logical consistency-based I/O error: incorrect checksum (expected: 0xf9ec3284; actual: 0xfe6c3284). It occurred during a read of page (1:228) in database ID 7 at offset 0x000000001c8000 in file &lsquo;C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\TEST_CHECKSUM.mdf&rsquo;.  Additional messages in the SQL Server error log or system event log may provide more detail. This is a severe error condition that threatens database integrity and must be corrected immediately. Complete a full database consistency check (DBCC CHECKDB). This error can be caused by many factors; for more information, see SQL Server Books Online.</p></blockquote>
<p>Prenons maintenant une sauvegarde de cette base de données, avec COMPRESSION, mais sans spécifier l&rsquo;option CHECKSUM :</p>
<div class="codecolorer-container tsql 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="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">BACKUP</span> <span style="color: #0000FF;">DATABASE</span> TEST_CHECKSUM<br />
<span style="color: #0000FF;">TO</span> <span style="color: #0000FF;">DISK</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'F:\SQLServer2012\TEST_CHECKSUM.bak'</span><br />
<span style="color: #0000FF;">WITH</span> COMPRESSION<br />
GO</div></td></tr></tbody></table></div>
<p>Aucun problème : nous obtenons :</p>
<blockquote><p>Processed 280 pages for database &lsquo;TEST_CHECKSUM&rsquo;, file &lsquo;TEST_CHECKSUM&rsquo; on file 1.<br />
Processed 3 pages for database &lsquo;TEST_CHECKSUM&rsquo;, file &lsquo;TEST_CHECKSUM_log&rsquo; on file 1.<br />
BACKUP DATABASE successfully processed 283 pages in 0.468 seconds (4.709 MB/sec).</p></blockquote>
<p>Voyons ce que contient la table d&rsquo;historique des sauvegardes :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #FF00FF;">user_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , backup_start_date<br />
&nbsp; &nbsp; &nbsp; &nbsp; , recovery_model<br />
&nbsp; &nbsp; &nbsp; &nbsp; , has_backup_checksums<br />
&nbsp; &nbsp; &nbsp; &nbsp; , is_damaged<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; msdb.<span style="color: #202020;">dbo</span>.<span style="color: #202020;">backupset</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; database_name <span style="color: #808080;">=</span> <span style="color: #FF0000;">'TEST_CHECKSUM'</span></div></td></tr></tbody></table></div>
<p><img src="http://img195.imageshack.us/img195/6295/backupchecksum05.png" alt="" /></p>
<p>On obtient un résultat similaire avec l&rsquo;instruction RESTORE HEADERONLY (colonnes <em>HasBackupChecksums</em> et <em>IsDamaged</em> toutes deux à zéro) :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">RESTORE</span> HEADERONLY<br />
<span style="color: #0000FF;">FROM</span> <span style="color: #0000FF;">DISK</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'F:\SQLServer2012\TEST_CHECKSUM.bak'</span></div></td></tr></tbody></table></div>
<p>Le fichier de sauvegarde ne dispose pas de la somme de contrôle, et n&rsquo;est pas marqué comme endommagé. Pourtant nous avons bien corrompu le fichier de données, et nous ne pouvons pas lire la table que nous avons peuplé auparavant !</p>
<p>Voyons ce que produit la même instruction, avec l&rsquo;option CHECKSUM :</p>
<div class="codecolorer-container tsql 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="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">BACKUP</span> <span style="color: #0000FF;">DATABASE</span> TEST_CHECKSUM<br />
<span style="color: #0000FF;">TO</span> <span style="color: #0000FF;">DISK</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'F:\SQLServer2012\TEST_CHECKSUM_CC.bak'</span><br />
<span style="color: #0000FF;">WITH</span> COMPRESSION, <span style="color: #FF00FF;">CHECKSUM</span><br />
GO</div></td></tr></tbody></table></div>
<blockquote><p>Msg 3043, Level 16, State 1, Line 1<br />
BACKUP &lsquo;TEST_CHECKSUM&rsquo; detected an error on page (1:228) in file &lsquo;C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\TEST_CHECKSUM.mdf&rsquo;.<br />
Msg 3013, Level 16, State 1, Line 1<br />
BACKUP DATABASE is terminating abnormally.</p></blockquote>
<p>Voyons maintenant la même instruction, seulement avec l&rsquo;option CHECKSUM :</p>
<div class="codecolorer-container tsql 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="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">BACKUP</span> <span style="color: #0000FF;">DATABASE</span> TEST_CHECKSUM<br />
<span style="color: #0000FF;">TO</span> <span style="color: #0000FF;">DISK</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'F:\SQLServer2012\TEST_CHECKSUM_CHK.bak'</span><br />
<span style="color: #0000FF;">WITH</span> <span style="color: #FF00FF;">CHECKSUM</span><br />
GO</div></td></tr></tbody></table></div>
<p>Nous obtenons la même erreur. Si nous interrogeons de nouveau la table d&rsquo;historique des sauvegardes pour cette base de données, nous ne trouvons que le premier backup, dont on sait qu&rsquo;il est corrompu. Pourtant nous n&rsquo;avons (presque) aucun moyen de le savoir, car ni cette table, ni l&rsquo;instruction RESTORE HEADERONLY ne permettent de vérifier que le fichier est bien intègre. On peut cependant vérifier les journaux de SQL Server à l&rsquo;aide de la procédure stockée étendue <a href="http://blog.developpez.com/elsuket/p10279/moteur-de-base-de-donnees-sql-server/gestion_lecture_journaux_sql_server"><em>xp_readerrorlog</em></a>, où l&rsquo;on trouve :</p>
<p><img src="http://img17.imageshack.us/img17/9685/backupchecksum06.png" alt="" /></p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Détecter la corruption le plus tôt possible</strong></p>
<p>Une des premières choses à faire après avoir réalisé une installation fraîche de SQL Server est d&rsquo;ajouter une liste d&rsquo;alertes de l&rsquo;Agent SQL Server, qui enverront un mail dès la détection d&rsquo;un problème de corruption. Ceci nécessite le paramétrage de Database Mail, et la mise en place d&rsquo;un opérateur SQL Agent. Voici le code qui permet d&rsquo;ajouter l&rsquo;alerte :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #008080;">-------------------------------</span><br />
<span style="color: #008080;">-- Nicolas Souquet - 26/05/2013</span><br />
<span style="color: #008080;">-------------------------------</span><br />
<span style="color: #0000FF;">DECLARE</span> @i <span style="color: #0000FF;">smallint</span> <span style="color: #808080;">=</span> <span style="color: #000;">823</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @alert_name sysname<br />
<br />
<span style="color: #0000FF;">DECLARE</span> @operator_name sysname <span style="color: #808080;">=</span> <span style="color: #FF0000;">'monOperateur'</span><br />
<br />
<span style="color: #0000FF;">WHILE</span> @i <span style="color: #808080;">&amp;</span>lt;<span style="color: #808080;">=</span> <span style="color: #000;">825</span><br />
<span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; @alert_name <span style="color: #808080;">=</span> <span style="color: #808080;">&amp;</span>#039;Message <span style="color: #808080;">&amp;</span>#039; <span style="color: #808080;">+</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>@i <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">char</span><span style="color: #808080;">&#40;</span><span style="color: #000;">3</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span> msdb.<span style="color: #202020;">dbo</span>.<span style="color: #AF0000;">sp_add_alert</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @name <span style="color: #808080;">=</span> @alert_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @message_id <span style="color: #808080;">=</span> @i<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @severity <span style="color: #808080;">=</span> <span style="color: #000;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @enabled <span style="color: #808080;">=</span> <span style="color: #000;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @delay_between_responses <span style="color: #808080;">=</span> <span style="color: #000;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @include_event_description_in <span style="color: #808080;">=</span> <span style="color: #000;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @job_id <span style="color: #808080;">=</span> N<span style="color: #808080;">&amp;</span>#039;00000000<span style="color: #808080;">-</span>0000<span style="color: #808080;">-</span>0000<span style="color: #808080;">-</span>0000<span style="color: #808080;">-</span>000000000000<span style="color: #808080;">&amp;</span>#039;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span> msdb.<span style="color: #202020;">dbo</span>.<span style="color: #AF0000;">sp_add_notification</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @alert_name <span style="color: #808080;">=</span> @alert_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @operator_name <span style="color: #808080;">=</span> @operator_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @notification_method <span style="color: #808080;">=</span> <span style="color: #000;">1</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @i <span style="color: #808080;">=</span> @i <span style="color: #808080;">+</span> <span style="color: #000;">1</span><br />
<span style="color: #0000FF;">END</span></div></td></tr></tbody></table></div>
<p>L&rsquo;erreur qui nous intéresse est la 824, mais les erreurs 823 et 825 sont importantes aussi. Pour trouver leur signification, il suffit d&rsquo;interroger la vue système <em>sys.messages</em> :</p>
<div class="codecolorer-container tsql 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="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">messages</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; message_id <span style="color: #808080;">BETWEEN</span> <span style="color: #000;">823</span> <span style="color: #808080;">AND</span> <span style="color: #000;">825</span><br />
<span style="color: #808080;">AND</span> &nbsp; &nbsp; language_id <span style="color: #808080;">=</span> <span style="color: #000;">1036</span> <span style="color: #008080;">-- Français</span></div></td></tr></tbody></table></div>
<p>On peut faire de même avec l&rsquo;erreur n° 3043, qui est celle que l&rsquo;on obtient lors de la sauvegarde.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Activer CHECKSUM pour toutes les sauvegardes</strong></p>
<p>Cela devrait aussi faire partie de la checklist d&rsquo;installation de SQL Server, d&rsquo;autant que c&rsquo;est d&rsquo;une simplicité enfantine : il suffit d&rsquo;activer le drapeau de trace n° 3023 :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">DBCC</span> TRACEON <span style="color: #808080;">&#40;</span><span style="color: #000;">3023</span>, <span style="color: #808080;">-</span><span style="color: #000;">1</span><span style="color: #808080;">&#41;</span></div></td></tr></tbody></table></div>
<p>Après avoir exécuté cette instruction, si nous ré-exécutons maintenant la commande suivante :</p>
<div class="codecolorer-container tsql 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="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">BACKUP</span> <span style="color: #0000FF;">DATABASE</span> TEST_CHECKSUM<br />
<span style="color: #0000FF;">TO</span> <span style="color: #0000FF;">DISK</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'F:\SQLServer2012\TEST_CHECKSUM.bak'</span><br />
<span style="color: #0000FF;">WITH</span> COMPRESSION<br />
GO</div></td></tr></tbody></table></div>
<p>Nous obtenons l&rsquo;erreur que nous avions obtenue lorsque nous avions ajouté l&rsquo;option CHECKSUM :</p>
<blockquote><p>Msg 3043, Level 16, State 1, Line 1<br />
BACKUP &lsquo;TEST_CHECKSUM&rsquo; detected an error on page (1:228) in file &lsquo;C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA\TEST_CHECKSUM.mdf&rsquo;.<br />
Msg 3013, Level 16, State 1, Line 1<br />
BACKUP DATABASE is terminating abnormally.</p></blockquote>
<p>Ceci est très pratique :</p>
<p>&#8211; Si l&rsquo;on prend les sauvegardes de base de données à l&rsquo;aide de <a href="http://blog.developpez.com/elsuket/p11161/agent-sql-server/supporter_plan_de_maintenance">plans de maintenance</a>, il est impossible de spécifier que l&rsquo;on souhaite avoir la somme de contrôle;<br />
&#8211; Si l&rsquo;on code une procédure stockée qui s&rsquo;en charge, cela évite d&rsquo;avoir à l&rsquo;ajouter dans le code.</p>
<p>D&rsquo;autre part si la <a href="http://blog.developpez.com/elsuket/p9040/moteur-de-base-de-donnees-sql-server/compresser_tous_les_backups_sans_modifie_2008">compression des sauvegardes est activée au niveau de l&rsquo;instance</a>, on n&rsquo;a plus qu&rsquo;a se soucier de la sauvegarde elle-même !</p>
<p>Bonnes sauvegardes et intégrité de pages à tous !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mise au point à propos du compteur de performance Page Life Expectancy</title>
		<link>https://blog.developpez.com/elsuket/p11951/moteur-de-base-de-donnees-sql-server/mise-au-point-a-propos-du-compteur-de-performance-page-life-expectancy</link>
		<comments>https://blog.developpez.com/elsuket/p11951/moteur-de-base-de-donnees-sql-server/mise-au-point-a-propos-du-compteur-de-performance-page-life-expectancy#comments</comments>
		<pubDate>Mon, 06 May 2013 12:17:05 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=279</guid>
		<description><![CDATA[Parmi les compteurs de performance qu&#8217;expose SQL Server, il en existe quelques-uns qui ne laissent aucun doute sur les performances courantes d&#8217;une instance SQL Server. Page Life Expectancy est l&#8217;un d&#8217;entre eux, puisqu&#8217;il nous renseigne sur la durée de vie &#8230; <a href="https://blog.developpez.com/elsuket/p11951/moteur-de-base-de-donnees-sql-server/mise-au-point-a-propos-du-compteur-de-performance-page-life-expectancy">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Parmi les compteurs de performance qu&rsquo;expose SQL Server, il en existe quelques-uns qui ne laissent aucun doute sur les performances courantes d&rsquo;une instance SQL Server. <em>Page Life Expectancy</em> est l&rsquo;un d&rsquo;entre eux, puisqu&rsquo;il nous renseigne sur la durée de vie moyenne d&rsquo;une page de données en RAM, en secondes.</p>
<p>L&rsquo;ensemble des opérations de manipulation de données se faisant exclusivement en mémoire par tout SGBDR digne de ce nom, on comprend aisément que plus la valeur exposée par ce compteur est élevée, plus les performances de l&rsquo;instance sont correctes. En effet, comme un accès en RAM est en pratique au moins 1000 fois plus rapide qu&rsquo;un accès à des disques mécaniques, plus on peut traiter de données en RAM, moins on est exposé à des problèmes de performances.</p>
<p>Cela étant, les serveurs physiques actuels disposant de plusieurs sockets pour accueillir leurs CPUs, ils sont tous une implémentation de NUMA (<em>Non-Uniform Memory Access</em>), dans lequel chaque processeur dispose d&rsquo;un bus mémoire dédié. On appelle nœud NUMA l&rsquo;ensemble composé par l&rsquo;espace mémoire et le processeur situés sur le même bus. On désigne par nœud NUMA distant un nœud NUMA distinct de celui sur lequel la requête s&rsquo;exécute. </p>
<p>Si par le passé on pouvait donc se référer directement à la valeur de ce compteur, puisque les serveur ne disposaient que d&rsquo;un seul socket, qu&rsquo;en est-il avec les architectures multi-socket ? Comment suivre cette valeur sous SQL Server ? Quelle valeur de ce compteur peut servir de seuil d&rsquo;alerte ?</p>
<p>Je vous propose la réponse à ces questions dans cet article !<br />
<span id="more-279"></span></p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Page Life Expectancy (PLE), qu&rsquo;est-ce que c&rsquo;est ?</strong></p>
<p>Comme nous l&rsquo;avons vu en introduction, ce compteur de performance nous indique, en secondes, la durée moyenne pendant laquelle une page reste stockée dans en RAM : c&rsquo;est ce que l&rsquo;on appelle plus communément le <em>buffer pool</em>.</p>
<p>Comme les opérations de lecture et d&rsquo;écriture se font exclusivement en RAM, plus une page de données reste longtemps dans le buffer pool, plus l&rsquo;instance SQL Server étudiée fonctionne proprement.</p>
<p>Au contraire, si la valeur de ce compteur est faible <strong>de façon constante</strong>, cela signifie que SQL Server est constamment obligé d&rsquo;importer les pages stockées sur disque en RAM, avant de réaliser l&rsquo;opération qu&rsquo;on lui a soumis. Cela signifie généralement que la majeure partie de la charge de travail que l&rsquo;on soumet à SQL Server lit une quantité de données qui excède celle de la RAM disponible sur le serveur, ce qui peut par exemple être du tout simplement à une configuration incorrecte de l&rsquo;option d&rsquo;instance <em>max server memory (MB)</em>, à une indexation pauvre, à un plan d&rsquo;exécution sous-optimal, &#8230;<br />
Il est à noter que si l&rsquo;on observe des valeurs faibles de façon sporadique, pour une durée de quelques secondes, cela est plus proche de signifier qu&rsquo;une requête produit un grand nombre d&rsquo;entrées/sorties. Une trace <a href="http://elsuket.developpez.com/tutoriels/sqlserveur/fichier-trace-cote-serveur/"><em>SQL Profiler</em></a> combinée à un fichier du <em>Moniteur de Performances</em> permettra de déterminer la requête coupable (dans SQL Profiler, choisir File &gt; Import Performance Data pour corréler un fichier .blg avec un fichier de trace).</p>
<p>Une valeur élevée pour PLE n&rsquo;équivaut pas à une pastille verte quand à l&rsquo;état des performances de l&rsquo;instance SQL Server auditée. Il est nécessaire de corréler la valeur de ce compteur avec celle du compteur <em>Buffer Cache Hit Ratio</em> (BCHR): ce dernier exprime par un pourcentage la proportion de pages trouvées directement en RAM par rapport au nombre de pages importées à partir des disques. Ici encore, on saisit facilement que plus on est proche de 100%, plus les performances sont optimales. PLE peut avoir une valeur décente et BCHR être faible : cela signifie que les disques sont largement sollicités par la charge de travail, et qu&rsquo;ils parviennent à fournir les pages de données suffisamment rapidement à SQL Server pour qu&rsquo;il puisse opérer sans que l&rsquo;on note une véritable dégradation des performances. Dans ce cas, un audit des requêtes grandes consommatrices d&rsquo;I/O et une optimisation sont nécessaires. Je vous invite à un <a href="http://blog.developpez.com/mikedavem/?s=+Lock+Pages+In+Memory">approfondissement</a> sur le blog de Mikedavem.</p>
<p>Finalement, lorsque l&rsquo;un ou l&rsquo;autre de ces compteurs montre une valeur faible, nous sommes en présence d&rsquo;une charge de travail qui fait subir au serveur une pression mémoire qu&rsquo;il est urgent d&rsquo;investiguer. C&rsquo;est à partir de ces deux compteurs que l&rsquo;on va décider de s&rsquo;intéresser ou non à d&rsquo;autres compteurs de performance (comme les queues disque, le nombre d&rsquo;opération <a href="http://blog.developpez.com/elsuket/p9529/moteur-de-base-de-donnees-sql-server/lazywriter_checkpoint_aamp_ghost_cleanup">checkpoints et lazywites</a> par seconde), &#8230;</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> <strong>Où trouver ce compteur de performance ?</strong></p>
<p>On trouve ce compteur de performance dans le <em>Moniteur de Performances</em>, sous la catégorie <em>SQL Server:Buffer Manager</em>, de même que BCHR :</p>
<p><img src="http://img40.imageshack.us/img40/5834/miseaupointplebuffermgr.png" alt="" /></p>
<p>Néanmoins, en fouillant un peu plus, on trouve le groupe <em>SQL Server:Buffer Node</em> :</p>
<p><img src="http://imageshack.us/a/img853/4583/miseaupointplebuffernod.png" alt="" /></p>
<p>On est alors libre de suivre toutes les <em>nodes</em>, c&rsquo;est à dire les nœuds NUMA de façon individuelle, mais il nous est d&rsquo;abord nécessaire de savoir sur quel nœud NUMA ladite requête s&rsquo;exécute. Ceci prouve que la moyenne des PLE de chaque nœud NUMA, exposée par le compteur <em>SQL Server:Buffer Manager</em> / <em>Page Life Expectancy</em> masque cet état de fait. </p>
<p>Implicitement, SQL Server va donc affecter l&rsquo;exécution d&rsquo;une requête au planificateur qui est le plus susceptible de disposer, dans l&rsquo;espace mémoire qu&rsquo;il adresse, toutes les données dont la requête a besoin. Ceci est dû au fait que l&rsquo;accès à un nœud NUMA distant est coûteux en ressources CPU.<br />
L&rsquo;affectation de la quantité de mémoire se fait de manière triviale : SQL Server lit la valeur de l&rsquo;option de configuration <em>max server memory (KB)</em>, et affecte à chaque nœud NUMA cette quantité de mémoire divisée par le nombre de nœuds NUMA du serveur. Si ladite option n&rsquo;est pas configurée, SQL Server produit le même calcul avec la quantité de RAM disponible sur le serveur.</p>
<p><img src="http://img12.imageshack.us/img12/5913/iconarrowp.gif" alt="" /> Comment détecter un pression mémoire sur un nœud NUMA ?</p>
<p>Peu après la sortie commerciale de SQL Server 2005, Microsoft a publié un <a href="http://technet.microsoft.com/en-us/library/cc966413.aspx">livre blanc</a> dans lequel il était préconisé qu&rsquo;une valeur de 300 pour PLE était une situation à éviter pour une instance SQL Server supportant une chage de travail OLTP. Malheureusement, cette recommandation s&rsquo;est répandue et est restée comme un standard officieux, alors qu&rsquo;il est totalement obsolète : en effet à cette époque là, peu de serveur disposaient de plusieurs dizaines de Go de RAM, et on était au point de basculement entre les architectures CPU 32 bits et 64 bits. 300 secondes signifie qu&rsquo;en 5 minutes, SQL Server lit autant de pages depuis les disque que de mémoire qui lui est alloué. Si l&rsquo;on applique cela à un serveur qui dispose de 128 Go de RAM, il devient évident que cette valeur seuil n&rsquo;est plus appropriée. On peut considérer qu&rsquo;à cette époque, les serveurs de base de données disposaient en moyenne de 8Go de RAM. On peut appliquer une règle de trois sur les configurations actuelles pour détecter une pression mémoire.</p>
<p>On peut exposer la différence entre les nœuds NUMA à l&rsquo;aide de la vue de gestion dynamique (DMV) <em>sys.dm_os_schedulers</em> : celle-ci expose au travers de la colonne <em>parent_node_id</em> le nœud NUMA auquel un planificateur d&rsquo;exécution de requête accepte ces dernières. Le lot de requêtes suivant aide à mieux comprendre ce qui se passe sur un serveur servant une instance SQL Server :</p>
<div class="codecolorer-container tsql 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 /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">TRANSACTION</span> <span style="color: #0000FF;">ISOLATION</span> <span style="color: #0000FF;">LEVEL</span> <span style="color: #0000FF;">READ</span> <span style="color: #0000FF;">UNCOMMITTED</span><br />
GO<br />
<br />
<span style="color: #0000FF;">DECLARE</span> @max_server_memory_MB <span style="color: #0000FF;">int</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @memory_node_count <span style="color: #0000FF;">int</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; , @node_ple_threshold <span style="color: #0000FF;">int</span><br />
<br />
<span style="color: #008080;">-- Lecture de la valeur configurée pour l'option max server memory (MB)</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; @max_server_memory_MB <span style="color: #808080;">=</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #0000FF;">value</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">int</span><span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">configurations</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; name <span style="color: #808080;">=</span> <span style="color: #FF0000;">'max server memory (MB)'</span><br />
<br />
<span style="color: #008080;">-- Lecture du nombre de noeuds NUMA</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; @memory_node_count <span style="color: #808080;">=</span> <span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">*</span><span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; sys.<span style="color: #202020;">dm_os_memory_nodes</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; memory_node_id &nbsp;<span style="color: #000;">64</span> <span style="color: #008080;">-- le noeud 64 est pour la fonctionnalité Dedicated Administrator Connection</span><br />
<br />
<span style="color: #008080;">-- Application de la règle de trois au seuil édité par Microsoft en 2006</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; @node_ple_threshold <span style="color: #808080;">=</span> <span style="color: #808080;">&#40;</span><span style="color: #808080;">&#40;</span>@max_server_memory_MB <span style="color: #808080;">/</span> @memory_node_count<span style="color: #808080;">&#41;</span> <span style="color: #808080;">*</span> <span style="color: #000;">300</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">/</span> <span style="color: #000;">8192</span><br />
<br />
<span style="color: #008080;">-- Affichage des valeurs obtenues</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; @max_server_memory_MB <span style="color: #0000FF;">AS</span> max_server_memory_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; , @memory_node_count <span style="color: #0000FF;">AS</span> memory_node_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; , @node_ple_threshold <span style="color: #0000FF;">AS</span> NUMA_node_PLE_threshold<br />
<br />
<span style="color: #008080;">-- Exposition de la PLE pour chaque noeud NUMA</span><br />
<span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; S.<span style="color: #202020;">parent_node_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , PC.<span style="color: #202020;">cntr_value</span> <span style="color: #0000FF;">AS</span> node_PLE<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , PC.<span style="color: #202020;">cntr_value</span> <span style="color: #808080;">/</span> @node_ple_threshold <span style="color: #0000FF;">AS</span> min_PLE_factor<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CASE</span> <span style="color: #0000FF;">WHEN</span> PC.<span style="color: #202020;">cntr_value</span> <span style="color: #808080;">&amp;</span>lt;<span style="color: #808080;">=</span> @node_ple_threshold <span style="color: #0000FF;">THEN</span> <span style="color: #FF0000;">'KO'</span> <span style="color: #0000FF;">ELSE</span> <span style="color: #FF0000;">'OK'</span> <span style="color: #0000FF;">END</span> <span style="color: #0000FF;">AS</span> node_PLE_state<br />
<span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_exec_requests</span> <span style="color: #0000FF;">AS</span> R<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_os_schedulers</span> <span style="color: #0000FF;">AS</span> S<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> R.<span style="color: #202020;">scheduler_id</span> <span style="color: #808080;">=</span> S.<span style="color: #202020;">scheduler_id</span><br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">dm_os_performance_counters</span> <span style="color: #0000FF;">AS</span> PC<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> PC.<span style="color: #202020;">instance_name</span> <span style="color: #808080;">=</span> <span style="color: #FF00FF;">REPLICATE</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'0'</span>, <span style="color: #000;">3</span> <span style="color: #808080;">-</span> <span style="color: #FF00FF;">LEN</span><span style="color: #808080;">&#40;</span>S.<span style="color: #202020;">parent_node_id</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>S.<span style="color: #202020;">parent_node_id</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">10</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span><br />
<span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; R.<span style="color: #202020;">command</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LAZY WRITER'</span> <span style="color: #008080;">-- Il existe un processus Lazywriter par noeud NUMA</span><br />
<span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PC.<span style="color: #202020;">counter_name</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'Page life expectancy'</span></div></td></tr></tbody></table></div>
<p>Ceci donne par exemple :</p>
<p><img src="http://imageshack.us/a/img818/4863/plepernodeserver.png" alt="" /></p>
<p>On voit bien ici que la PLE est bien plus faible sur le nœud NUMA 0, et qu&rsquo;elle est pas totalement identique sur les autres nœuds.<br />
On peut donc penser à mettre en place une alerte lorsque la PLE d&rsquo;une des noeuds NUMA passe en-dessous de la valeur calculée par le script ci-dessus.<br />
Malheureusement les alertes proposées par SQL Server Agent ne permettent de prendre en compte que la moyenne des PLE de tous les nœuds NUMA, c&rsquo;est à dire le compteur de performance <em>SQL Server:Buffer Manager</em> / <em>Page Life Expectancy</em>.<br />
On peut cependant exécuter à intervalles réguliers et fréquents une procédure stockée qui vérifie la PLE de chaque noeud NUMA, à l&rsquo;aide d&rsquo;un job de l&rsquo;Agent SQL Server.</p>
<p>Bon monitoring à tous !</p>
<p>ElSüket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Une procédure stockée pour connaître l&#8217;état des fichiers du journal des transactions</title>
		<link>https://blog.developpez.com/elsuket/p11777/moteur-de-base-de-donnees-sql-server/une-procedure-stockee-pour-connaitre-letat-des-fichiers-du-journal-des-transactions</link>
		<comments>https://blog.developpez.com/elsuket/p11777/moteur-de-base-de-donnees-sql-server/une-procedure-stockee-pour-connaitre-letat-des-fichiers-du-journal-des-transactions#comments</comments>
		<pubDate>Mon, 11 Feb 2013 05:12:22 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Non documenté]]></category>
		<category><![CDATA[DBCC]]></category>
		<category><![CDATA[journal]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[transaction]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=199</guid>
		<description><![CDATA[Ha ! le fichier du journal des transactions, l&#8217;option de récupération, son grossissement, &#8230; et bien sûr la fameuse transaction restée ouverte qui a provoqué une explosion de la taille de celui-ci, allant jusqu&#8217;à remplir le volume disque qui l&#8217;héberge &#8230; <a href="https://blog.developpez.com/elsuket/p11777/moteur-de-base-de-donnees-sql-server/une-procedure-stockee-pour-connaitre-letat-des-fichiers-du-journal-des-transactions">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Ha ! le fichier du journal des transactions, l&rsquo;option de récupération, son grossissement, &#8230; et bien sûr la fameuse transaction restée ouverte qui a provoqué une explosion de la taille de celui-ci, allant jusqu&rsquo;à remplir le volume disque qui l&rsquo;héberge : tout autant de paramétrages et d&rsquo;investigations fastidieuses.</p>
<p>Alors comme je n&rsquo;aime pas beaucoup répéter plusieurs fois les mêmes opérations sans avoir un script, ou mieux, une procédure stockée sous la main, j&rsquo;ai créé la suivante, dont voici le script de création :</p>
<div class="codecolorer-container tsql 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 />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br /></div></td><td><div class="tsql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0000FF;">USE</span> master<br />
GO<br />
<br />
<span style="color: #008080;">-----------------------------------------------------------------</span><br />
<span style="color: #008080;">-- Nicolas Souquet - 09/02/2013</span><br />
<span style="color: #008080;">-- LA PROCEDURE STOCKEE SUIVANTE EST DONNEE EN TANT QUE TELLE</span><br />
<span style="color: #008080;">-- SON UTILISATION ET SA MODIFICATION EST A VOS RISQUES ET PÉRILS</span><br />
<span style="color: #008080;">-----------------------------------------------------------------</span><br />
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">PROCEDURE</span> <span style="color: #808080;">&#91;</span>dbo<span style="color: #808080;">&#93;</span>.<span style="color: #808080;">&#91;</span>sp__log_space_get<span style="color: #808080;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @_database_name sysname <span style="color: #808080;">=</span> <span style="color: #808080;">NULL</span><br />
<span style="color: #0000FF;">AS</span><br />
<span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> <span style="color: #0000FF;">NOCOUNT</span> <span style="color: #0000FF;">ON</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @<span style="color: #0000FF;">sql</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">256</span><span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Récupération de l'espace disque disponible</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- sur tous les volumes visibles par l'instance SQL Server</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @free_disk_space <span style="color: #0000FF;">TABLE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; drive_letter <span style="color: #0000FF;">char</span><span style="color: #808080;">&#40;</span><span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , free_space_MB <span style="color: #0000FF;">int</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @free_disk_space<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span>&nbsp; &nbsp; master.<span style="color: #202020;">dbo</span>.<span style="color: #202020;">xp_fixeddrives</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Récupération de l'occupation des fichiers des journaux de transaction</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- de toutes les bases de données hébergées par l'instance SQL Server</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @dbcc_sqlperf_logspace <span style="color: #0000FF;">TABLE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; database_name sysname<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , log_size <span style="color: #0000FF;">float</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , log_space_used_pct <span style="color: #0000FF;">decimal</span> <span style="color: #808080;">&#40;</span><span style="color: #000;">5</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , status <span style="color: #0000FF;">tinyint</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @dbcc_sqlperf_logspace<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span>&nbsp; &nbsp; <span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'DBCC SQLPERF(logspace)'</span><span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Récupération de la liste de tous les fichiers virtuels</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- du fichier du journal des transactions de toutes les bases de données</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- disponibles, hébergées par l'instance SQL Server</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @dbcc_loginfo <span style="color: #0000FF;">TABLE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; recovery_unit_id <span style="color: #0000FF;">tinyint</span> <span style="color: #008080;">-- new column in SQL Server 2012</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , fileid <span style="color: #0000FF;">tinyint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , file_size <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , start_offset <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , f_seq_no <span style="color: #0000FF;">bigint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , status <span style="color: #0000FF;">tinyint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , parity <span style="color: #0000FF;">tinyint</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , create_LSN <span style="color: #0000FF;">varbinary</span><span style="color: #808080;">&#40;</span><span style="color: #FF00FF;">max</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">NOT</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Cas où l'on souhaite réaliser l'audit du fichier du journal des transactions</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- de toutes les bases de données hébergées par l'instance SQL Server</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Dans ce cas le paramètre d'entrée @_database_name est à NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> @_database_name <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @dbcc_loginfo_all_db <span style="color: #0000FF;">TABLE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; database_name <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">128</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , log_file_id <span style="color: #0000FF;">tinyint</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , vlf_count <span style="color: #0000FF;">smallint</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Récupération de liste de toutes les bases de données disponibles</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- (pas une capture iOFFLINE, SINGLE_USER, ou ... SUSPECT ;))</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @dbcc_loginfo_all_db<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , log_file_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , vlf_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , MF.<span style="color: #FF00FF;">file_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #000;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">databases</span> <span style="color: #0000FF;">AS</span> D<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">master_files</span> <span style="color: #0000FF;">AS</span> MF<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> D.<span style="color: #202020;">database_id</span> <span style="color: #808080;">=</span> MF.<span style="color: #202020;">database_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">source_database_id</span> <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span> <span style="color: #008080;">-- ce n'est pas une capture instantanée de base de données</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">state_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ONLINE'</span> <span style="color: #008080;">-- la base de données est disponible</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">user_access_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'MULTI_USER'</span> <span style="color: #008080;">-- la base de données est à l'écoute de connexions utilisateur</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MF.<span style="color: #202020;">type_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LOG'</span> <span style="color: #008080;">-- le type de fichier est &quot;journal des transactions&quot;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Pour chaque base de données, récupération de la liste des fichiers virtuels</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- du fichier du journal des transactions pour toutes les bases de données disponibles</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHILE</span> <span style="color: #808080;">EXISTS</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #808080;">*</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; @dbcc_loginfo_all_db<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; vlf_count <span style="color: #808080;">=</span> <span style="color: #000;">0</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; <span style="color: #0000FF;">TOP</span> <span style="color: #000;">1</span> @_database_name <span style="color: #808080;">=</span> database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; @dbcc_loginfo_all_db<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; vlf_count <span style="color: #808080;">=</span> <span style="color: #000;">0</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @<span style="color: #0000FF;">sql</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'DBCC LOGINFO ('</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @_database_name <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">')'</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @dbcc_loginfo<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span>&nbsp; &nbsp; <span style="color: #808080;">&#40;</span>@<span style="color: #0000FF;">sql</span><span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;<span style="color: #0000FF;">WITH</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CTE <span style="color: #0000FF;">AS</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; fileid<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">*</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> vlf_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; @dbcc_loginfo<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">GROUP</span> &nbsp; <span style="color: #0000FF;">BY</span> fileid<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">UPDATE</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @dbcc_loginfo_all_db<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vlf_count <span style="color: #808080;">=</span> C.<span style="color: #202020;">vlf_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @dbcc_loginfo_all_db <span style="color: #0000FF;">AS</span> DLAD<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; CTE <span style="color: #0000FF;">AS</span> C<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> DLAD.<span style="color: #202020;">log_file_id</span> <span style="color: #808080;">=</span> C.<span style="color: #202020;">fileid</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DLAD.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> @_database_name<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DELETE</span>&nbsp; <span style="color: #0000FF;">FROM</span> @dbcc_loginfo<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Résultat final, avec addition de quelques détails</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LS.<span style="color: #202020;">database_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , D.<span style="color: #202020;">recovery_model_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , MF.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> logical_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , FDS.<span style="color: #202020;">drive_letter</span> <span style="color: #0000FF;">AS</span> transaction_log_file_stored_on<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , FDS.<span style="color: #202020;">free_space_MB</span> <span style="color: #0000FF;">AS</span> volume_free_space_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>LS.<span style="color: #202020;">log_size</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">38</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> transaction_log_file_size_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , LS.<span style="color: #202020;">log_space_used_pct</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#40;</span>LS.<span style="color: #202020;">log_space_used_pct</span> <span style="color: #808080;">/</span> <span style="color: #000;">100.0</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">*</span> LS.<span style="color: #202020;">log_size</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">38</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> log_used_size_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CASE</span> MF.<span style="color: #202020;">is_percent_growth</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">THEN</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">growth</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">3</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' %'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">growth</span> <span style="color: #808080;">/</span> <span style="color: #000;">128</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">20</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' MB'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> <span style="color: #0000FF;">AS</span> growth &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , D.<span style="color: #202020;">log_reuse_wait_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , DLAD.<span style="color: #202020;">vlf_count</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , MF.<span style="color: #202020;">physical_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">master_files</span> <span style="color: #0000FF;">AS</span> MF<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; @dbcc_sqlperf_logspace <span style="color: #0000FF;">AS</span> LS<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> LS.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> <span style="color: #FF00FF;">DB_NAME</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">database_id</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; @free_disk_space <span style="color: #0000FF;">AS</span> FDS<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> FDS.<span style="color: #202020;">drive_letter</span> <span style="color: #808080;">=</span> <span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">physical_name</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">COLLATE</span> database_default<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">databases</span> <span style="color: #0000FF;">AS</span> D<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> D.<span style="color: #202020;">name</span> <span style="color: #808080;">=</span> LS.<span style="color: #202020;">database_name</span> <span style="color: #0000FF;">COLLATE</span> database_default<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; @dbcc_loginfo_all_db <span style="color: #0000FF;">AS</span> DLAD<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> DLAD.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> D.<span style="color: #202020;">name</span> <span style="color: #0000FF;">COLLATE</span> database_default<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> DLAD.<span style="color: #202020;">log_file_id</span> <span style="color: #808080;">=</span> MF.<span style="color: #FF00FF;">file_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> DLAD.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> <span style="color: #FF00FF;">DB_NAME</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">database_id</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MF.<span style="color: #202020;">type_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LOG'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">source_database_id</span> <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">state_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ONLINE'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">user_access_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'MULTI_USER'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Si la base de données que l'on souhaite auditer n'existe pas ==&amp;gt; exception</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">IF</span> <span style="color: #FF00FF;">DB_ID</span><span style="color: #808080;">&#40;</span>@_database_name<span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">BEGIN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RAISERROR</span><span style="color: #808080;">&#40;</span><span style="color: #FF0000;">'The database named '</span><span style="color: #FF0000;">'%s'</span><span style="color: #FF0000;">' does not exist'</span>, <span style="color: #000;">16</span>, <span style="color: #000;">1</span>, @_database_name<span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">RETURN</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- récupération de la liste des fichiers virtuels</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- du fichier du journal des transactions de la base de données choisie</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">DECLARE</span> @vlf_count <span style="color: #0000FF;">int</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SET</span> @<span style="color: #0000FF;">sql</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'DBCC LOGINFO ('</span><span style="color: #FF0000;">''</span> <span style="color: #808080;">+</span> @_database_name <span style="color: #808080;">+</span> <span style="color: #FF0000;">''</span><span style="color: #FF0000;">')'</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INSERT</span>&nbsp; <span style="color: #0000FF;">INTO</span> @dbcc_loginfo<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">EXEC</span>&nbsp; &nbsp; <span style="color: #808080;">&#40;</span>@<span style="color: #0000FF;">sql</span><span style="color: #808080;">&#41;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">-- Résultat final, avec addition de quelques détails</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;<span style="color: #0000FF;">WITH</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CTE <span style="color: #0000FF;">AS</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; fileid<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #FF00FF;">COUNT</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">*</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> vlf_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; @dbcc_loginfo<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">GROUP</span> &nbsp; <span style="color: #0000FF;">BY</span> fileid<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">SELECT</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LS.<span style="color: #202020;">database_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , D.<span style="color: #202020;">recovery_model_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , MF.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> logical_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , FDS.<span style="color: #202020;">drive_letter</span> <span style="color: #0000FF;">AS</span> transaction_log_file_stored_on<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , FDS.<span style="color: #202020;">free_space_MB</span> <span style="color: #0000FF;">AS</span> volume_free_space_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>LS.<span style="color: #202020;">log_size</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">38</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> transaction_log_file_size_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , LS.<span style="color: #202020;">log_space_used_pct</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span><span style="color: #808080;">&#40;</span>LS.<span style="color: #202020;">log_space_used_pct</span> <span style="color: #808080;">/</span> <span style="color: #000;">100.0</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">*</span> LS.<span style="color: #202020;">log_size</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">decimal</span><span style="color: #808080;">&#40;</span><span style="color: #000;">38</span>,<span style="color: #000;">2</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">AS</span> log_used_size_MB<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , <span style="color: #0000FF;">CASE</span> MF.<span style="color: #202020;">is_percent_growth</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHEN</span> <span style="color: #000;">1</span> <span style="color: #0000FF;">THEN</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">growth</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">3</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' %'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ELSE</span> <span style="color: #0000FF;">CAST</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">growth</span> <span style="color: #808080;">/</span> <span style="color: #000;">128</span> <span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">varchar</span><span style="color: #808080;">&#40;</span><span style="color: #000;">20</span><span style="color: #808080;">&#41;</span><span style="color: #808080;">&#41;</span> <span style="color: #808080;">+</span> <span style="color: #FF0000;">' MB'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span> <span style="color: #0000FF;">AS</span> growth<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , D.<span style="color: #202020;">log_reuse_wait_desc</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , C.<span style="color: #202020;">vlf_count</span> <span style="color: #0000FF;">AS</span> VLF_count<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , MF.<span style="color: #202020;">physical_name</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">FROM</span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">master_files</span> <span style="color: #0000FF;">AS</span> MF<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; @dbcc_sqlperf_logspace <span style="color: #0000FF;">AS</span> LS<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> LS.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> <span style="color: #FF00FF;">DB_NAME</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">database_id</span><span style="color: #808080;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; @free_disk_space <span style="color: #0000FF;">AS</span> FDS<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> FDS.<span style="color: #202020;">drive_letter</span> <span style="color: #808080;">=</span> <span style="color: #0000FF;">LEFT</span><span style="color: #808080;">&#40;</span>MF.<span style="color: #202020;">physical_name</span>, <span style="color: #000;">1</span><span style="color: #808080;">&#41;</span> <span style="color: #0000FF;">COLLATE</span> database_default<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">databases</span> <span style="color: #0000FF;">AS</span> D<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> D.<span style="color: #202020;">name</span> <span style="color: #808080;">=</span> LS.<span style="color: #202020;">database_name</span> <span style="color: #0000FF;">COLLATE</span> database_default<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; CTE <span style="color: #0000FF;">AS</span> C<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">ON</span> C.<span style="color: #202020;">fileid</span> <span style="color: #808080;">=</span> MF.<span style="color: #FF00FF;">file_id</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; MF.<span style="color: #202020;">type_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'LOG'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LS.<span style="color: #202020;">database_name</span> <span style="color: #808080;">=</span> @_database_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">source_database_id</span> <span style="color: #0000FF;">IS</span> <span style="color: #808080;">NULL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">state_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'ONLINE'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080;">AND</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; D.<span style="color: #202020;">user_access_desc</span> <span style="color: #808080;">=</span> <span style="color: #FF0000;">'MULTI_USER'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000FF;">END</span><br />
<span style="color: #0000FF;">END</span><br />
GO<br />
<br />
<span style="color: #008080;">-- On marque la procédure stockée comme objet système</span><br />
<span style="color: #008080;">-- Dès lors, on pourra l'exécuter dans n'importe quel contexte de base de données</span><br />
<span style="color: #0000FF;">EXEC</span> sp_ms_marksystemobject <span style="color: #FF0000;">'sp__log_space_get'</span></div></td></tr></tbody></table></div>
<p>Elle donne un résultat comme le suivant :</p>
<p><a href="http://blog.developpez.com/elsuket/p11777/moteur-de-base-de-donnees-sql-server/une-procedure-stockee-pour-connaitre-letat-des-fichiers-du-journal-des-transactions/attachment/sp__log_space_get" rel="attachment wp-att-203"><img src="http://blog.developpez.com/elsuket/files/2013/02/sp__log_space_get-300x29.png" alt="sp__log_space_get" width="300" height="29" class="alignnone size-medium wp-image-203" /></a></p>
<p>à savoir :</p>
<p>&#8211; le nom de la base de données<br />
&#8211; l&rsquo;option de récupération de la base de données<br />
&#8211; le nom logique du fichier du journal des transactions (utile pour un DBCC SHRINKFILE après que le journal ait explosé en taille)<br />
&#8211; le volume sur lequel est hébergé le fichier du journal des transactions<br />
&#8211; la quantité d&rsquo;espace disque libre restant sur ce volume<br />
&#8211; la taille actuelle du fichier du journal des transactions<br />
&#8211; le pourcentage d&rsquo;utilisation de ce fichier (taille occupée dans le fichier par rapport à la taille totale du fichier)<br />
&#8211; la taille équivalente à ce pourcentage<br />
&#8211; le paramètre de grossissement de ce fichier<br />
&#8211; ce qui empêche actuellement la troncature de l&rsquo;espace occupé dans ce fichier<br />
&#8211; le chemin complet du fichier</p>
<p>On peut utiliser cette procédure stockée sous SQL Server 2005, 2008 et 2012.<br />
Elle fonctionne également pour les bases de données ayant plusieurs fichiers du journal des transactions</p>
<p>Bonne gestion des fichiers du journal des transactions !</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>Reprise d&#8217;activité étape par étapes : le poster de Paul Randal</title>
		<link>https://blog.developpez.com/elsuket/p11773/moteur-de-base-de-donnees-sql-server/reprise-dactivite-etape-par-etapes-le-poster-de-paul-randal</link>
		<comments>https://blog.developpez.com/elsuket/p11773/moteur-de-base-de-donnees-sql-server/reprise-dactivite-etape-par-etapes-le-poster-de-paul-randal#comments</comments>
		<pubDate>Sat, 09 Feb 2013 04:21:00 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>
		<category><![CDATA[disaster recovery]]></category>
		<category><![CDATA[DR]]></category>
		<category><![CDATA[HA]]></category>
		<category><![CDATA[HADR]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=191</guid>
		<description><![CDATA[Paul Randal est très connu dans la communauté SQL Server puisqu&#8217;il publie très régulièrement des détails sur le fonctionnement interne de SQL Server, dont certains ne sont pas documentés, à travers son site SQLSkills.com (son blog et ceux d&#8217;autres experts &#8230; <a href="https://blog.developpez.com/elsuket/p11773/moteur-de-base-de-donnees-sql-server/reprise-dactivite-etape-par-etapes-le-poster-de-paul-randal">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Paul Randal est très connu dans la communauté SQL Server puisqu&rsquo;il publie très régulièrement des détails sur le fonctionnement interne de SQL Server, dont certains ne sont pas documentés, à travers son site <a href="http://www.sqlskills.com/" title="SQLSkills.com" target="_blank">SQLSkills.com</a> (son blog et ceux d&rsquo;autres experts sont référencés en bas à droite de la page).</p>
<p>Paul Randal vient donc de mettre à la disposition de la communauté un <a href="http://www.sqlskills.com/blogs/paul/sql-server-disaster-recovery-poster-now-available/" title="SQL Server Disaster Recovery Poster Now Available" target="_blank">poster</a> qui détaille les étapes de la reprise d&rsquo;activité par un diagramme décisionnel.</p>
<p>Ce diagramme contient certaines étapes qui référencent un numéro, et chaque numéro correspond à un article publié par Paul Randal. Ils sont tous référencés sur <a href="http://www.sqlskills.com/drposter.asp" title="SQL Server Disaster Recovery Poster Steps Details" target="_blank">cette page</a>.</p>
<p>Toujours bon à avoir sous la main !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cadeau de Noël de Kalen Delaney : un livre sur le verrouillage, le blocage et le versionnement de ligne</title>
		<link>https://blog.developpez.com/elsuket/p11606/moteur-de-base-de-donnees-sql-server/livre_verrouillage_blocage_versionning</link>
		<comments>https://blog.developpez.com/elsuket/p11606/moteur-de-base-de-donnees-sql-server/livre_verrouillage_blocage_versionning#comments</comments>
		<pubDate>Sat, 22 Dec 2012 07:24:37 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Lecture]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[blocage]]></category>
		<category><![CDATA[blocking]]></category>
		<category><![CDATA[lock]]></category>
		<category><![CDATA[verrou]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=177</guid>
		<description><![CDATA[Le site de RedGate, créé par Bard Mc Gehee, publie depuis quelques années déjà de nombreux ouvrages, dont certains abordent des thèmes que l&#8217;on voit rarement explorés en détails, parfois même par les mêmes auteurs chez d&#8217;autres éditeurs. Vous n&#8217;avez &#8230; <a href="https://blog.developpez.com/elsuket/p11606/moteur-de-base-de-donnees-sql-server/livre_verrouillage_blocage_versionning">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Le site de RedGate, créé par Bard Mc Gehee, publie depuis quelques années déjà de nombreux ouvrages, dont certains abordent des thèmes que l&rsquo;on voit rarement explorés en détails, parfois même par les mêmes auteurs chez d&rsquo;autres éditeurs.</p>
<p>Vous n&rsquo;avez plus grand chose à vous mettre sous la dent après avoir lu comment fonctionne <a href="http://blog.developpez.com/elsuket/p11069/moteur-de-base-de-donnees-sql-server/comprendre_plan_requete_optimiseur" title="Comprendre les plans d’exécution et l’Optimiseur de requêtes : deux très bons ouvrages" target="_blank">l&rsquo;optimiseur de requêtes</a> ? On ne peut pas déclarer cela sérieusement avec la sortie récente de SQL Server 2012, et de ses nombreuses innovations ou améliorations <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>Malgré toutes ces nouveautés à décortiquer, les fondamentaux du fonctionnement de SQL Server demeurent. Donc pour Noël, Kalen Delaney nous fait le cadeau de son dernier ouvrage, <a href="http://www.red-gate.com/community/books/sql-server-concurrency" title="SQL Server Concurrency by Kalen Delaney"><em>SQL Server Concurrency: Locking, Blocking and Row Versioning</em></a>, et que l&rsquo;on peut déjà télécharger gratuitement en PDF (d&rsquo;habitude RedGate ne le permet qu&rsquo;après quelques mois).</p>
<p>Bonne lecture de Noël à tous !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Trouver et corriger les index uniques (non filtrés) sans contrainte</title>
		<link>https://blog.developpez.com/elsuket/p11206/moteur-de-base-de-donnees-sql-server/indexation/index_unique_sans_contrainte</link>
		<comments>https://blog.developpez.com/elsuket/p11206/moteur-de-base-de-donnees-sql-server/indexation/index_unique_sans_contrainte#comments</comments>
		<pubDate>Wed, 08 Aug 2012 08:16:01 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Exception faite des index unique filtrées, il n&#8217;y aucune différence en termes de performances entre l&#8217;ajout d&#8217;un index unique, et l&#8217;ajout d&#8217;une contrainte d&#8217;unicité (qui est elle-même supportée par un index unique). La contrainte d&#8217;unicité permet de signifier que l’intégrité &#8230; <a href="https://blog.developpez.com/elsuket/p11206/moteur-de-base-de-donnees-sql-server/indexation/index_unique_sans_contrainte">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Exception faite des index unique filtrées, il n&rsquo;y aucune différence en termes de performances entre l&rsquo;ajout d&rsquo;un index unique, et l&rsquo;ajout d&rsquo;une contrainte d&rsquo;unicité (qui est elle-même supportée par un index unique).<br />
La contrainte d&rsquo;unicité permet de signifier que l’intégrité des données est le but, alors que le but premier d&rsquo;un index est l&rsquo;accélération des requêtes.<br />
La majorité des index unique étant ajoutés pour renforcer l’intégrité des données, voici donc un script pour trouver tous les index unique non filtrés qui n&rsquo;ont pas de contrainte d&rsquo;unicité.</p>
<p><span id="more-31"></span></p>
<p>Ce script donne :</p>
<p>&#8211; le nom de la table<br />
&#8211; le nom de l&rsquo;index actuel<br />
&#8211; la liste des colonnes clé de l&rsquo;index<br />
&#8211; le script T-SQL de normalisation du nom de la contrainte d&rsquo;unicité et de suppression de l&rsquo;index actuel.</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 /></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 - 2012-08-08 <br />
------------------------------- <br />
DECLARE @cr char(2) = CHAR(13) + CHAR(10) <br />
&nbsp;<br />
;WITH <br />
&nbsp; CTE AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;S.name AS schema_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , T.name AS table_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , I.name AS index_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , LEFT(KC.key_column_list, LEN(KC.key_column_list) - 1) AS key_column_list <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;sys.indexes AS I <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON I.object_id = T.object_id <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.schemas AS S <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON T.schema_id = S.schema_id <br />
&nbsp; &nbsp; CROSS APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;CS.name + ', ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns AS CS <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS ICS <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON CS.object_id = ICS.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND CS.column_id = ICS.column_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;I.index_id = ICS.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;I.object_id = ICS.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;ICS.is_included_column = 0 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ORDER BY &nbsp;ICS.index_column_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FOR &nbsp; &nbsp;XML PATH ('') <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS KC (key_column_list) <br />
&nbsp; &nbsp; WHERE &nbsp; &nbsp;I.is_unique = 1 -- l'index est unique <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;I.is_primary_key = 0 -- il ne s'agit pas d'un index de clé primaire <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;T.is_ms_shipped = 0 -- il ne s'agit pas d'une table système <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;I.is_unique_constraint = 0 -- l'index n'a pas de contrainte <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;I.has_filter = 0 -- l'index n'est pas filtré <br />
&nbsp; ) <br />
SELECT &nbsp;schema_name + '.' + table_name AS qualified_table_name <br />
&nbsp; , index_name AS current_index_name <br />
&nbsp; , key_column_list <br />
&nbsp; , 'ALTER TABLE ' + schema_name + '.' + table_name + @cr <br />
&nbsp; &nbsp; + 'ADD CONSTRAINT UQ_' + table_name + '__' + REPLACE(key_column_list, ', ', '__') + @cr <br />
&nbsp; &nbsp; + ' &nbsp;UNIQUE (' + key_column_list + ')' + @cr + 'GO' + @cr + @cr <br />
&nbsp; &nbsp; + 'DROP INDEX ' + QUOTENAME(index_name) + ' ON ' + schema_name + '.' + table_name + @cr + 'GO' + @cr + @cr <br />
FROM &nbsp;CTE <br />
ORDER &nbsp;BY table_name</div></td></tr></tbody></table></div>
<p>Bonne gestion des index !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>23</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 procédure stockée pour trouver sous quel compte de service s&#8217;exécute une instance SQL Server</title>
		<link>https://blog.developpez.com/elsuket/p8531/moteur-de-base-de-donnees-sql-server/une_procedure_stockee_pour_trouver_sous</link>
		<comments>https://blog.developpez.com/elsuket/p8531/moteur-de-base-de-donnees-sql-server/une_procedure_stockee_pour_trouver_sous#comments</comments>
		<pubDate>Tue, 19 Jan 2010 10:28:25 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une petite procédure stockée qui affiche dans la console de SSMS le nom du compte de service sous lequel s&#8217;exécute une instance SQL Server : 12345678910111213141516171819202122232425CREATE PROCEDURE spGetSQLServerServiceAccountName AS BEGIN &#160; DECLARE @nomInstance SYSNAME, &#160; &#160; @nomMachine SYSNAME &#160; &#8230; <a href="https://blog.developpez.com/elsuket/p8531/moteur-de-base-de-donnees-sql-server/une_procedure_stockee_pour_trouver_sous">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une petite procédure stockée qui affiche dans la console de SSMS le nom du compte de service sous lequel s&rsquo;exécute une instance SQL Server :</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">CREATE PROCEDURE spGetSQLServerServiceAccountName <br />
AS <br />
BEGIN <br />
&nbsp; DECLARE @nomInstance SYSNAME, <br />
&nbsp; &nbsp; @nomMachine SYSNAME <br />
&nbsp; &nbsp; <br />
&nbsp; SELECT @nomInstance = CAST(SERVERPROPERTY('InstanceName') AS SYSNAME), <br />
&nbsp; &nbsp; @nomMachine = @@SERVERNAME <br />
&nbsp;<br />
&nbsp; DECLARE @cle NVARCHAR(256), <br />
&nbsp; &nbsp; @compteDeService NVARCHAR(128) <br />
&nbsp; &nbsp; <br />
&nbsp; SELECT @cle = CASE &nbsp;<br />
&nbsp; &nbsp; &nbsp; WHEN @nomInstance IS NULL THEN N'SYSTEM\CurrentControlSet\Services\MSSQLServer' <br />
&nbsp; &nbsp; &nbsp; ELSE N'SYSTEM\CurrentControlSet\Services\MSSQL$' + @nomInstance <br />
&nbsp; &nbsp; END <br />
&nbsp; <br />
&nbsp; EXEC master.dbo.xp_regread N'HKEY_LOCAL_MACHINE', <br />
&nbsp; &nbsp; &nbsp; &nbsp;@cle, <br />
&nbsp; &nbsp; &nbsp; &nbsp;N'ObjectName', <br />
&nbsp; &nbsp; &nbsp; &nbsp;@compteDeService OUTPUT, <br />
&nbsp; &nbsp; &nbsp; &nbsp;N'no_output' <br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; PRINT 'Le compte de service est ' + @compteDeService <br />
END</div></td></tr></tbody></table></div>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connaître les caractéristiques d&#8217;une trace SQL Profiler</title>
		<link>https://blog.developpez.com/elsuket/p9016/moteur-de-base-de-donnees-sql-server/connaitre_les_caracteristiques_d_une_tra</link>
		<comments>https://blog.developpez.com/elsuket/p9016/moteur-de-base-de-donnees-sql-server/connaitre_les_caracteristiques_d_une_tra#comments</comments>
		<pubDate>Wed, 16 Jun 2010 06:27:27 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[T-SQL]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Sur un serveur à la configuration sous-dimensionnée que je surveille de temps en temps, j&#8217;ai trouvé une trace SQL Profiler en cours d&#8217;exécution. J&#8217;ai voulu en savoir plus sur les caractéristiques de cette trace. Voici la requête : 123456789101112131415------------------------------- -- &#8230; <a href="https://blog.developpez.com/elsuket/p9016/moteur-de-base-de-donnees-sql-server/connaitre_les_caracteristiques_d_une_tra">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Sur un serveur à la configuration sous-dimensionnée que je surveille de temps en temps, j&rsquo;ai trouvé une trace SQL Profiler en cours d&rsquo;exécution.<br />
J&rsquo;ai voulu en savoir plus sur les caractéristiques de cette trace.<br />
Voici la requête :</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 /></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 - 16/06/2010 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;C.name <br />
&nbsp; &nbsp; , FI.value <br />
&nbsp; &nbsp; , T.start_time <br />
&nbsp; &nbsp; , T.last_event_time <br />
&nbsp; &nbsp; , T.event_count <br />
&nbsp; &nbsp; , S.login_name <br />
&nbsp; &nbsp; , S.session_id <br />
&nbsp; &nbsp; , 'EXEC sp_trace_setstatus ' + CAST(T.id AS varchar(10)) + ', 0' AS stop_trace_stmt <br />
FROM &nbsp; &nbsp;sys.traces AS T <br />
CROSS APPLY &nbsp;sys.fn_trace_getfilterinfo (T.id) AS FI <br />
INNER JOIN &nbsp;sys.trace_columns AS C ON FI.columnid = C.trace_column_id <br />
INNER JOIN &nbsp;sys.dm_exec_sessions AS S ON S.session_id = T.reader_spid</div></td></tr></tbody></table></div>
<p>On sait tout de suite quel filtres ont été utilisés à l&rsquo;aide des deux premières colonnes.<br />
La dernière colonne contient l&rsquo;instruction qui permet d&rsquo;arrêter la trace : le développeur a donc toujours ses résultats.</p>
<p>Pour savoir comment créer une trace côté serveur, c&rsquo;est par <a href="http://elsuket.developpez.com/tutoriels/sqlserveur/fichier-trace-cote-serveur/">ici</a></p>
<p>Bon traçage !</p>
<p>ElSüket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Suivre le nombre de fichiers journaux virtuels du fichier du journal des transactions</title>
		<link>https://blog.developpez.com/elsuket/p9312/moteur-de-base-de-donnees-sql-server/suivre_le_nombre_de_fichiers_journaux_vi</link>
		<comments>https://blog.developpez.com/elsuket/p9312/moteur-de-base-de-donnees-sql-server/suivre_le_nombre_de_fichiers_journaux_vi#comments</comments>
		<pubDate>Thu, 23 Sep 2010 06:00:02 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Avant d&#8217;envisager une réduction du fichier du journal des transactions, il convient de connaître le nombre de fichiers virtuels que contient le fichier du journal des transactions. On peut également envisager de le faire grossir de nouveau pour avoir moins &#8230; <a href="https://blog.developpez.com/elsuket/p9312/moteur-de-base-de-donnees-sql-server/suivre_le_nombre_de_fichiers_journaux_vi">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Avant d&rsquo;envisager une réduction du fichier du journal des transactions,  il convient de connaître  le nombre de fichiers virtuels que contient le fichier du journal des transactions.<br />
On peut également envisager de le faire grossir de nouveau pour avoir moins de fichiers virtuels, et obtenir de meilleures performances pour les transactions manipulant un grand volume de données.<br />
Voyons comment faire cela :</p>
<p><span id="more-104"></span></p>
<p>Il s&rsquo;agit ici d&rsquo;utiliser une bonne vieille commande DBCC <strong>non documentée</strong> : DBCC LOGINFO.<br />
Chaque ligne retournée par l&rsquo;instruction DBCC LOGINFO représente en fait un fichier virtuel.</p>
<p>Sur une base de données de production pour laquelle le fichier du journal des transactions est sauvegardé régulièrement mais où la croissance automatique a été mal gérée, on peut obtenir un grand nombre de fichiers virtuels.</p>
<p>En effet, le fichier du journal des transactions grossit suivant le paramètre d&rsquo;agrandissement de celui-ci pour la base de données considérée.<br />
Si celui-ci est petit, nous aurons un nombre de fichiers virtuels élevé.<br />
D&rsquo;où, encore une fois, l&rsquo;importance de tailler les fichiers de la base de données lors de la création de celle-ci.</p>
<p>En fait, les fichiers virtuel en cours d&rsquo;utilisation ont leur valeur de colonne <em>Status</em> égale à 2.<br />
Si l&rsquo;on veut donc savoir combien sont en cours d&rsquo;utilisation, il suffit d&rsquo;exécuter le petit script suivant :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">DECLARE @vlf TABLE <br />
( <br />
&nbsp; &nbsp; FileId tinyint <br />
&nbsp; &nbsp; , FileSize bigint <br />
&nbsp; &nbsp; , StartOffset bigint <br />
&nbsp; &nbsp; , FSeqNo int <br />
&nbsp; &nbsp; , Status tinyint <br />
&nbsp; &nbsp; , Parity tinyint <br />
&nbsp; &nbsp; , CreateLSN varchar(21) <br />
) <br />
&nbsp;<br />
INSERT &nbsp; &nbsp;@vlf <br />
EXEC ('DBCC LOGINFO') <br />
&nbsp;<br />
SELECT &nbsp; &nbsp;SUM(FileSize) / 1048576 AS total_file_size_MB <br />
&nbsp; &nbsp; , SUM <br />
&nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; CASE Status <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 2 THEN FileSize <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE 0 <br />
&nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; ) / 1048576 AS file_size_in_use_MB &nbsp; &nbsp; <br />
&nbsp; &nbsp; , COUNT(*) AS VLF_amount <br />
&nbsp; &nbsp; , SUM <br />
&nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; CASE Status <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 2 THEN 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE 0 <br />
&nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; ) AS VLF_in_use <br />
FROM &nbsp; &nbsp;@vlf</div></td></tr></tbody></table></div>
<p>Bonne gestion du fichier du journal des transactions <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p>ElSuket <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>3</slash:comments>
		</item>
		<item>
		<title>Attacher une base de données qui n&#8217;a pas de fichier du journal des transactions</title>
		<link>https://blog.developpez.com/elsuket/p11188/moteur-de-base-de-donnees-sql-server/attacher_base_donnees_sans_tran_log</link>
		<comments>https://blog.developpez.com/elsuket/p11188/moteur-de-base-de-donnees-sql-server/attacher_base_donnees_sans_tran_log#comments</comments>
		<pubDate>Sat, 28 Jul 2012 15:18:35 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici comment attacher une base de données SQL Server pour laquelle on dispose seulement des fichiers de données mais pas du fichier du journal des transactions. L&#8217;exemple qui suit est basé sur l&#8217;attachement de la base de données exemple AdventureWorks2012, &#8230; <a href="https://blog.developpez.com/elsuket/p11188/moteur-de-base-de-donnees-sql-server/attacher_base_donnees_sans_tran_log">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici comment attacher une base de données SQL Server pour laquelle on dispose seulement des fichiers de données mais pas du fichier du journal des transactions.</p>
<p><span id="more-123"></span></p>
<p>L&rsquo;exemple qui suit est basé sur l&rsquo;attachement de la base de données exemple <em>AdventureWorks2012</em>, que l&rsquo;on peut télécharger sur le site <a href="http://msftdbprodsamples.codeplex.com/releases/view/55330">CodePlex</a> :</p>
<p><img src="http://blog.developpez.com/media/attach_no_tran_log_file_01.png" width="594" height="619" alt="" /></p>
<p>Une fois le fichier téléchargé, il suffit de le placer dans le dossier où l&rsquo;on souhaite que la base de données réside.<br />
Dans mon cas, il s&rsquo;agit de D:\SQLServer :</p>
<p><img src="http://blog.developpez.com/media/attach_no_tran_log_file_02.png" width="548" height="162" alt="" /></p>
<p>Passons sous <em>SQL Server Management Studio</em>, où l&rsquo;on peut attacher une base de données à une instance SQL Server après un clic-droit sur le nœud <em>Databases</em> > <em>Attach &#8230;</em> :</p>
<p><img src="http://blog.developpez.com/media/attach_no_tran_log_file_03.png" width="382" height="326" alt="" /></p>
<p>Il suffit de cliquer sur le bouton <em>Add &#8230;</em> dans le dialogue qui s&rsquo;ouvre &#8230;</p>
<p><img src="http://blog.developpez.com/media/attach_no_tran_log_file_04.png" width="703" height="624" alt="" /></p>
<p>&#8230; et de référencer le fichier de données :</p>
<p><img src="http://blog.developpez.com/media/attach_no_tran_log_file_05.png" width="440" height="608" alt="" /></p>
<p>Une fois que l&rsquo;on a cliqué sur OK, le dialogue est mis à jour de la façon suivante :</p>
<p><img src="http://blog.developpez.com/media/attach_no_tran_log_file_06.png" width="965" height="637" alt="" /></p>
<p>Il suffit alors de sélectionner le fichier du journal de transaction (qui n&rsquo;existe pas), et de cliquer sur le bouton <em>Remove</em>, puis sur <em>OK</em> :</p>
<p><img src="http://blog.developpez.com/media/attach_no_tran_log_file_08.png" width="642" height="574" alt="" /></p>
<p>Le fichier du journal des transactions est automatiquement recréé, et la base de données est maintenant attachée.</p>
<p>Cela peut aussi se faire par un script, avec l&rsquo;option ATTACH_REBUILD_LOG de l&rsquo;instruction CREATE DATABASE :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">USE master <br />
GO <br />
&nbsp;<br />
CREATE DATABASE AdventureWorks2012 <br />
ON (FILENAME = N'D:\SQLServer\AdventureWorks2012_Data.mdf') <br />
FOR ATTACH_REBUILD_LOG <br />
GO</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/attach_no_tran_log_file_09.png" width="847" height="297" alt="" /></p>
<p>Bon attachement de bases de données !</p>
<p>ElSüket <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Activer la compression par défaut de toutes les sauvegardes de base de données</title>
		<link>https://blog.developpez.com/elsuket/p11176/moteur-de-base-de-donnees-sql-server/compression_par_defaut_sauvegardes</link>
		<comments>https://blog.developpez.com/elsuket/p11176/moteur-de-base-de-donnees-sql-server/compression_par_defaut_sauvegardes#comments</comments>
		<pubDate>Fri, 27 Jul 2012 18:51:58 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[SQL Server 2008 a introduit la compression native des sauvegardes de base de données. S&#8217;il est simple d&#8217;ajouter l&#8217;option COMPRESSION dans une instruction BACKUP, il est encore mieux de ne même pas avoir à y penser. Pour cela, il suffit &#8230; <a href="https://blog.developpez.com/elsuket/p11176/moteur-de-base-de-donnees-sql-server/compression_par_defaut_sauvegardes">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>SQL Server 2008 a introduit la compression native des sauvegardes de base de données.<br />
S&rsquo;il est simple d&rsquo;ajouter l&rsquo;option COMPRESSION dans une instruction BACKUP, il est encore mieux de ne même pas avoir à y penser.<br />
Pour cela, il suffit d&rsquo;activer la compression par défaut de toutes les sauvegardes de base de données.<br />
Notons que cela vaut pour :</p>
<p>&#8211; tous les types de sauvegarde (complète, différentielle, du journal des transactions, partielle, &#8230;)<br />
&#8211; les sauvegardes réalisées à l&rsquo;aide de plans de maintenance.</p>
<p><span id="more-122"></span></p>
<p>Il s&rsquo;agit en fait d&rsquo;une option d&rsquo;instance, nommée <em>backup compression default</em>.<br />
Par défaut elle est désactivée, mais il est très simple de l&rsquo;activer.</p>
<p>=> <strong>Avec la procédure stockée système <em>sp_configure</em></strong> :</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">EXEC dbo.sp_configure 'backup compression default', 1 <br />
GO <br />
RECONFIGURE <br />
GO</div></td></tr></tbody></table></div>
<p>=> <strong>Avec <em>SQL Server Management Studio</em></strong> :</p>
<p>Après avoir cliqué-droit sur l&rsquo;instance dans l&rsquo;explorateur d&rsquo;objets (F8), il suffit de se rendre dans la page <em>Options de base de données</em> :</p>
<p><img src="http://blog.developpez.com/media/backup_compression.png" width="704" height="632" alt="" /></p>
<p>Cliquez sur OK et le tour est joué !</p>
<p>Bonnes sauvegardes; n&rsquo;oubliez pas de les tester de temps en temps <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>Attention aux types de données money et smallmoney !</title>
		<link>https://blog.developpez.com/elsuket/p11175/moteur-de-base-de-donnees-sql-server/attention_money_smallmoney</link>
		<comments>https://blog.developpez.com/elsuket/p11175/moteur-de-base-de-donnees-sql-server/attention_money_smallmoney#comments</comments>
		<pubDate>Wed, 25 Jul 2012 18:23:18 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[En effet, ces deux types de données produisent des erreurs de calculs. Voici un petit test pour révéler cela : 12345678910111213141516171819202122DECLARE @mon1 smallmoney, &#160; &#160; &#160; &#160;@mon2 smallmoney, &#160; &#160; &#160; &#160;@mon3 smallmoney, &#160; &#160; &#160; &#160;@mon4 smallmoney, &#160; &#160; &#8230; <a href="https://blog.developpez.com/elsuket/p11175/moteur-de-base-de-donnees-sql-server/attention_money_smallmoney">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>En effet, ces deux types de données produisent des erreurs de calculs.<br />
Voici un petit test pour révéler cela :</p>
<p><span id="more-12"></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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">DECLARE @mon1 smallmoney, <br />
&nbsp; &nbsp; &nbsp; &nbsp;@mon2 smallmoney, <br />
&nbsp; &nbsp; &nbsp; &nbsp;@mon3 smallmoney, <br />
&nbsp; &nbsp; &nbsp; &nbsp;@mon4 smallmoney, <br />
&nbsp; &nbsp; &nbsp; &nbsp;@num1 decimal(19,4), <br />
&nbsp; &nbsp; &nbsp; &nbsp;@num2 decimal(19,4), <br />
&nbsp; &nbsp; &nbsp; &nbsp;@num3 decimal(19,4), <br />
&nbsp; &nbsp; &nbsp; &nbsp;@num4 decimal(19,4) <br />
&nbsp;<br />
SELECT @mon1 = 100 <br />
&nbsp; &nbsp; &nbsp; &nbsp;, @mon2 = 339 <br />
&nbsp; &nbsp; &nbsp; &nbsp;, @mon3 = 10000 <br />
&nbsp; &nbsp; &nbsp; &nbsp;--- <br />
&nbsp; &nbsp; &nbsp; &nbsp;, @num1 = 100 <br />
&nbsp; &nbsp; &nbsp; &nbsp;, @num2 = 339 <br />
&nbsp; &nbsp; &nbsp; &nbsp;, @num3 = 10000 <br />
&nbsp;<br />
SELECT @mon4 = @mon1 / @mon2 * @mon3 <br />
&nbsp; &nbsp; &nbsp; &nbsp;, @num4 = @num1 / @num2 * @num3 <br />
&nbsp;<br />
SELECT @mon4 AS money_result <br />
&nbsp; &nbsp; &nbsp; &nbsp;, @num4 AS numeric_result</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/money_error.PNG" width="325" height="507" alt="" /></p>
<p>Attention donc au <a href="http://blog.developpez.com/elsuket/p8233/sql-general/du-choix-des-types-de-donnees/">choix des types de données</a> !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Une procédure stockée système pour monitorer les verrous</title>
		<link>https://blog.developpez.com/elsuket/p11135/moteur-de-base-de-donnees-sql-server/procedure_monitor_locks</link>
		<comments>https://blog.developpez.com/elsuket/p11135/moteur-de-base-de-donnees-sql-server/procedure_monitor_locks#comments</comments>
		<pubDate>Thu, 05 Jul 2012 02:01:08 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une procédure stockée qui permet de lister les verrous en cours dans une instance SQL Server 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788USE master GO ------------------------------- -- Nicolas Souquet - 05/07/2012 ------------------------------- CREATE PROCEDURE sp__processes_locks &#160; @_spid int = NULL AS BEGIN &#160; SET NOCOUNT &#8230; <a href="https://blog.developpez.com/elsuket/p11135/moteur-de-base-de-donnees-sql-server/procedure_monitor_locks">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une procédure stockée qui permet de lister les verrous en cours dans une instance SQL Server</p>
<p><span id="more-121"></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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">USE master <br />
GO <br />
------------------------------- <br />
-- Nicolas Souquet - 05/07/2012 <br />
------------------------------- <br />
CREATE PROCEDURE sp__processes_locks <br />
&nbsp; @_spid int = NULL <br />
AS <br />
BEGIN <br />
&nbsp; SET NOCOUNT ON &nbsp;<br />
&nbsp; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED <br />
&nbsp;<br />
&nbsp; SELECT &nbsp; &nbsp;S.host_name <br />
&nbsp; &nbsp; &nbsp; , S.login_name <br />
&nbsp; &nbsp; &nbsp; , CASE &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN S.program_name LIKE 'Microsoft SQL Server Management Studio%' THEN 'SSMS' <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN S.program_name LIKE 'LiteSpeed for SQL Server%' THEN 'LiteSpeed' <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN S.program_name = 'Microsoft SQL Server Analysis Services' THEN 'SSAS' <br />
&nbsp; &nbsp; &nbsp; &nbsp; ELSE S.program_name <br />
&nbsp; &nbsp; &nbsp; END AS program <br />
&nbsp; &nbsp; &nbsp; , D.name AS database_name <br />
&nbsp; &nbsp; &nbsp; , SQLT.objectid <br />
&nbsp; &nbsp; &nbsp; , TL.request_session_id <br />
&nbsp; &nbsp; &nbsp; , TL.resource_type <br />
&nbsp; &nbsp; &nbsp; , TL.resource_subtype <br />
&nbsp; &nbsp; &nbsp; , TL.request_mode <br />
&nbsp; &nbsp; &nbsp; , TL.request_type <br />
&nbsp; &nbsp; &nbsp; , TL.request_status <br />
&nbsp; &nbsp; &nbsp; , COUNT(*) AS lock_count <br />
&nbsp; &nbsp; &nbsp; , CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN TL.resource_type = 'OBJECT' THEN OBJECT_NAME(TL.resource_associated_entity_id) <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN TL.resource_type IN ('KEY', 'PAGE', 'RID') <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; THEN <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;OBJECT_NAME(object_id) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp;sys.partitions AS P <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;P.hobt_id = TL.resource_associated_entity_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) <br />
&nbsp; &nbsp; &nbsp; &nbsp; ELSE TL.resource_type &nbsp;<br />
&nbsp; &nbsp; &nbsp; END AS requested_object_name <br />
&nbsp; &nbsp; &nbsp; , R.wait_type <br />
&nbsp; &nbsp; &nbsp; , R.wait_time <br />
&nbsp; &nbsp; &nbsp; , R.last_wait_type <br />
&nbsp; &nbsp; &nbsp; , R.plan_handle <br />
&nbsp; &nbsp; &nbsp; , R.cpu_time / 1000 AS CPU <br />
&nbsp; &nbsp; &nbsp; , R.reads AS reads <br />
&nbsp; &nbsp; &nbsp; , R.writes AS writes <br />
&nbsp; &nbsp; &nbsp; , R.open_transaction_count AS nbtran <br />
&nbsp; FROM &nbsp; &nbsp;sys.dm_tran_locks AS TL <br />
&nbsp; INNER JOIN &nbsp;sys.databases AS D <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON TL.resource_database_id = D.database_id <br />
&nbsp; LEFT JOIN &nbsp;sys.dm_exec_requests AS R <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON TL.request_session_id = R.session_id <br />
&nbsp; INNER JOIN &nbsp;sys.dm_exec_sessions AS S <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON R.session_id = S.session_id <br />
&nbsp; CROSS APPLY &nbsp;sys.dm_exec_sql_text(R.sql_handle) SQLT <br />
&nbsp; WHERE &nbsp; &nbsp;TL.request_session_id &gt;= 50 <br />
&nbsp; AND &nbsp; &nbsp;TL.request_session_id &lt;&gt; @@SPID <br />
&nbsp; AND &nbsp; &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; @_spid IS NULL <br />
&nbsp; &nbsp; &nbsp; &nbsp; OR TL.request_session_id = @_spid <br />
&nbsp; &nbsp; &nbsp; ) <br />
&nbsp; GROUP BY &nbsp;S.host_name <br />
&nbsp; &nbsp; &nbsp; , S.login_name <br />
&nbsp; &nbsp; &nbsp; , S.program_name <br />
&nbsp; &nbsp; &nbsp; , D.name <br />
&nbsp; &nbsp; &nbsp; , TL.request_session_id <br />
&nbsp; &nbsp; &nbsp; , TL.resource_type <br />
&nbsp; &nbsp; &nbsp; , TL.resource_subtype <br />
&nbsp; &nbsp; &nbsp; , TL.request_mode <br />
&nbsp; &nbsp; &nbsp; , TL.request_type <br />
&nbsp; &nbsp; &nbsp; , TL.request_status <br />
&nbsp; &nbsp; &nbsp; , TL.resource_type <br />
&nbsp; &nbsp; &nbsp; , SQLT.objectid <br />
&nbsp; &nbsp; &nbsp; , TL.resource_associated_entity_id <br />
&nbsp; &nbsp; &nbsp; , R.wait_type <br />
&nbsp; &nbsp; &nbsp; , R.wait_time <br />
&nbsp; &nbsp; &nbsp; , R.last_wait_type <br />
&nbsp; &nbsp; &nbsp; , R.plan_handle <br />
&nbsp; &nbsp; &nbsp; , R.cpu_time <br />
&nbsp; &nbsp; &nbsp; , R.reads <br />
&nbsp; &nbsp; &nbsp; , R.writes <br />
&nbsp; &nbsp; &nbsp; , R.open_transaction_count <br />
&nbsp; ORDER BY &nbsp;TL.request_session_id <br />
END <br />
GO <br />
&nbsp;<br />
EXEC sp_ms_marksystemobject 'sp__processes_locks'</div></td></tr></tbody></table></div>
<p>Il suffit ensuite d&rsquo;exécuter <code class="codecolorer text default"><span class="text">EXEC sp__processes_locks</span></code> dans n&rsquo;importe quel contexte de base de données, 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>Bon monitoring !</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>Les Événements Étendus avec SQL Server 2008</title>
		<link>https://blog.developpez.com/elsuket/p11065/moteur-de-base-de-donnees-sql-server/evenements_etendus_sql_server_2008</link>
		<comments>https://blog.developpez.com/elsuket/p11065/moteur-de-base-de-donnees-sql-server/evenements_etendus_sql_server_2008#comments</comments>
		<pubDate>Sun, 03 Jun 2012 09:13:20 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Annonces]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Je viens de publier un article sur les Événements Étendus avec SQL Server 2008. Je tiens à remercier Mikedavem pour ses encouragements, la relecture et l&#8217;aide à la publication. Je remercie également toute l&#8217;équipe de Développez.com pour la mise à &#8230; <a href="https://blog.developpez.com/elsuket/p11065/moteur-de-base-de-donnees-sql-server/evenements_etendus_sql_server_2008">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Je viens de publier un article sur les <a href="http://elsuket.developpez.com/tutoriels/sqlserveur/EvenementsEtendusSQLServer2008/">Événements Étendus avec SQL Server 2008</a>.</p>
<p>Je tiens à remercier <a href="http://blog.developpez.com/mikedavem/">Mikedavem</a> pour ses encouragements, la relecture et l&rsquo;aide à la publication.</p>
<p>Je remercie également toute l&rsquo;équipe de Développez.com pour la mise à disposition de la plateforme de publication.</p>
<p>Voici le menu :</p>
<p><strong>I. Architecture logique des XE</strong>, où sont décrits ce que sont les packages, les événements, les cibles, les actions, les prédicats, les « maps », et enfin les types</p>
<p><strong>II. Gestion des sessions d&rsquo;XE avec les vues et fonctions de gestion dynamique</strong>, qui donne le détail et les requêtes pour gérer les sessions XE</p>
<p><strong>III. Quelques exemples guidés</strong> (3 au total)</p>
<p><strong>IV. Le futur avec SQL Server 2012</strong> : une brève section sur les améliorations apportées par SQL Server 2012 concernant les XE</p>
<p><strong>V. Avantages et inconvénients de l&rsquo;utilisation des XE</strong> : une liste de ce qu&rsquo;apportent les XE, et de leurs (rares à mon avis) freins à leur adoption</p>
<p>Bonne Lecture à tous et merci de vos commentaires <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>Lister toutes les instances de SQL Server installées sur un serveur (ou une machine virtuelle)</title>
		<link>https://blog.developpez.com/elsuket/p11114/moteur-de-base-de-donnees-sql-server/lister_instance_sql_server</link>
		<comments>https://blog.developpez.com/elsuket/p11114/moteur-de-base-de-donnees-sql-server/lister_instance_sql_server#comments</comments>
		<pubDate>Sun, 24 Jun 2012 12:35:30 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici un script généreusement publié par Parikshit Savjani, et qui permet d&#8217;obtenir la liste du nom de toutes les instance SQL Server installées sur un serveur. Merci Parikshit, et bon listage à tous]]></description>
				<content:encoded><![CDATA[<p>Voici un <a href="http://blogs.msdn.com/b/sqlserverfaq/archive/2009/03/20/how-to-list-all-the-installed-sql-server-on-the-server-using-tsql.aspx">script</a> généreusement publié par Parikshit Savjani, et qui permet d&rsquo;obtenir la liste du nom de toutes les instance SQL Server installées sur un serveur.</p>
<p>Merci Parikshit, et bon listage à tous <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>3</slash:comments>
		</item>
		<item>
		<title>Comprendre les plans d&#8217;exécution et l&#8217;Optimiseur de requêtes : deux très bons ouvrages</title>
		<link>https://blog.developpez.com/elsuket/p11069/moteur-de-base-de-donnees-sql-server/comprendre_plan_requete_optimiseur</link>
		<comments>https://blog.developpez.com/elsuket/p11069/moteur-de-base-de-donnees-sql-server/comprendre_plan_requete_optimiseur#comments</comments>
		<pubDate>Mon, 04 Jun 2012 08:55:29 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Lecture]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[L&#8217;Optimiseur de Requêtes est l&#8217;organe logiciel au cœur du moteur de base de données de SQL Server. Pour avoir optimisé un grand nombre de requêtes, je dois dire que c&#8217;est une bête incroyable qui continue de m&#8217;étonner : elle continue &#8230; <a href="https://blog.developpez.com/elsuket/p11069/moteur-de-base-de-donnees-sql-server/comprendre_plan_requete_optimiseur">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>L&rsquo;<em>Optimiseur de Requêtes</em> est l&rsquo;organe logiciel au cœur du moteur de base de données de SQL Server.<br />
Pour avoir optimisé un grand nombre de requêtes, je dois dire que c&rsquo;est une bête incroyable qui continue de m&rsquo;étonner : elle continue de faire fonctionner SQL Server avec des performances acceptables alors que le modèle de données laisse souvent à désirer quand ce n&rsquo;est pas pire <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>Voici donc deux ouvrages qui exposent comment lire les plans d&rsquo;exécution graphiques, et comment l&rsquo;Optimiseur de requêtes fonctionne. Le reste, c&rsquo;est l&rsquo;expérience qui le donne !</p>
<p><span id="more-119"></span></p>
<p>=&gt; <a href="http://www.red-gate.com/community/books/assets/sql-server-execution-plans.pdf">Dissecting SQL Server Execution Plans</a>, par Grant Fritchey</p>
<p>=&gt; <a href="http://www.red-gate.com/products/sql-development/sql-prompt/entrypage/sql-query-optimizer-ebook2">Inside the SQL Server Query Optimizer</a>, par Benjamin Nevarez</p>
<p>Un bon outil pour la lecture facilitée des plans de requêtes graphique, qui plus est gratuit, est <a href="http://blog.developpez.com/elsuket/p10724/utilitaires/sql-sentry-plan-explorer/">SQL Sentry Plan Explorer</a></p>
<p>Bonne lecture !</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>1</slash:comments>
		</item>
		<item>
		<title>Une requête pour connaître l&#8217;utilisation des index (et leur définition) : la DMV sys.dm_db_index_usage_stats</title>
		<link>https://blog.developpez.com/elsuket/p11068/moteur-de-base-de-donnees-sql-server/definition_stat_utilisation_index</link>
		<comments>https://blog.developpez.com/elsuket/p11068/moteur-de-base-de-donnees-sql-server/definition_stat_utilisation_index#comments</comments>
		<pubDate>Mon, 04 Jun 2012 08:32:53 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une requête qui retourne l&#8217;utilisation des index avec leur définition, sur un schéma et/ou une table ou vue indexée et/ou une base de données : 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899------------------------------- -- Nicolas Souquet - 04/06/2012 ------------------------------- &#160; SET NOCOUNT ON SET TRANSACTION ISOLATION &#8230; <a href="https://blog.developpez.com/elsuket/p11068/moteur-de-base-de-donnees-sql-server/definition_stat_utilisation_index">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une requête qui retourne l&rsquo;utilisation des index avec leur définition, sur un schéma et/ou une table ou vue indexée et/ou une base de données :</p>
<p><span id="more-118"></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 /></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 - 04/06/2012 <br />
------------------------------- <br />
&nbsp;<br />
SET NOCOUNT ON <br />
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED <br />
GO <br />
&nbsp;<br />
DECLARE &nbsp;@schema_name sysname = 'dbo' <br />
&nbsp; , @table_or_view_name sysname --= 'maTable' -- si NULL, étudie tous les index de toutes les table du schéma <br />
&nbsp; , @index_name sysname = NULL -- si NULL, étudie tous les index de la table <br />
&nbsp; , @separator varchar(2) = ', ' <br />
---------------------------------------------------------------------------------------------------------------------- <br />
SELECT &nbsp; &nbsp;DISTINCT S.name + '.' + O.name AS schema_table_name <br />
&nbsp; &nbsp; , I.name AS index_name <br />
&nbsp; &nbsp; , PS.row_count <br />
&nbsp; &nbsp; , I.type_desc <br />
&nbsp; &nbsp; , LEFT(KC.key_column_list, LEN(KC.key_column_list) - 2) AS key_column_list <br />
&nbsp; &nbsp; , LEFT(KCI.included_key_column_list, LEN(KCI.included_key_column_list) - 1) AS included_key_column_list <br />
&nbsp; &nbsp; , REPLACE(REPLACE(REPLACE(REPLACE(I.filter_definition, '[', ''), ']', ''), '(', ''), ')', '') AS filter_definition <br />
&nbsp; &nbsp; , PS.used_page_count AS pages_count <br />
&nbsp; &nbsp; , STATS_DATE(O.object_id, I.index_id) AS last_stat_update <br />
&nbsp; &nbsp; , IUS.user_seeks <br />
&nbsp; &nbsp; , IUS.user_scans <br />
&nbsp; &nbsp; , IUS.user_lookups <br />
&nbsp; &nbsp; , (IUS.user_seeks + IUS.user_scans + IUS.user_lookups) AS total_user_searches <br />
&nbsp; &nbsp; , IUS.last_user_seek <br />
&nbsp; &nbsp; , IUS.last_user_scan &nbsp;<br />
&nbsp; &nbsp; , IUS.last_user_lookup <br />
&nbsp; &nbsp; , LS.max_last_search_date <br />
&nbsp; &nbsp; , PS.used_page_count / 8 AS index_size_kb <br />
FROM &nbsp; &nbsp;sys.schemas AS S <br />
INNER JOIN &nbsp;sys.objects AS O <br />
&nbsp; &nbsp; &nbsp; ON S.schema_id = O.schema_id <br />
INNER JOIN &nbsp;sys.indexes AS I &nbsp;<br />
&nbsp; &nbsp; &nbsp; ON O.object_id = I.object_id <br />
INNER JOIN &nbsp;sys.index_columns AS IC <br />
&nbsp; &nbsp; &nbsp; ON IC.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; AND IC.index_id = I.index_id <br />
INNER JOIN &nbsp;sys.columns AS C <br />
&nbsp; &nbsp; &nbsp; ON IC.object_id = C.object_id <br />
&nbsp; &nbsp; &nbsp; AND IC.column_id = C.column_id <br />
LEFT JOIN &nbsp;sys.dm_db_index_usage_stats AS IUS <br />
&nbsp; &nbsp; &nbsp; ON IUS.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; AND IUS.index_id = I.index_id <br />
&nbsp; &nbsp; &nbsp; AND IUS.database_id = DB_ID() <br />
INNER JOIN &nbsp;sys.dm_db_partition_stats AS PS <br />
&nbsp; &nbsp; &nbsp; ON PS.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; AND PS.index_id = I.index_id <br />
CROSS APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;CS.name + @separator <br />
&nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns AS CS <br />
&nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS ICS <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON CS.object_id = ICS.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND CS.column_id = ICS.column_id <br />
&nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;IC.object_id = ICS.object_id <br />
&nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;IC.index_id = ICS.index_id <br />
&nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;ICS.is_included_column = 0 <br />
&nbsp; &nbsp; &nbsp; ORDER BY &nbsp;ICS.index_column_id <br />
&nbsp; &nbsp; &nbsp; FOR XML PATH ('') <br />
&nbsp; &nbsp; ) AS KC (key_column_list) <br />
OUTER APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;CSI.name + @separator <br />
&nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns AS CSI <br />
&nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS ICSI <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON CSI.object_id = ICSI.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND CSI.column_id = ICSI.column_id <br />
&nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;IC.object_id = ICSI.object_id <br />
&nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;IC.index_id = ICSI.index_id <br />
&nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;ICSI.is_included_column = 1 <br />
&nbsp; &nbsp; &nbsp; ORDER BY &nbsp;ICSI.index_column_id <br />
&nbsp; &nbsp; &nbsp; FOR XML PATH ('') <br />
&nbsp; &nbsp; ) AS KCI (included_key_column_list) <br />
OUTER APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp;MAX(M.last_search_date) <br />
&nbsp; &nbsp; &nbsp; FROM &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;LU_USK.last_user_seek <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp;sys.dm_db_index_usage_stats AS LU_USK <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;IUS.database_id = LU_USK.database_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.object_id = LU_USK.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.index_id = LU_USK.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UNION ALL <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;LU_USC.last_user_scan <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp;sys.dm_db_index_usage_stats AS LU_USC <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;IUS.database_id = LU_USC.database_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.object_id = LU_USC.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.index_id = LU_USC.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UNION ALL <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;LU_LK.last_user_lookup <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp;sys.dm_db_index_usage_stats AS LU_LK <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;IUS.database_id = LU_LK.database_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.object_id = LU_LK.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.index_id = LU_LK.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS M (last_search_date) <br />
&nbsp; &nbsp; ) AS LS (max_last_search_date) <br />
WHERE &nbsp; &nbsp;(@schema_name IS NULL OR S.name = @schema_name) <br />
AND &nbsp; &nbsp;(@table_or_view_name IS NULL OR O.name = @table_or_view_name) <br />
AND &nbsp; &nbsp;(@index_name IS NULL OR I.name = @index_name) <br />
ORDER BY &nbsp;I.type_desc</div></td></tr></tbody></table></div>
<p>Cette vue accumule les statistiques tant que le service SQL Server est démarré; un redémarrage du service ou du serveur purge les statistiques exposées par cette DMV.<br />
Si elle permet de détecter les index non-utilisés et donc à supprimer, vérifiez depuis combien de temps le service SQL Server est actif <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>Bonne utilisation de vos index !</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>Connaître la taille du cache allouée aux bases de données et à leurs tables avec SQL Server 2005 et suivants</title>
		<link>https://blog.developpez.com/elsuket/p11067/moteur-de-base-de-donnees-sql-server/cache_donnees_alloue_bd_tables</link>
		<comments>https://blog.developpez.com/elsuket/p11067/moteur-de-base-de-donnees-sql-server/cache_donnees_alloue_bd_tables#comments</comments>
		<pubDate>Mon, 04 Jun 2012 07:50:14 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici quelques requêtes qui montrent la taille du cache de données allouée aux tables (et vues indexées) : &#8211; pour toute l&#8217;instance SQL Server, &#8211; par base de données &#8211; par table (ou vue indexée) dans une base de données &#8230; <a href="https://blog.developpez.com/elsuket/p11067/moteur-de-base-de-donnees-sql-server/cache_donnees_alloue_bd_tables">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici quelques requêtes qui montrent la taille du cache de données allouée aux tables (et vues indexées) :</p>
<p>&#8211; pour toute l&rsquo;instance SQL Server,<br />
&#8211; par base de données<br />
&#8211; par table (ou vue indexée) dans une base de données en particulier</p>
<p><span id="more-117"></span></p>
<p>=&gt; <strong>Au niveau de l&rsquo;instance SQL Server</strong></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 /></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 - 04/06/2012 <br />
------------------------------- <br />
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED <br />
GO <br />
&nbsp;<br />
;WITH <br />
&nbsp; CTE AS &nbsp;<br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp;COUNT(*) / 128 AS used_MB <br />
&nbsp; &nbsp; &nbsp; , SUM (CAST (free_space_in_bytes AS float)) / (1024 * 1024) AS empty_MB <br />
&nbsp; &nbsp; FROM &nbsp;sys.dm_os_buffer_descriptors <br />
&nbsp; ) <br />
SELECT &nbsp;used_MB <br />
&nbsp; , CAST(empty_MB AS bigint) AS empty_MB <br />
&nbsp; , CAST((empty_MB / used_MB) * 100 AS decimal(5,2)) AS ratio <br />
FROM &nbsp;CTE <br />
GO</div></td></tr></tbody></table></div>
<p>Cette requête donne l&rsquo;espace alloué au cache de données pour toutes les bases de données d&rsquo;une instance SQL Server.<br />
Elle montre également l&rsquo;espace vide dans les pages, qui quand elle est élevée, est due soit à une fragmentation des index élevée, soit à un modèle de données incorrect qui conduit à ne pouvoir stocker que peu de lignes par page de données.<br />
En effet le taille d&rsquo;une page de données est de 8192 octets, desquels 8060 octets sont dédiés aux données utilisateur.<br />
Si donc la taille d&rsquo;une ligne est de 4031 octets (cas extrême) ou plus, on ne peut stocker qu&rsquo;une seule ligne de données par page, et on gaspille 4029 octets.</p>
<p>=&gt; <strong>Décomposition par base de données</strong></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 - 04/06/2012 <br />
------------------------------- <br />
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED <br />
GO <br />
&nbsp;<br />
;WITH <br />
&nbsp; CTE AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp;CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN database_id = 32767 THEN 'RESOURCE DATABASE' <br />
&nbsp; &nbsp; &nbsp; &nbsp; ELSE DB_NAME(database_id) &nbsp;<br />
&nbsp; &nbsp; &nbsp; END AS database_name <br />
&nbsp; &nbsp; &nbsp; , COUNT (*) * 8 / 1024 AS reserved_MB <br />
&nbsp; &nbsp; &nbsp; , SUM(CAST(free_space_in_bytes AS bigint)) / (1024 * 1024) AS empty_MB <br />
&nbsp; &nbsp; FROM &nbsp;sys.dm_os_buffer_descriptors <br />
&nbsp; &nbsp; GROUP &nbsp;BY database_id <br />
&nbsp; ) <br />
SELECT &nbsp;database_name <br />
&nbsp; , reserved_MB <br />
&nbsp; , empty_MB <br />
&nbsp; , CAST(100.0 * empty_MB / CASE reserved_MB WHEN 0 THEN 1 ELSE reserved_MB END AS decimal(5,2))[empty_%] <br />
FROM &nbsp;CTE <br />
--WHERE &nbsp;database_name = 'maBD' <br />
ORDER &nbsp;BY empty_MB DESC</div></td></tr></tbody></table></div>
<p>Même chose ici, mais pour chaque objet de base de données.</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 - 04/06/2012 <br />
------------------------------- <br />
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED <br />
GO <br />
&nbsp;<br />
;WITH <br />
&nbsp; CTE AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;BD.allocation_unit_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , AU.type_desc AS allocation_type <br />
&nbsp; &nbsp; &nbsp; &nbsp; , P.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , P.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , COUNT_BIG(*) AS page_count <br />
&nbsp; &nbsp; &nbsp; &nbsp; , COUNT_BIG(*) * 8192 AS allocated_space_in_bytes <br />
&nbsp; &nbsp; &nbsp; &nbsp; , SUM(CAST(BD.free_space_in_bytes AS bigint)) AS free_space_in_bytes <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;sys.dm_os_buffer_descriptors AS BD <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.allocation_units AS AU <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON AU.allocation_unit_id = BD.allocation_unit_id <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.partitions AS P <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON AU.container_id = P.partition_id <br />
&nbsp; &nbsp; WHERE &nbsp; &nbsp;BD.database_id = DB_ID() <br />
&nbsp; &nbsp; GROUP BY &nbsp;BD.allocation_unit_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , AU.type_desc <br />
&nbsp; &nbsp; &nbsp; &nbsp; , P.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , P.index_id <br />
&nbsp; &nbsp; HAVING &nbsp; &nbsp;COUNT_BIG(*) &amp;gt; 8 <br />
&nbsp; ) <br />
SELECT &nbsp; &nbsp;S.name + '.' + O.name AS table_or_indexed_view_name <br />
&nbsp; &nbsp; , I.name AS index_name <br />
&nbsp; &nbsp; , C.allocation_type <br />
&nbsp; &nbsp; , C.page_count <br />
&nbsp; &nbsp; , C.allocated_space_in_bytes <br />
&nbsp; &nbsp; , C.allocated_space_in_bytes - C.free_space_in_bytes AS used_space_in_bytes <br />
&nbsp; &nbsp; , C.free_space_in_bytes <br />
&nbsp; &nbsp; , CAST((CAST(C.free_space_in_bytes AS decimal(20,2)) / C.allocated_space_in_bytes) * 100 AS decimal(5,2)) AS [free_space_in_%] <br />
FROM &nbsp; &nbsp;CTE AS C <br />
INNER JOIN &nbsp;sys.indexes AS I <br />
&nbsp; &nbsp; &nbsp; ON I.index_id = C.index_id <br />
&nbsp; &nbsp; &nbsp; AND I.object_id = C.object_id <br />
INNER JOIN &nbsp;sys.objects AS O <br />
&nbsp; &nbsp; &nbsp; ON C.object_id = O.object_id <br />
INNER JOIN &nbsp;sys.schemas AS S <br />
&nbsp; &nbsp; &nbsp; ON S.schema_id = O.schema_id <br />
INNER JOIN &nbsp;sys.database_principals AS DP <br />
&nbsp; &nbsp; &nbsp; ON S.principal_id = DP.principal_id <br />
WHERE &nbsp; &nbsp;DP.type = 'S' -- schema <br />
AND &nbsp; &nbsp;DP.default_schema_name IS NOT NULL <br />
ORDER BY &nbsp;C.page_count DESC</div></td></tr></tbody></table></div>
<p>Cette requête nécessite de changer le contexte de base de données à la base de données que l&rsquo;on souhaite étudier.<br />
En effet, elle retourne la liste des tables (et vues indexées) qui sont présentes dans le cache de données, ainsi que la taille qu&rsquo;elles y occupent, avec les index.</p>
<p>En exécutant cette dernière requête à intervalles de temps réguliers à l&rsquo;aide d&rsquo;un job de l&rsquo;Agent SQL Server, et en enregistrant le résultat dans une table, on peut étudier la taille du cache allouée aux objets, de façon à faire une projection sur la quantité de RAM nécessaire au bon fonctionnement de la base de données.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Etude de table : retourner les caractéristiques des statistiques et index d&#8217;une table (ou vue indexée)</title>
		<link>https://blog.developpez.com/elsuket/p11051/moteur-de-base-de-donnees-sql-server/indexation/etude_index_stat_table</link>
		<comments>https://blog.developpez.com/elsuket/p11051/moteur-de-base-de-donnees-sql-server/indexation/etude_index_stat_table#comments</comments>
		<pubDate>Mon, 28 May 2012 14:15:24 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici un script qui retourne : &#8211; l&#8217;en-tête des statistiques d&#8217;une table &#8211; la liste des colonnes qui participent à la statistique, ou des colonnes clé de l&#8217;index (incluses et filtrées) &#8211; le vecteur de la statistique, qui permet de &#8230; <a href="https://blog.developpez.com/elsuket/p11051/moteur-de-base-de-donnees-sql-server/indexation/etude_index_stat_table">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici un script qui retourne :</p>
<p>&#8211; l&rsquo;en-tête des statistiques d&rsquo;une table<br />
&#8211; la liste des colonnes qui participent à la statistique, ou des colonnes clé de l&rsquo;index (incluses et filtrées)<br />
&#8211; le vecteur de la statistique, qui permet de connaître sa sélectivité<br />
&#8211; optionnellement, le niveau de fragmentation des index<br />
&#8211; le nombre d&rsquo;utilisation des index<br />
&#8211; la date de dernière mise à jour de chaque statistique scrutée par le script</p>
<p><span id="more-115"></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 />170<br />171<br />172<br />173<br />174<br />175<br />176<br />177<br />178<br />179<br />180<br />181<br />182<br />183<br />184<br />185<br />186<br />187<br />188<br />189<br />190<br />191<br />192<br />193<br />194<br />195<br />196<br />197<br />198<br />199<br />200<br />201<br />202<br />203<br />204<br />205<br />206<br />207<br />208<br />209<br />210<br />211<br />212<br />213<br />214<br />215<br />216<br />217<br />218<br />219<br />220<br />221<br />222<br />223<br />224<br />225<br />226<br />227<br />228<br />229<br />230<br />231<br />232<br />233<br />234<br />235<br />236<br />237<br />238<br />239<br />240<br />241<br />242<br />243<br />244<br />245<br />246<br />247<br />248<br />249<br />250<br />251<br />252<br />253<br />254<br />255<br />256<br />257<br />258<br />259<br />260<br />261<br />262<br />263<br />264<br />265<br />266<br />267<br />268<br />269<br />270<br />271<br />272<br />273<br />274<br />275<br />276<br />277<br />278<br />279<br />280<br />281<br />282<br />283<br />284<br />285<br />286<br />287<br />288<br />289<br />290<br />291<br />292<br />293<br />294<br />295<br />296<br />297<br />298<br />299<br />300<br />301<br />302<br />303<br />304<br />305<br />306<br />307<br />308<br />309<br />310<br />311<br />312<br />313<br />314<br />315<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">----------------------------------------- <br />
-- 28/05/2012 - Copyright Nicolas Souquet <br />
----------------------------------------- <br />
&nbsp;<br />
SET NOCOUNT ON <br />
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED <br />
GO <br />
&nbsp;<br />
------------------------------------------------------------------------------------------------------------------------------ <br />
DECLARE &nbsp;@schema_name sysname = 'dbo' <br />
&nbsp; , @table_or_indexed_view_name sysname = 'maTable' <br />
&nbsp; , @statistic_name sysname = NULL -- NULL effectue l'étude pour toutes les statistiques ou index de la table <br />
&nbsp; --- <br />
&nbsp; , @index_study bit = 1 -- mettre à 1 pour indiquer si l'on souhaite regarder la fragmentation des index, 0 sinon <br />
&nbsp; , @index_scan_level_mode varchar(8) = 'LIMITED' -- scan level mode (DETAILED, SAMPLED, LIMITED) &nbsp;<br />
&nbsp; --- <br />
&nbsp; , @separator varchar(2) = ', ' <br />
------------------------------------------------------------------------------------------------------------------------------ <br />
-- NE RIEN CHANGER APRÈS CETTE LIGNE <br />
------------------------------------------------------------------------------------------------------------------------------ <br />
IF (SELECT OBJECT_ID('TEMPDB.dbo.#STUDY')) IS NOT NULL <br />
BEGIN <br />
&nbsp; DROP TABLE #STUDY <br />
END <br />
&nbsp;<br />
------------------------------------------------------------------------------ <br />
-- Vérifie que la table ou vue indexée existe dans la base de données en cours <br />
------------------------------------------------------------------------------ <br />
DECLARE @object_type char(1) <br />
&nbsp;<br />
SELECT &nbsp; &nbsp;@object_type = O.type <br />
FROM &nbsp; &nbsp;sys.schemas AS S <br />
INNER JOIN &nbsp;sys.objects AS O ON S.schema_id = O.schema_id <br />
WHERE &nbsp; &nbsp;S.name = @schema_name <br />
AND &nbsp; &nbsp;O.name = @table_or_indexed_view_name <br />
AND &nbsp; &nbsp;O.type IN ('U', 'V') -- table ou vue (indexée) <br />
&nbsp;<br />
IF @object_type IS NULL <br />
BEGIN <br />
&nbsp; RAISERROR('La table ou vue indexée ''%s.%s'' n''existe pas !', 16, 1, @schema_name, @table_or_indexed_view_name) <br />
&nbsp; RETURN <br />
END <br />
&nbsp;<br />
-- Seules les vues indexées on des statistiques <br />
IF @object_type = 'V' <br />
AND NOT EXISTS <br />
( <br />
&nbsp; SELECT &nbsp; &nbsp;* <br />
&nbsp; FROM &nbsp; &nbsp;sys.schemas AS S <br />
&nbsp; INNER JOIN &nbsp;sys.views AS V ON S.schema_id = V.schema_id <br />
&nbsp; INNER JOIN &nbsp;sys.indexes AS I ON V.object_id = I.object_id <br />
&nbsp; WHERE &nbsp; &nbsp;S.name = @schema_name <br />
&nbsp; AND &nbsp; &nbsp;V.name = @table_or_indexed_view_name <br />
) <br />
BEGIN <br />
&nbsp; RAISERROR('The %s.%s view is not indexed !', 16, 1, @schema_name, @table_or_indexed_view_name) <br />
&nbsp; RETURN <br />
END <br />
&nbsp;<br />
DECLARE @qualified_table_or_indexed_view_name nvarchar(256) = @schema_name + '.' + @table_or_indexed_view_name <br />
&nbsp;<br />
-------------------------------------------------- <br />
-- Collecte des statistiques de colonne et d'index <br />
-------------------------------------------------- <br />
DECLARE &nbsp;@stat_header TABLE <br />
( <br />
&nbsp; stat_name varchar(256) <br />
&nbsp; , updated varchar(32) <br />
&nbsp; , row_count bigint <br />
&nbsp; , rows_sampled bigint <br />
&nbsp; , steps int <br />
&nbsp; , density float <br />
&nbsp; , avg_key_length float <br />
&nbsp; , string_index char(3) <br />
&nbsp; , filter_expression varchar(1024) &nbsp;<br />
&nbsp; , unfiltered_rows bigint <br />
) <br />
&nbsp;<br />
DECLARE @density_vector TABLE <br />
( <br />
&nbsp; all_density float <br />
&nbsp; , average_length float <br />
&nbsp; , column_list varchar(1024) <br />
) <br />
&nbsp;<br />
DECLARE @stat_name_density_vector TABLE <br />
( <br />
&nbsp; stat_name varchar(256) <br />
&nbsp; , all_density float <br />
) <br />
&nbsp;<br />
DECLARE @stat_name varchar(256) = ' ' <br />
&nbsp; , @object_id int <br />
&nbsp; , @sql_stat_header nvarchar(256) = 'DBCC SHOW_STATISTICS(@TABLE@, @STATS@) WITH STAT_HEADER, NO_INFOMSGS' <br />
&nbsp; , @sql_density_vector nvarchar(256) = 'DBCC SHOW_STATISTICS(@TABLE@, @STATS@) WITH DENSITY_VECTOR, NO_INFOMSGS' <br />
&nbsp; , @exec_string nvarchar(512) <br />
&nbsp;<br />
WHILE DATALENGTH(@stat_name) &gt; 0 <br />
BEGIN <br />
&nbsp; SET @stat_name = NULL <br />
&nbsp;<br />
&nbsp; SELECT &nbsp; &nbsp;TOP(1) @stat_name = QUOTENAME(D.name) <br />
&nbsp; FROM &nbsp; &nbsp;sys.stats AS D <br />
&nbsp; INNER JOIN &nbsp;sys.objects AS O ON D.object_id = O.object_id <br />
&nbsp; INNER JOIN &nbsp;sys.schemas AS S ON O.schema_id = S.schema_id <br />
&nbsp; LEFT JOIN &nbsp;@stat_header AS SH ON D.name = SH.stat_name <br />
&nbsp; WHERE &nbsp; &nbsp;S.name = @schema_name <br />
&nbsp; AND &nbsp; &nbsp;O.name = @table_or_indexed_view_name <br />
&nbsp; AND &nbsp; &nbsp;SH.stat_name IS NULL <br />
&nbsp; AND &nbsp; &nbsp;(@statistic_name IS NULL OR D.name = @statistic_name) <br />
&nbsp; <br />
&nbsp; -- Statistics header <br />
&nbsp; SELECT @exec_string = REPLACE(REPLACE(@sql_stat_header, '@STATS@', @stat_name), '@TABLE@', '''' + @schema_name + '.' + @table_or_indexed_view_name &nbsp;+ '''') <br />
&nbsp;<br />
&nbsp; INSERT &nbsp;@stat_header <br />
&nbsp; EXEC &nbsp;(@exec_string) <br />
&nbsp; <br />
&nbsp; -- Density vector <br />
&nbsp; SELECT @exec_string = REPLACE(REPLACE(@sql_density_vector, '@STATS@', @stat_name), '@TABLE@', '''' + @schema_name + '.' + @table_or_indexed_view_name &nbsp;+ '''') <br />
&nbsp; <br />
&nbsp; INSERT &nbsp;@density_vector (all_density, average_length, column_list) <br />
&nbsp; EXEC &nbsp;(@exec_string) <br />
&nbsp; <br />
&nbsp; INSERT &nbsp;INTO @stat_name_density_vector <br />
&nbsp; SELECT &nbsp;TOP 1 @stat_name <br />
&nbsp; &nbsp; , all_density <br />
&nbsp; FROM &nbsp;@density_vector <br />
&nbsp; ORDER &nbsp;BY average_length <br />
&nbsp; <br />
&nbsp; DELETE &nbsp;FROM @density_vector <br />
END <br />
----------------------------------------------------------------------------------------------------------------------- <br />
;WITH <br />
&nbsp; INDEX_CTE AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;DISTINCT I.name AS index_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , I.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , PS.partition_number <br />
&nbsp; &nbsp; &nbsp; &nbsp; , PS.row_count <br />
&nbsp; &nbsp; &nbsp; &nbsp; , I.type_desc <br />
&nbsp; &nbsp; &nbsp; &nbsp; , I.is_unique <br />
&nbsp; &nbsp; &nbsp; &nbsp; , I.is_unique_constraint <br />
&nbsp; &nbsp; &nbsp; &nbsp; , I.is_primary_key <br />
&nbsp; &nbsp; &nbsp; &nbsp; , LEFT(KC.key_column_list, LEN(KC.key_column_list) - LEN(@separator)) AS key_column_list <br />
&nbsp; &nbsp; &nbsp; &nbsp; , LEFT(KCI.included_column_list, LEN(KCI.included_column_list) - 1) AS included_column_list <br />
&nbsp; &nbsp; &nbsp; &nbsp; , REPLACE(REPLACE(REPLACE(REPLACE(I.filter_definition, '[', ''), ']', ''), '(', ''), ')', '') AS filter_definition <br />
&nbsp; &nbsp; &nbsp; &nbsp; , STATS_DATE(O.object_id, I.index_id) AS last_stat_update <br />
&nbsp; &nbsp; &nbsp; &nbsp; , IUS.user_seeks <br />
&nbsp; &nbsp; &nbsp; &nbsp; , IUS.user_scans <br />
&nbsp; &nbsp; &nbsp; &nbsp; , IUS.user_lookups <br />
&nbsp; &nbsp; &nbsp; &nbsp; , (IUS.user_seeks + IUS.user_scans + IUS.user_lookups) AS total_user_searches <br />
&nbsp; &nbsp; &nbsp; &nbsp; , IUS.user_updates <br />
&nbsp; &nbsp; &nbsp; &nbsp; , LS.max_last_search_date <br />
&nbsp; &nbsp; &nbsp; &nbsp; , I.is_disabled &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; , (PS.reserved_page_count * 8192) / 1024 AS index_size_kb <br />
&nbsp; &nbsp; &nbsp; &nbsp; , IPS.index_level <br />
&nbsp; &nbsp; &nbsp; &nbsp; , IPS.index_depth <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CAST(IPS.avg_fragmentation_in_percent AS decimal(5, 2)) AS avg_frag_pct <br />
&nbsp; &nbsp; &nbsp; &nbsp; , I.fill_factor <br />
&nbsp; &nbsp; &nbsp; &nbsp; , IPS.forwarded_record_count <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;sys.schemas AS S <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.objects AS O <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON S.schema_id = O.schema_id <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.indexes AS I &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON O.object_id = I.object_id <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS IC <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON IC.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND IC.index_id = I.index_id <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.columns AS C <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON IC.object_id = C.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND IC.column_id = C.column_id <br />
&nbsp; &nbsp; LEFT JOIN &nbsp;sys.dm_db_index_usage_stats AS IUS <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON IUS.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND IUS.index_id = I.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND IUS.database_id = DB_ID() <br />
&nbsp; &nbsp; LEFT JOIN &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , database_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , index_level <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , index_depth <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , avg_fragmentation_in_percent <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , forwarded_record_count <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp;sys.dm_db_index_physical_stats <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DB_ID() -- database <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , OBJECT_ID(@table_or_indexed_view_name) -- all tables <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , NULL -- all indexes <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , NULL -- all partitions <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , @index_scan_level_mode -- scan level mode (DETAILED, SAMPLED, LIMITED) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;@index_study = 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS IPS <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON IPS.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; AND IPS.index_id = I.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; AND IPS.database_id = DB_ID() <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.dm_db_partition_stats AS PS <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON PS.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND PS.index_id = I.index_id <br />
&nbsp; &nbsp; CROSS APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;CS.name + CASE ICS.is_descending_key WHEN 1 THEN ' DESC' ELSE '' END + @separator <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns AS CS <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS ICS <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON CS.object_id = ICS.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND CS.column_id = ICS.column_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;IC.object_id = ICS.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;IC.index_id = ICS.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;ICS.is_included_column = 0 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ORDER BY &nbsp;ICS.index_column_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FOR XML PATH ('') <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS KC (key_column_list) <br />
&nbsp; &nbsp; OUTER APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;CSI.name + @separator <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns AS CSI <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS ICSI <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON CSI.object_id = ICSI.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND CSI.column_id = ICSI.column_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;IC.object_id = ICSI.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;IC.index_id = ICSI.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;ICSI.is_included_column = 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ORDER BY &nbsp;ICSI.index_column_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FOR XML PATH ('') <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS KCI (included_column_list) <br />
&nbsp; &nbsp; OUTER APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;MAX(M.last_search_date) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;LU_USK.last_user_seek <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp;sys.dm_db_index_usage_stats AS LU_USK <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;IUS.database_id = LU_USK.database_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.object_id = LU_USK.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.index_id = LU_USK.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UNION ALL <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;LU_USC.last_user_scan <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp;sys.dm_db_index_usage_stats AS LU_USC <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;IUS.database_id = LU_USC.database_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.object_id = LU_USC.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.index_id = LU_USC.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UNION ALL <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;LU_LK.last_user_lookup <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp;sys.dm_db_index_usage_stats AS LU_LK <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;IUS.database_id = LU_LK.database_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.object_id = LU_LK.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp;IUS.index_id = LU_LK.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) AS M (last_search_date) <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS LS (max_last_search_date) <br />
&nbsp; &nbsp; WHERE &nbsp; &nbsp;(@schema_name IS NULL OR S.name = @schema_name) <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;(@table_or_indexed_view_name IS NULL OR O.name = @table_or_indexed_view_name) <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;(@stat_name IS NULL OR I.name = @stat_name) <br />
&nbsp; ) <br />
SELECT &nbsp; &nbsp;COALESCE(C.type_desc, 'STAT') AS type_desc <br />
&nbsp; &nbsp; , CAST(SH.density AS decimal(7,6)) AS header <br />
&nbsp; &nbsp; , SNDV.all_density AS vector <br />
&nbsp; &nbsp; , C.row_count <br />
&nbsp; &nbsp; , SH.stat_name <br />
&nbsp; &nbsp; , COALESCE(C.key_column_list, LEFT(SC.stat_column_list, LEN(SC.stat_column_list) - 1)) AS stat_column_list <br />
&nbsp; &nbsp; , C.included_column_list <br />
&nbsp; &nbsp; , C.index_id <br />
&nbsp; &nbsp; , C.partition_number <br />
&nbsp; &nbsp; , C.is_disabled <br />
&nbsp; &nbsp; , C.is_unique AS is_uq <br />
&nbsp; &nbsp; , C.is_unique_constraint AS is_uqc <br />
&nbsp; &nbsp; , C.is_primary_key AS is_PK <br />
&nbsp; &nbsp; , REPLACE(REPLACE(REPLACE(REPLACE(SH.filter_expression, '[', ''), ']', ''), '(', ''), ')', '') AS filter_definition <br />
&nbsp; &nbsp; , SH.row_count AS stat_row_count <br />
&nbsp; &nbsp; , COALESCE(C.row_count, SH.row_count) AS real_row_count <br />
&nbsp; &nbsp; , SI.rowmodctr <br />
&nbsp; &nbsp; , SH.rows_sampled <br />
&nbsp; &nbsp; , C.index_size_kb <br />
&nbsp; &nbsp; , STATS_DATE(D.object_id, D.stats_id) AS last_stat_update <br />
&nbsp; &nbsp; , C.user_seeks <br />
&nbsp; &nbsp; , C.user_scans <br />
&nbsp; &nbsp; , C.user_lookups &nbsp; &nbsp;<br />
&nbsp; &nbsp; , C.total_user_searches <br />
&nbsp; &nbsp; , C.user_updates <br />
&nbsp; &nbsp; , C.max_last_search_date <br />
&nbsp; &nbsp; , C.index_depth <br />
&nbsp; &nbsp; , C.avg_frag_pct <br />
&nbsp; &nbsp; , C.index_level <br />
&nbsp; &nbsp; , CASE <br />
&nbsp; &nbsp; &nbsp; WHEN COALESCE(C.type_desc, 'STAT') = 'STAT' THEN NULL <br />
&nbsp; &nbsp; &nbsp; WHEN C.index_level = 0 THEN 'LEAF' <br />
&nbsp; &nbsp; &nbsp; WHEN C.index_depth - C.index_level &gt; 1 THEN 'INTERMEDIATE' <br />
&nbsp; &nbsp; &nbsp; ELSE 'ROOT' <br />
&nbsp; &nbsp; END AS index_level_type <br />
&nbsp; &nbsp; , C.forwarded_record_count <br />
INTO &nbsp; &nbsp;#STUDY <br />
FROM &nbsp; &nbsp;@stat_header AS SH <br />
INNER JOIN &nbsp;@stat_name_density_vector AS SNDV <br />
&nbsp; &nbsp; &nbsp; ON QUOTENAME(SH.stat_name) = SNDV.stat_name <br />
LEFT JOIN &nbsp;INDEX_CTE AS C <br />
&nbsp; &nbsp; &nbsp; ON SH.stat_name = C.index_name <br />
INNER JOIN &nbsp;sys.stats AS D <br />
&nbsp; &nbsp; &nbsp; ON D.object_id = OBJECT_ID(@schema_name + '.' + @table_or_indexed_view_name) <br />
&nbsp; &nbsp; &nbsp; AND D.name = SH.stat_name <br />
INNER JOIN &nbsp;sys.sysindexes AS SI <br />
&nbsp; &nbsp; &nbsp; ON SI.id = D.object_id <br />
&nbsp; &nbsp; &nbsp; AND SI.indid = D.stats_id <br />
CROSS APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;C.name + ',' <br />
&nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.stats AS S <br />
&nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.stats_columns AS SC <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON S.object_id = SC.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND S.stats_id = SC.stats_id <br />
&nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.columns AS C <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON C.object_id = SC.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND C.column_id = SC.column_id <br />
&nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;SH.stat_name = S.name <br />
&nbsp; &nbsp; &nbsp; ORDER BY &nbsp;SC.stats_column_id <br />
&nbsp; &nbsp; &nbsp; FOR XML PATH ('') <br />
&nbsp; &nbsp; ) AS SC (stat_column_list) <br />
ORDER BY &nbsp;stat_name <br />
&nbsp;<br />
SELECT &nbsp;* <br />
FROM &nbsp;#STUDY <br />
ORDER &nbsp;BY type_desc</div></td></tr></tbody></table></div>
<p>Bonne étude de table !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Différence entre ALTER INDEX &#8230; REBUILD et ALTER INDEX &#8230; REORGANIZE</title>
		<link>https://blog.developpez.com/elsuket/p10897/moteur-de-base-de-donnees-sql-server/indexation/difference_alter_index_rebuild_reorganiz</link>
		<comments>https://blog.developpez.com/elsuket/p10897/moteur-de-base-de-donnees-sql-server/indexation/difference_alter_index_rebuild_reorganiz#comments</comments>
		<pubDate>Sat, 31 Mar 2012 11:02:52 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Après avoir vu ce que sont la fragmentation interne et externe d&#8217;un index, voyons les différences entre les options REBUILD et REORGANIZE de l&#8217;instruction ALTER INDEX (ou respectivement DBCC DBREINDEX ou DBCC INDEXDEFRAG sous SQL Server 2000) => REBUILD est &#8230; <a href="https://blog.developpez.com/elsuket/p10897/moteur-de-base-de-donnees-sql-server/indexation/difference_alter_index_rebuild_reorganiz">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Après avoir vu ce que sont la <a href="http://blog.developpez.com/elsuket/p7894/indexation/difference-entre-fragmentation-interne-e/">fragmentation interne et externe d&rsquo;un index</a>, voyons les différences entre les options REBUILD et REORGANIZE de l&rsquo;instruction ALTER INDEX (ou respectivement DBCC DBREINDEX ou DBCC INDEXDEFRAG sous SQL Server 2000)<br />
<span id="more-30"></span><br />
=> REBUILD est une opération atomique, alors que REORGANIZE ne l&rsquo;est pas.<br />
Cela signifie que si l&rsquo;on arrête une instruction ALTER INDEX &#8230; REBUILD en cours d&rsquo;exécution, tout le travail du moteur de base de données effectué jusqu’au moment de l&rsquo;arrêt de l&rsquo;exécution de l&rsquo;instruction est perdu. Ce n&rsquo;est pas le cas de REORGANIZE.</p>
<p>=> REORGANIZE ne fait que ré-arranger le niveau feuille de l&rsquo;index, et n&rsquo;alloue ou ne désalloue aucune page.<br />
En revanche, REBUILD reconstruit tous les niveaux de l&rsquo;index, et se sert au besoin de nouvelles pages, de façon à réduire la fragmentation interne et externe de l&rsquo;index. REORGANIZE ne fait que réduire la fragmentation logique de l&rsquo;index, de sorte à minimiser, si ce n&rsquo;est éviter, les aller-retours dans les pages de l&rsquo;index lors de la lecture de celui-ci.</p>
<p>=> REBUILD est exécutée hors-ligne par défaut.<br />
Dans ce cas, on ne peut pas mettre à jour la table sous-jacente s&rsquo;il s&rsquo;agit de son index cluster, et on ne peut pas changer les colonnes qui participent à la définition d&rsquo;un index non-cluster tant que l&rsquo;instruction ALTER INDEX &#8230; REBUILD est en cours d&rsquo;exécution.</p>
<p>REORGANIZE ne maintient pas ces verrous, et permet donc de continuer à effectuer des mises à jour sur la table cible de l&rsquo;instruction, qui est toujours effectuée en ligne.</p>
<p>C&rsquo;est donc pour cela que l&rsquo;on doit utiliser :</p>
<p>=> REORGANIZE lorsque la fragmentation de l&rsquo;index est faible (entre 5-10% et 25-30%)<br />
=> REBUILD lorsque la fragmentation de l&rsquo;index est plus élevée (plus de 25-30%).</p>
<p>Si l&rsquo;on exécute une instruction ALTER INDEX &#8230; REBUILD en ligne avec l&rsquo;option ONLINE, qui n&rsquo;est disponible que dans les instances de SQL Server dont l&rsquo;édition est <em>Enterprise</em>, deux index sont maintenus : l&rsquo;ancien est supprimé et remplacé par le nouveau à la fin de l&rsquo;opération. Cela permet l&rsquo;accès en écriture sur la table, même si l&rsquo;opération est plus longue et plus coûteuse. Mais cela est nécessaire lorsqu&rsquo;on a une base de données dont la disponibilité doit être 24 x 7 x 366.</p>
<p>On notera qu&rsquo;on ne peut pas reconstruire un index en ligne si :</p>
<p>&#8211; l&rsquo;index est cluster et la table a au moins une colonne de type LOB (image, text, ntext varchar(max), nvarchar(max), varbinary(max)), spatial (geography et geometry) ou hierarchy, ou encore une colonne calculée,</p>
<p>&#8211; l&rsquo;index est non-cluster, et porte sur des colonnes de type LOB, spatial ou hierarchy, ou que l&rsquo;une des colonnes clé de l&rsquo;index porte sur une colonne calculée.</p>
<p>Bonne maintenance des index !</p>
<p>ElSüket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>5 nouvelles DMV dans SQL Server 2008 R2 SP1 (et donc SQL Server 2012)</title>
		<link>https://blog.developpez.com/elsuket/p10828/moteur-de-base-de-donnees-sql-server/5_dmv_dans_sql_2008_r2_sp1_sql_2012</link>
		<comments>https://blog.developpez.com/elsuket/p10828/moteur-de-base-de-donnees-sql-server/5_dmv_dans_sql_2008_r2_sp1_sql_2012#comments</comments>
		<pubDate>Tue, 13 Mar 2012 12:53:59 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le service pack 1 de SQL Server 2008 R2 a introduit quelques nouvelles vues de gestion dynamique fort intéressantes, surtout quand il s&#8217;agit de communiquer avec les administrateurs système. => sys.dm_os_volume_stats permet d&#8217;obtenir quelques informations sur les volumes sur lesquels &#8230; <a href="https://blog.developpez.com/elsuket/p10828/moteur-de-base-de-donnees-sql-server/5_dmv_dans_sql_2008_r2_sp1_sql_2012">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Le service pack 1 de SQL Server 2008 R2 a introduit quelques nouvelles vues de gestion dynamique fort intéressantes, surtout quand il s&rsquo;agit de communiquer avec les administrateurs système.<br />
<span id="more-114"></span></p>
<p>=> <strong>sys.dm_os_volume_stats</strong> permet d&rsquo;obtenir quelques informations sur les volumes sur lesquels sont stockés les fichiers des bases de données hébergées par le serveur. On obtient la liste des volumes avec leurs caractéristiques avec la requête suivante :</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 /></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 - 13/03/2012 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;DISTINCT VS.volume_mount_point <br />
&nbsp; &nbsp; , VS.volume_id <br />
&nbsp; &nbsp; , VS.logical_volume_name <br />
&nbsp; &nbsp; , VS.file_system_type <br />
&nbsp; &nbsp; , VS.total_bytes / 1024 / 1024 AS volume_size_MB <br />
&nbsp; &nbsp; , VS.available_bytes / 1024 / 1024 AS volumn_free_space_MB <br />
&nbsp; &nbsp; , VS.supports_compression <br />
&nbsp; &nbsp; , VS.supports_alternate_streams <br />
&nbsp; &nbsp; , VS.supports_sparse_files <br />
&nbsp; &nbsp; , VS.is_read_only <br />
&nbsp; &nbsp; , VS.is_compressed <br />
FROM &nbsp; &nbsp;sys.master_files AS MF <br />
CROSS APPLY &nbsp;sys.dm_os_volume_stats(MF.database_id, MF.file_id) AS VS</div></td></tr></tbody></table></div>
<p>Et un requête avec la carte des fichiers, pour toutes les bases de données :</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 /></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 - 13/03/2012 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;D.name AS database_name <br />
&nbsp; &nbsp; , MF.name AS file_logical_name <br />
&nbsp; &nbsp; , MF.physical_name AS file_physical_name <br />
&nbsp; &nbsp; , MF.type_desc AS file_type <br />
&nbsp; &nbsp; , VS.volume_mount_point <br />
&nbsp; &nbsp; , VS.volume_id <br />
&nbsp; &nbsp; , VS.logical_volume_name <br />
&nbsp; &nbsp; , VS.file_system_type <br />
&nbsp; &nbsp; , VS.total_bytes / 1024 / 1024 AS volume_size_MB <br />
&nbsp; &nbsp; , VS.available_bytes / 1024 / 1024 AS volumn_free_space_MB <br />
&nbsp; &nbsp; , VS.supports_compression <br />
&nbsp; &nbsp; , VS.supports_alternate_streams <br />
&nbsp; &nbsp; , VS.supports_sparse_files <br />
&nbsp; &nbsp; , VS.is_read_only <br />
&nbsp; &nbsp; , VS.is_compressed <br />
FROM &nbsp; &nbsp;sys.master_files AS MF <br />
CROSS APPLY &nbsp;sys.dm_os_volume_stats(MF.database_id, MF.file_id) AS VS <br />
INNER JOIN &nbsp;sys.databases AS D <br />
&nbsp; &nbsp; &nbsp; ON D.database_id = MF.database_id <br />
-- WHERE &nbsp;D.name = 'maBD'</div></td></tr></tbody></table></div>
<p>La documentation de cette DMV pour <a href="http://msdn.microsoft.com/fr-fr/library/hh223223.aspx">SQL Server 2008 R2</a> et <a href="http://msdn.microsoft.com/fr-fr/library/hh223223%28v=sql.110%29.aspx">SQL Server 2012</a></p>
<p>=> <strong>sys.dm_os_windows_info</strong></p>
<p>Cette DMV retourne quelques informations intéressantes à propos de l&rsquo;installation de Windows qui héberge SQL Server.<br />
En l&rsquo;interrogeant sur mon PC sous Windows 7 SP1 en Français, j&rsquo;obtiens :</p>
<p><img src="http://blog.developpez.com/media/sys.dm_os_windows_info.PNG" width="516" height="158" alt="" /></p>
<p>La documentation de cette DMV pour <a href="http://msdn.microsoft.com/fr-fr/library/hh204565.aspx">SQL Server 2008 R2</a> et <a href="http://msdn.microsoft.com/fr-fr/library/hh204565%28v=sql.110%29.aspx">SQL Server 2012</a></p>
<p>=> <strong>sys.dm_server_registry</strong></p>
<p>Cette DMV retourne toutes les valeurs stockées dans le registre pour SQL Server, en ce qui concerne les options de démarrage du service, et la configuration des <a href="http://blog.developpez.com/elsuket/p7723/utilitaires/configurer-les-protocoles-de-connexion-a/">protocoles de connexion</a> à l&rsquo;instance interrogée :</p>
<p><img src="http://img440.imageshack.us/img440/612/sysdmserverregistry.png" alt="" title="" /></p>
<p>La documentation de cette DMV pour <a href="http://msdn.microsoft.com/fr-fr/library/hh204561.aspx">SQL Server 2008 R2</a> et <a href="http://msdn.microsoft.com/fr-fr/library/hh204561%28v=sql.110%29.aspx">SQL Server 2012</a></p>
<p>=> <strong>sys.dm_server_services</strong></p>
<p>Comme son nom l&rsquo;indique, cette DMV retourne quelques informations sur les services installés pour l&rsquo;instance SQL Server interrogée :</p>
<p><img src="http://blog.developpez.com/media/sys.dm_server_services.PNG" width="1532" height="184" alt="" /></p>
<p>On notera que sont exposés la date de dernier démarrage du service et l&rsquo;instance est en cluster.</p>
<p>La documentation de cette DMV pour <a href="http://msdn.microsoft.com/fr-fr/library/hh204542.aspx">SQL Server 2008 R2</a> et <a href="http://msdn.microsoft.com/fr-fr/library/hh204542%28v=sql.110%29.aspx">SQL Server 2012</a></p>
<p>=> <strong>sys.dm_server_memory_dumps</strong></p>
<p>Cette DMV retourne l&rsquo;ensemble des vidages mémoire avec le chemin des fichiers, c&rsquo;est-à-dire à chaque fois que SQL Server a rencontré un gros problème.<br />
Malheureusement (ou pas) sur mon installation de SQL Server 2012, l&rsquo;interrogation de cette DMV ne retourne rien <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>La documentation de cette DMV pour <a href="http://msdn.microsoft.com/fr-fr/library/hh204543%28v=sql.105%29.aspx">SQL Server 2008 R2</a> et <a href="http://msdn.microsoft.com/fr-fr/library/hh204543%28v=SQL.110%29.aspx">SQL Server 2012</a></p>
<p>On le voit donc, Microsoft continue d&rsquo;exposer les données système à travers les <a href="http://msdn.microsoft.com/fr-fr/library/ms188754.aspx">fonctions et vues de gestion dynamique</a> (respectivement DMF et DMV dans la littérature, et plus généralement DMO pour Dynamic Management Object).<br />
Elles ont été introduites avec SQL Server 2005, et facilitent grandement les travail des administrateurs de bases de données et des consultants.</p>
<p>Ces 5 nouvelles DMVs permettent notamment de démarrer une discussion avec les administrateurs système.<br />
En effet en exécutant de telles requêtes sur un ensemble de serveurs hébergeant une instance de SQL Server à travers les possibilités de Central Management Server, elles permettent en outre de comparer et détecter très simplement les différences de configuration entre plusieurs serveurs, et elles sont donc fort bienvenues.</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mêlée de considérations sur la gestion du fichier du journal des transactions</title>
		<link>https://blog.developpez.com/elsuket/p10037/moteur-de-base-de-donnees-sql-server/melee_considerations_fichier_journal_tra</link>
		<comments>https://blog.developpez.com/elsuket/p10037/moteur-de-base-de-donnees-sql-server/melee_considerations_fichier_journal_tra#comments</comments>
		<pubDate>Tue, 07 Jun 2011 03:19:17 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici un petit lot de requêtes qui permet de connaître le nombre de Virtual Log Files en cours d&#8217;utilisation &#8230; En effet le fichier du journal des transactions est découpé en portions logiques, dont le nombre et la taille sont &#8230; <a href="https://blog.developpez.com/elsuket/p10037/moteur-de-base-de-donnees-sql-server/melee_considerations_fichier_journal_tra">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici un petit lot de requêtes qui permet de connaître le nombre de <em>Virtual Log Files</em> en cours d&rsquo;utilisation &#8230;<br />
<span id="more-110"></span></p>
<p>En effet le fichier du journal des transactions est découpé en portions logiques, dont le nombre et la taille sont variables &#8230;<br />
C&rsquo;est en fait le cas si on n&rsquo;a pas bien taillé le fichier dès la création de la base de données.<br />
Ces portions logiques sont nommées <em>fichiers virtuels du journal</em>, ou encore <em>Virtual Log Files</em>, abrégé en VLF dans la littérature.</p>
<p>En effet ce fichier, comme les fichiers de données de la base de données, peut grossir autant que cela est nécessaire.<br />
En suivant donc sa taille, on peut décider d&rsquo;augmenter la fréquence des sauvegardes de ce fichier, qui permettent dans la majorité des cas de maintenir le fichier à une taille stable.</p>
<p>Un manœuvre d&rsquo;urgence consiste à effectuer une sauvegarde du fichier du journal des transactions avec l&rsquo;option WITH TRUNCATE_ONLY (qui n&rsquo;est plus disponible sous SQL Server 2008), puis à faire rétrécir le fichier.</p>
<p>Rappelons qu&rsquo;en aucun cas autre que celui d&rsquo;urgence ou exceptionnel, on ne rétrécira ce fichier, comme les autres fichiers de la base de données.<br />
Il peut être nécessaire d&rsquo;y avoir recours :</p>
<p>&#8211; par manque d&rsquo;espace disque,<br />
&#8211; parce qu&rsquo;on a purgé un grand nombre de tables, et qu&rsquo;on considère qu&rsquo;elles n’atteindront plus jamais cette taille<br />
&#8211; parce qu&rsquo;on a changé le <a href="http://msdn.microsoft.com/fr-fr/library/ms189275.aspx">mode de récupération</a> de la base de données vers le mode SIMPLE</p>
<p>En effet c&rsquo;est ce dernier qui pilote l&rsquo;utilisation du fichier du journal des transactions.<br />
En résumé, dans le mode de récupération </p>
<p>=> SIMPLE, les fichiers virtuels du journal des transactions est vidé dès la fin d&rsquo;une transaction<br />
=> FULL toutes les transactions sont conservées dans leur intégralité jusqu&rsquo;à la prochaine sauvegarde du fichier<br />
=> BULK_LOGGED, toutes les transactions sont conservées dans leur intégralité jusqu&rsquo;à la prochaine sauvegarde du fichier, sauf pour certaines opérations, comme la reconstruction des index ou encore le chargement de fichiers par BCP ou BULK INSERT, &#8230;</p>
<p>C&rsquo;est là une vue très simple des modes de récupération, et certains facteurs peuvent affecter sa troncature :</p>
<p>&#8211; Une transaction qui a été laissée ouverte. On peut facilement le savoir à l&rsquo;aide de l&rsquo;instruction DBCC OPENTRAN.<br />
&#8211; Une réplication en cours<br />
&#8211; Une mise en miroir mise en pause<br />
&#8211; Une lecture du fichier du journal des transactions (c&rsquo;est très court mais cela peut se produire lorsqu&rsquo;on utilise <em>Change Data Capture</em><br />
&#8211; Une création d&rsquo;une <a href="http://blog.developpez.com/elsuket/p7454/moteur-de-base-de-donnees-sql-server/creer-des-captures-instantanees-de-bases/">capture instantanée</a> de la base de données<br />
&#8211; &#8230;</p>
<p>L&rsquo;instruction (non documentée) DBCC LOGINFO permet de connaître le nombre de fichiers journaux virtuels, ainsi que de savoir combien d&rsquo;entre eux sont actifs.</p>
<p>Il suffit de la décortiquer avec le lot de requête suivant pour avoir un rapide état des lieux :</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 /></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 - 07/06/2011 <br />
------------------------------- <br />
DECLARE @vlf TABLE <br />
( <br />
&nbsp; FileId tinyint <br />
&nbsp; , FileSize bigint <br />
&nbsp; , StartOffset bigint <br />
&nbsp; , FSeqNo int <br />
&nbsp; , Status tinyint <br />
&nbsp; , Parity tinyint <br />
&nbsp; , CreateLSN varchar(21) <br />
) <br />
&nbsp;<br />
INSERT &nbsp;@vlf <br />
EXEC ('DBCC LOGINFO') <br />
&nbsp;<br />
SELECT &nbsp;SUM(FileSize) / 1048576 AS total_file_size_MB <br />
&nbsp; , SUM <br />
&nbsp; ( <br />
&nbsp; &nbsp; CASE Status <br />
&nbsp; &nbsp; &nbsp; WHEN 2 THEN FileSize <br />
&nbsp; &nbsp; &nbsp; ELSE 0 <br />
&nbsp; &nbsp; END <br />
&nbsp; ) / 1048576 AS file_size_in_use_MB <br />
&nbsp; , COUNT(*) AS VLF_amount <br />
&nbsp; , SUM <br />
&nbsp; ( <br />
&nbsp; &nbsp; CASE Status <br />
&nbsp; &nbsp; &nbsp; WHEN 2 THEN 1 <br />
&nbsp; &nbsp; &nbsp; ELSE 0 <br />
&nbsp; &nbsp; END <br />
&nbsp; ) AS VLF_in_use <br />
FROM &nbsp;@vlf <br />
&nbsp;<br />
DBCC SQLPERF(logspace)</div></td></tr></tbody></table></div>
<p>Si l&rsquo;on souhaite réduire le nombre de VLFs du fichier du journal des transactions, il faudra d&rsquo;abord le faire rétrécir.<br />
Pour ce faire, il faudra donc procéder à une sauvegarde fichier du journal des transactions (attention parfois deux sont <a href="http://blog.developpez.com/mikedavem/p8044/sql-server-2005/architecture/pourquoi-la-commande-shrinkfile-ne-redui/">nécessaires</a>)</p>
<p>Ensuite on peut faire grossir le fichier par incréments suivant la règle d&rsquo;allocation :</p>
<p>&#8211; Si la taille de l&rsquo;incrément est comprise entre 1 et 64Mo, alors 4 VLFs seront ajoutés;<br />
&#8211; Si la taille de l&rsquo;incrément est comprise entre 65Mo et 1Go, alors 8 VLFs seront ajoutés;<br />
&#8211; Si la taille de l&rsquo;incrément plus grande qu&rsquo;un 1Go, alors 16 VLFs seront ajoutés.</p>
<p>Pour faire grossir le fichier du journal des transactions, il suffit d&rsquo;exécuter le squelette 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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ALTER DATABASE maBaseDeDonnees <br />
MODIFY FILE (NAME = '[nomLogiqueDuFichierDuJournalDesTransactions]', SIZE = [nouvelleTaille][MB_ou_GB], FILEGROWTH = [tailleIncrement]</div></td></tr></tbody></table></div>
<p>Quelques détails :</p>
<p>=> [nomLogiqueDuFichierDuJournalDesTransactions] se trouve avec la requête suivante :</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 /></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 - 07/06/2011 <br />
------------------------------- <br />
SELECT &nbsp;name <br />
&nbsp; , physical_name <br />
&nbsp; , type_desc <br />
FROM &nbsp;sys.database_files <br />
WHERE &nbsp;type_desc = 'LOG'</div></td></tr></tbody></table></div>
<p>Ou plus généralement :</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 /></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 - 07/06/2011 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;D.name AS database_name <br />
&nbsp; &nbsp; , MF.name AS logical_file_name <br />
&nbsp; &nbsp; , MF.physical_name AS physical_file_name <br />
&nbsp; &nbsp; , type_desc AS file_type <br />
FROM &nbsp; &nbsp;sys.master_files AS MF <br />
INNER JOIN &nbsp;sys.databases AS D ON MF.database_id = D.database_id <br />
WHERE &nbsp; &nbsp;MF.type_desc = 'LOG' <br />
ORDER BY &nbsp;D.name</div></td></tr></tbody></table></div>
<p>=> [nouvelleTaille] est la taille que l&rsquo;on souhaite que le fichier du journal des transaction ait<br />
=> [tailleIncrement] est la taille de grossissement du fichier, si cela doit se produire<br />
=> [MB_ou_GB] est le suffixe de taille : on précise MB ou GB, (mais on peut aussi mettre KB ).</p>
<p>Bonne gestion du fichier du journal des transactions !</p>
<p>ElSüket</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>1</slash:comments>
		</item>
		<item>
		<title>Trouver la consommation de CPU par base de données en utilisant le cache de plans, sous SQL Server 2005 et suivants</title>
		<link>https://blog.developpez.com/elsuket/p10710/moteur-de-base-de-donnees-sql-server/trouver_la_consommation_de_cpu_par_base_</link>
		<comments>https://blog.developpez.com/elsuket/p10710/moteur-de-base-de-donnees-sql-server/trouver_la_consommation_de_cpu_par_base_#comments</comments>
		<pubDate>Sun, 12 Feb 2012 10:06:15 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une petite requête qui permet de retrouver le temps CPU consommé par base de données d&#8217;une instance SQL Server 1234567891011121314151617181920212223242526------------------------------- -- Nicolas Souquet - 2012-02-12 ------------------------------- ;WITH &#160; DB_CPU_STAT AS &#160; ( &#160; &#160; SELECT &#160; &#160;D.database_id &#160; &#160; &#8230; <a href="https://blog.developpez.com/elsuket/p10710/moteur-de-base-de-donnees-sql-server/trouver_la_consommation_de_cpu_par_base_">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une petite requête qui permet de retrouver le temps CPU consommé par base de données d&rsquo;une instance SQL Server<br />
<span id="more-113"></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 /></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 - 2012-02-12 <br />
------------------------------- <br />
;WITH <br />
&nbsp; DB_CPU_STAT AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;D.database_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , D.name AS database_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , SUM(total_worker_time) / 1000 AS total_CPU_time_ms <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;sys.dm_exec_query_stats AS QS <br />
&nbsp; &nbsp; CROSS APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp;CONVERT(int, value) AS database_id &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp;sys.dm_exec_plan_attributes(QS.plan_handle) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;attribute = N'dbid' <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS DB <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.databases AS D <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON DB.database_id = D.database_id <br />
&nbsp; &nbsp; GROUP BY &nbsp;D.database_id, D.name <br />
&nbsp; ) <br />
SELECT &nbsp;database_name <br />
&nbsp; , total_CPU_time_ms / 1000 AS total_CPU_time_s <br />
&nbsp; , CAST(total_CPU_time_ms * 1.0 / SUM(total_CPU_time_ms) OVER() * 100.0 AS decimal(5, 2)) AS [CPU_%] <br />
FROM &nbsp;DB_CPU_STAT <br />
WHERE &nbsp;database_id &gt; 4 -- system databases <br />
AND &nbsp;database_id &lt;&gt; 32767 -- ResourceDB <br />
ORDER &nbsp;BY total_CPU_time_ms DESC</div></td></tr></tbody></table></div>
<p>Et bonne surveillance de SQL Server <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>Savoir quelles collations sont utilisées au niveau colonne, base de données et instance SQL Server</title>
		<link>https://blog.developpez.com/elsuket/p10232/moteur-de-base-de-donnees-sql-server/savoir_quelle_sont_les_collations_utilis</link>
		<comments>https://blog.developpez.com/elsuket/p10232/moteur-de-base-de-donnees-sql-server/savoir_quelle_sont_les_collations_utilis#comments</comments>
		<pubDate>Sat, 27 Aug 2011 12:01:22 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Comme il est important de savoir si la collation utilisée par une colonne, une base de données ou une instance SQL Server est sensible à la casse ou aux accents, ou &#8230;, voici quelques requêtes qui permettent d&#8217;obtenir l&#8217;information très &#8230; <a href="https://blog.developpez.com/elsuket/p10232/moteur-de-base-de-donnees-sql-server/savoir_quelle_sont_les_collations_utilis">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Comme il est important de savoir si la collation utilisée par une colonne, une base de données ou une instance SQL Server est sensible à la casse ou aux accents, ou &#8230;, voici quelques requêtes qui permettent d&rsquo;obtenir l&rsquo;information très simplement :<br />
<span id="more-111"></span></p>
<p>=> <strong>Au niveau colonne :</strong></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 /></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/08/2011 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;S.name + '.' + T.name AS table_name <br />
&nbsp; &nbsp; , C.name AS column_name <br />
&nbsp; &nbsp; , C.collation_name AS column_collation_name <br />
&nbsp; &nbsp; , FHC.description AS collation_description <br />
FROM &nbsp; &nbsp;sys.columns AS C <br />
INNER JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; ON T.object_id = C.object_id <br />
INNER JOIN &nbsp;sys.schemas AS S <br />
&nbsp; &nbsp; &nbsp; ON S.schema_id = T.schema_id <br />
INNER JOIN &nbsp;sys.fn_helpcollations() AS FHC <br />
&nbsp; &nbsp; &nbsp; ON C.collation_name = FHC.name <br />
WHERE &nbsp; &nbsp;S.name = 'dbo' <br />
AND &nbsp; &nbsp;T.name = 'maTable' <br />
AND &nbsp; &nbsp;C.name = 'maColonne'</div></td></tr></tbody></table></div>
<p>=> <strong>Au niveau base de données :</strong></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 /></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/08/2011 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;D.name AS database_name <br />
&nbsp; &nbsp; , D.collation_name AS database_collation_name <br />
&nbsp; &nbsp; , FHC.description AS collation_description <br />
FROM &nbsp; &nbsp;sys.databases AS D <br />
INNER JOIN &nbsp;sys.fn_helpcollations() AS FHC <br />
&nbsp; &nbsp; &nbsp; ON D.collation_name = FHC.name <br />
--WHERE &nbsp; &nbsp;D.name = 'leNomDeVotreBaseDeDonnees'</div></td></tr></tbody></table></div>
<p>=> <strong>Au niveau de l&rsquo;instance SQL Server</strong></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 /></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/08/2011 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;SC.server_collation_name <br />
&nbsp; &nbsp; , FHC.description AS server_collation_name <br />
FROM &nbsp; &nbsp;(SELECT &nbsp;SERVERPROPERTY('Collation') AS server_collation_name) AS SC <br />
INNER JOIN &nbsp;sys.fn_helpcollations() AS FHC <br />
&nbsp; &nbsp; &nbsp; ON SC.server_collation_name = FHC.name</div></td></tr></tbody></table></div>
<p>Pour en savoir un peu plus sur les collations dans SQL Server, je vous conseille de lire l&rsquo;<a href="http://sqlpro.developpez.com/cours/sqlserver/collations/">article</a> de SQLPro à ce sujet.</p>
<p>Bon tri de chaînes !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Marquer une procédure stockée comme objet système : la procédure stockée sp_MS_marksystemobject</title>
		<link>https://blog.developpez.com/elsuket/p9409/utilitaires/marquer_un_procedure_stockee_comme_objet</link>
		<comments>https://blog.developpez.com/elsuket/p9409/utilitaires/marquer_un_procedure_stockee_comme_objet#comments</comments>
		<pubDate>Tue, 19 Oct 2010 04:55:58 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Non documenté]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Il peut être intéressant de pouvoir utiliser une procédure stockée dans n&#8217;importe quel contexte de base de données (sur la même instance SQL Server). Voyons comment faire cela à l&#8217;aide de la procédure stockée système non documentée sp_MS_marksystemobject Je cherchai &#8230; <a href="https://blog.developpez.com/elsuket/p9409/utilitaires/marquer_un_procedure_stockee_comme_objet">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Il peut être intéressant de pouvoir utiliser une procédure stockée dans n&rsquo;importe quel contexte de base de données (sur la même instance SQL Server).<br />
Voyons comment faire cela à l&rsquo;aide de la procédure stockée système <strong>non documentée <em>sp_MS_marksystemobject</em></strong><br />
<span id="more-130"></span><br />
Je cherchai à fournir à mes collègues développeurs SQL un moyen de générer des instructions CRUD (INSERT, SELECT, UPDATE, DELETE) de façon propre et générique.<br />
Voici donc l&rsquo;exemple de l&rsquo;INSERT (je publierai les autres dans un billet à venir) :</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">USE master <br />
GO <br />
&nbsp;<br />
CREATE PROCEDURE dbo.sp__generate_INSERT <br />
&nbsp; &nbsp; @_table_name sysname, <br />
&nbsp; &nbsp; @_nb_tab tinyint = 0 <br />
AS <br />
BEGIN <br />
&nbsp; &nbsp; SET NOCOUNT ON <br />
&nbsp;<br />
&nbsp; &nbsp; DECLARE @sql varchar(max) <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;@sql = CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN @sql IS NULL THEN REPLICATE(CHAR(9), @_nb_tab) + 'INSERT' + CHAR(9) + @_table_name + &nbsp;CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), @_nb_tab) + '(' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), @_nb_tab) + CHAR(9) + name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE @sql + CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), @_nb_tab) + CHAR(9) + ', ' + name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns <br />
&nbsp; &nbsp; WHERE &nbsp; &nbsp;object_id = OBJECT_ID(@_table_name) <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;is_computed = 0 <br />
&nbsp; &nbsp; ORDER &nbsp; &nbsp;BY column_id <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; SET &nbsp; &nbsp;@sql = @sql + CHAR(13) + CHAR(10) + REPLICATE(CHAR(9), @_nb_tab) + ')' <br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; PRINT &nbsp; &nbsp;@sql <br />
END</div></td></tr></tbody></table></div>
<p>Vous remarquerez que je me place dans le contexte de la base de données système master, qui est la seule dans laquelle vous pouvez marquer des procédures stockées comme objet système.</p>
<p>Un autre requis pour pouvoir utiliser une procédure stockée marquée comme objet système dans n&rsquo;importe quel contexte de base de données de l&rsquo;instance en cours, est de faire commencer le nom de la procédure stockée par &laquo;&nbsp;sp&nbsp;&raquo;.<br />
Rien ne vous empêche de marquer la procédure stockée comme objet système, mais lorsque vous exécuterez une telle procédure stockée (dont le nom ne commence donc pas par &laquo;&nbsp;sp&nbsp;&raquo;), SQL Server &laquo;&nbsp;feindra&nbsp;&raquo; de ne pas trouver celle-ci.</p>
<p><strong>Le marquage se fait de façon extrêmement simple, mais n&rsquo;est pas documenté</strong> :</p>
<p><code class="codecolorer text default"><span class="text">EXEC sp_MS_marksystemobject 'sp__generate_INSERT'</span></code></p>
<p>Et le tour est joué : vous pouvez générer le script d&rsquo;INSERT en exécutant tout simplement :</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 maBD <br />
GO <br />
&nbsp;<br />
EXEC sp__generate_INSERT 'maTable'</div></td></tr></tbody></table></div>
<p>Bonne génération !</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>5</slash:comments>
		</item>
		<item>
		<title>Connaître les caractéristiques des statistiques de colonne d&#8217;une table</title>
		<link>https://blog.developpez.com/elsuket/p9966/moteur-de-base-de-donnees-sql-server/connaitre_caracteristiques_statistiques</link>
		<comments>https://blog.developpez.com/elsuket/p9966/moteur-de-base-de-donnees-sql-server/connaitre_caracteristiques_statistiques#comments</comments>
		<pubDate>Thu, 12 May 2011 10:45:24 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici un lot de requêtes qui retourne quelques caractéristiques intéressantes des statistiques d&#8217;une table, notamment : &#8211; la quantité de données, en MB, qui a été échantillonnée &#8211; la date de dernier échantillonnage &#8211; le nom de la statistique, ainsi &#8230; <a href="https://blog.developpez.com/elsuket/p9966/moteur-de-base-de-donnees-sql-server/connaitre_caracteristiques_statistiques">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici un lot de requêtes qui retourne quelques caractéristiques intéressantes des statistiques d&rsquo;une table, notamment :</p>
<p>&#8211; la quantité de données, en MB, qui a été échantillonnée<br />
&#8211; la date de dernier échantillonnage<br />
&#8211; le nom de la statistique, ainsi que les colonnes sur lesquelles la statistique échantillonne<br />
&#8211; le nombre de lignes échantillonnées lors du dernier échantillonnage<br />
&#8211; la densité (inverse de la sélectivité)<br />
&#8211; le nombre de modifications dans les colonnes de la statistique depuis le dernier échantillonnage<br />
&#8211; le SRT (<em>Statistic Recomputation Threshold</em> : seuil de ré-échantillonnage de la statistique)<br />
  C&rsquo;est le nombre de modifications que les colonnes de la statistique doivent subir avant d&rsquo;être ré-échantillonnées.<br />
&#8211; quelques comparaisons par rapport au nombre réel de lignes de la table</p>
<p><span id="more-109"></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 /></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 - 12-05-2011 <br />
------------------------------- <br />
SET NOCOUNT ON <br />
GO <br />
------------------------------------------------------------------------------------------------------------------------------ <br />
DECLARE &nbsp;@schema_name sysname = 'dbo' <br />
&nbsp; , @table_or_view_name sysname = 'maTable' <br />
&nbsp; , @statistic_name sysname = NULL -- NULL lit toutes les statistiques de la table <br />
&nbsp; , @separator varchar(2) = ', ' <br />
------------------------------------------------------------------------------------------------------------------------------ <br />
IF NOT EXISTS <br />
( <br />
&nbsp; SELECT &nbsp; &nbsp;* <br />
&nbsp; FROM &nbsp; &nbsp;sys.schemas AS S <br />
&nbsp; INNER JOIN &nbsp;sys.objects AS O ON S.schema_id = O.schema_id <br />
&nbsp; WHERE &nbsp; &nbsp;S.name = @schema_name <br />
&nbsp; AND &nbsp; &nbsp;O.name = @table_or_view_name <br />
&nbsp; AND &nbsp; &nbsp;O.type IN ('U', 'V') -- table or view <br />
) <br />
BEGIN <br />
&nbsp; RAISERROR('The %s.%s table or indexed view does not exist !', 16, 1, @schema_name, @table_or_view_name) <br />
&nbsp; RETURN <br />
END <br />
&nbsp;<br />
IF @statistic_name IS NOT NULL <br />
AND NOT EXISTS <br />
( <br />
&nbsp; SELECT &nbsp; &nbsp;* <br />
&nbsp; FROM &nbsp; &nbsp;sys.schemas AS S <br />
&nbsp; INNER JOIN &nbsp;sys.objects AS O ON S.schema_id = O.schema_id <br />
&nbsp; INNER JOIN &nbsp;sys.indexes AS I ON O.object_id = I.object_id <br />
&nbsp; WHERE &nbsp; &nbsp;S.name = @schema_name <br />
&nbsp; AND &nbsp; &nbsp;O.name = @table_or_view_name <br />
&nbsp; AND &nbsp; &nbsp;I.name = @statistic_name <br />
) <br />
BEGIN <br />
&nbsp; RAISERROR('The %s statistics on the %s.%s table or indexed view does not exist !', 16, 1, @schema_name, @table_or_view_name, @statistic_name) <br />
&nbsp; RETURN <br />
END <br />
----------------------------------------- <br />
-- Collecting column and index statistics <br />
----------------------------------------- <br />
DECLARE &nbsp;@stat_header TABLE <br />
( <br />
&nbsp; stat_name sysname <br />
&nbsp; , updated varchar(32) <br />
&nbsp; , row_count bigint <br />
&nbsp; , rows_sampled bigint <br />
&nbsp; , steps int <br />
&nbsp; , density float <br />
&nbsp; , avg_key_length float <br />
&nbsp; , string_index char(3) <br />
&nbsp; , filter_expression varchar(1024) &nbsp;<br />
&nbsp; , unfiltered_rows bigint <br />
) <br />
&nbsp;<br />
DECLARE @stat_name sysname = ' ' <br />
&nbsp; , @object_id int <br />
&nbsp; , @sql nvarchar(256) = 'DBCC SHOW_STATISTICS(@TABLE@, @STATS@) WITH NO_INFOMSGS, STAT_HEADER' <br />
&nbsp; , @exec_string nvarchar(512) <br />
&nbsp;<br />
WHILE DATALENGTH(@stat_name) &gt; 0 <br />
BEGIN <br />
&nbsp; SET @stat_name = NULL <br />
&nbsp;<br />
&nbsp; SELECT &nbsp; &nbsp;TOP(1) @stat_name = S.name <br />
&nbsp; FROM &nbsp; &nbsp;sys.stats AS S <br />
&nbsp; INNER JOIN &nbsp;sys.objects AS O ON S.object_id = O.object_id <br />
&nbsp; LEFT JOIN &nbsp;@stat_header AS SH ON S.name = SH.stat_name <br />
&nbsp; WHERE &nbsp; &nbsp;O.name = @table_or_view_name <br />
&nbsp; AND &nbsp; &nbsp;SH.stat_name IS NULL <br />
&nbsp; AND &nbsp; &nbsp;(@statistic_name IS NULL OR S.name = @statistic_name) <br />
&nbsp; <br />
&nbsp; SELECT @exec_string = REPLACE(REPLACE(@sql, '@STATS@', @stat_name), '@TABLE@', @table_or_view_name) <br />
&nbsp;<br />
&nbsp; INSERT &nbsp;@stat_header <br />
&nbsp; EXEC &nbsp;(@exec_string) <br />
END <br />
-------------------------------------------------------------------------------------------------------- <br />
;WITH <br />
&nbsp; CTE AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;T.stat_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , T.row_count <br />
&nbsp; &nbsp; &nbsp; &nbsp; , T.rows_sampled <br />
&nbsp; &nbsp; &nbsp; &nbsp; , SI.rowmodctr <br />
&nbsp; &nbsp; &nbsp; &nbsp; , T.steps <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CAST(T.density AS decimal(5,3)) AS density <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CAST((CAST(T.rows_sampled AS decimal(38, 10)) / T.row_count) * 100 AS decimal(38, 2)) AS stat_sample_rate <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CAST((CAST(SI.rowmodctr AS decimal(38, 10)) / T.row_count) * 100 AS decimal(38, 2)) AS change_rate <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CAST(updated AS datetime) AS last_update <br />
&nbsp; &nbsp; &nbsp; &nbsp; , S.auto_created <br />
&nbsp; &nbsp; &nbsp; &nbsp; , REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(S.filter_definition, '[', ''), ']', ''), ')', ''), '(', ''), '=', ' = ') AS filter_definition <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;@stat_header AS T <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.stats AS S <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON S.object_id = OBJECT_ID(@table_or_view_name) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND S.name = T.stat_name <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.sysindexes AS SI <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON SI.id = S.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND SI.indid = S.stats_id <br />
&nbsp; ) <br />
&nbsp; , CTE_FINAL AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;PS.in_row_used_page_count / 128 AS data_MB <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.stat_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.auto_created <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.filter_definition <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.density <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.row_count AS stat_row_count <br />
&nbsp; &nbsp; &nbsp; &nbsp; , PS.row_count AS real_row_count <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.rows_sampled <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.rowmodctr <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.steps <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN PS.row_count &lt; 6 THEN 6 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN PS.row_count BETWEEN 6 AND 500 THEN 500 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE CAST(500 + (0.2 * PS.row_count) AS int) + 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; END AS stat_recompute_threshold <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.stat_sample_rate <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CAST(CAST(C.rows_sampled AS decimal(38, 10)) / (CASE PS.row_count WHEN 0 THEN 1 ELSE PS.row_count END) * 100 AS decimal(38, 2)) AS real_sample_rate <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.change_rate AS stat_change_rate <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CAST((CAST(C.rowmodctr AS decimal(38, 10)) / (CASE PS.row_count WHEN 0 THEN 1 ELSE PS.row_count END)) * 100 AS decimal(38, 2)) AS real_change_rate <br />
&nbsp; &nbsp; &nbsp; &nbsp; , 100 - (CAST(C.row_count AS decimal(38, 10)) / (CASE PS.row_count WHEN 0 THEN 1 ELSE PS.row_count END)) * 100 AS row_count_gap <br />
&nbsp; &nbsp; &nbsp; &nbsp; , C.last_update <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;CTE AS C <br />
&nbsp; &nbsp; CROSS JOIN &nbsp;sys.dm_db_partition_stats AS PS <br />
&nbsp; &nbsp; WHERE &nbsp; &nbsp;(@table_or_view_name IS NULL OR PS.object_id = OBJECT_ID(@table_or_view_name)) <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;PS.index_id BETWEEN 0 AND 1 <br />
&nbsp; ) <br />
SELECT &nbsp; &nbsp;@table_or_view_name AS table_or_view_name <br />
&nbsp; &nbsp; , CF.data_MB <br />
&nbsp; &nbsp; , CF.last_update <br />
&nbsp; &nbsp; , CF.density <br />
&nbsp; &nbsp; , CF.stat_name <br />
&nbsp; &nbsp; , LEFT(SC.stat_column_list, LEN(SC.stat_column_list) - 1) AS stat_column_list <br />
&nbsp; &nbsp; , CF.filter_definition <br />
&nbsp; &nbsp; , CF.stat_row_count <br />
&nbsp; &nbsp; , CF.real_row_count &nbsp;<br />
&nbsp; &nbsp; , CF.rows_sampled <br />
&nbsp; &nbsp; , CF.steps <br />
&nbsp; &nbsp; , CF.rowmodctr <br />
&nbsp; &nbsp; , CF.stat_recompute_threshold AS SRT <br />
&nbsp; &nbsp; , CF.stat_sample_rate <br />
&nbsp; &nbsp; , CF.real_sample_rate <br />
&nbsp; &nbsp; , CF.stat_change_rate <br />
&nbsp; &nbsp; , CF.real_change_rate <br />
&nbsp; &nbsp; , CF.row_count_gap <br />
FROM &nbsp; &nbsp;CTE_FINAL AS CF <br />
CROSS APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;C.name + ',' <br />
&nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.stats AS S <br />
&nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.stats_columns AS SC <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON S.object_id = SC.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND S.stats_id = SC.stats_id <br />
&nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.columns AS C <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON C.object_id = SC.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND C.column_id = SC.column_id <br />
&nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;CF.stat_name = S.name <br />
&nbsp; &nbsp; &nbsp; ORDER BY &nbsp;SC.stats_column_id <br />
&nbsp; &nbsp; &nbsp; FOR XML PATH ('') <br />
&nbsp; &nbsp; ) AS SC (stat_column_list) <br />
ORDER BY &nbsp;auto_created, stat_name</div></td></tr></tbody></table></div>
<p>On peut ensuite voir plus en détails ce qui a été échantillonné, à l&rsquo;aide de l&rsquo;instruction <a href="http://msdn.microsoft.com/fr-fr/library/ms174384.aspx">DBCC SHOW_STATISTICS</a> (maTable, maStatistique).</p>
<p>Cela aide souvent à comprendre pourquoi l&rsquo;optimiseur a choisi un index plutôt qu&rsquo;un autre <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p>Bonne optimisation !</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>Différence entre un index ordonné en cluster et un index non-cluster</title>
		<link>https://blog.developpez.com/elsuket/p7628/moteur-de-base-de-donnees-sql-server/difference_entre_un_index_ordonne_en_clu</link>
		<comments>https://blog.developpez.com/elsuket/p7628/moteur-de-base-de-donnees-sql-server/difference_entre_un_index_ordonne_en_clu#comments</comments>
		<pubDate>Tue, 19 May 2009 22:22:11 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Nous utilisons tous les jours de nombreux indexes : heure, calendrier, annuaire, sommaire et index d&#8217;un livre, &#8230; Passons aux bases de données : quelle est la différence entre un index cluster et un index non-cluster ? Si la différence &#8230; <a href="https://blog.developpez.com/elsuket/p7628/moteur-de-base-de-donnees-sql-server/difference_entre_un_index_ordonne_en_clu">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Nous utilisons tous les jours de nombreux indexes : heure, calendrier, annuaire, sommaire et index d&rsquo;un livre, &#8230;</p>
<p>Passons aux bases de données : quelle est la différence entre un index cluster et un index non-cluster ?<br />
Si la différence peut sembler obscure de prime abord, le choix des index est crucial pour la performance globale de la base de données, et de coût quasiment nul en terme de modifications à apporter au schéma de celle-ci.</p>
<p>Les deux types d&rsquo;index sont-ils complémentaires ? Quelles sont les conséquences du choix de la clé de ceux-ci ?</p>
<p><span id="more-78"></span></p>
<p>Rappelons d&rsquo;abord la différence entre les deux types d&rsquo;indexes :</p>
<p>=> Dans un <strong>index cluster</strong>, les niveaux intermédiaires de l&rsquo;arbre de tri contiennent les valeurs de la clé (et un RowID), selon l&rsquo;ordre physique de celle-ci, et seul le niveau feuille de l&rsquo;index contient les pages de données de la table.</p>
<p>En ce sens :</p>
<p>&#8211; il ne peut y avoir qu&rsquo;un seul index cluster par table,<br />
&#8211; un index cluster est plus sujet aux splits de page (mais on peut les éviter en spécifiant la colonne comme auto-incrémentée),<br />
&#8211; un index cluster est un doublon de la table,<br />
&#8211; une analogie en est l&rsquo;index que vous trouvez au début d&rsquo;un livre : il montre de quelle façon est organisé le livre dans l&rsquo;ordre physique des pages de celui-ci.</p>
<p>Sous SQL Server, les indexes cluster sont créés :</p>
<p>&#8211; implicitement lors de la spécification de la clé primaire de la table,<br />
&#8211; lors de l&rsquo;ajout d&rsquo;une contrainte d&rsquo;unicité spécifiant CLUSTERED (si la table ne comporte pas déjà de clé primaire).</p>
<p>=> Un <strong>index non-cluster</strong> est ordonné suivant l&rsquo;ordre logique des valeurs de sa clé (et un keyID), et son niveau feuille ne contient pas les pages de données, mais les lignes de l&rsquo;index cluster.</p>
<p>En ce sens :</p>
<p>&#8211; il peut y avoir plusieurs indexes non-cluster sur une table,<br />
&#8211; un index non-cluster est moins sujet aux splits de page,<br />
&#8211; une analogie en est l&rsquo;index que vous trouvez à a fin d&rsquo;un livre : il est ordonné suivant les titres des sujets qui sont traités, mais il référence la clé physique du livre : les numéros de page.</p>
<p>Sous SQL Server, tous les indexes sont implicitement créés non-cluster, à l&rsquo;exception des indexes de clé primaire.</p>
<p>Dès lors, on comprend que le choix de la clé de l&rsquo;index cluster d&rsquo;une table est très important, puisqu&rsquo;il influe sur la qualité des indexes non-cluster qui seront posés sur la même table.</p>
<p>Le choix des indexes reste complexe et à réaliser avec parcimonie, parce qu&rsquo;il est difficile de trouver le parfait arbitrage entre les performances des requêtes et le coût de mise à jour de ceux-ci.<br />
Pour la préservation des performances générales d&rsquo;une base de données, leur maintenance et un audit sur leur qualité et leur <a href="http://blog.developpez.com/elsuket/p6345/indexation/title-107/#more6345">absence</a> doit être régulièrement effectué.</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quelles sont les requêtes et tâches en cours d&#8217;exécution dans une instance SQL Server ?</title>
		<link>https://blog.developpez.com/elsuket/p9047/moteur-de-base-de-donnees-sql-server/requetes_et_taches_cours_execution</link>
		<comments>https://blog.developpez.com/elsuket/p9047/moteur-de-base-de-donnees-sql-server/requetes_et_taches_cours_execution#comments</comments>
		<pubDate>Fri, 25 Jun 2010 05:08:40 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une requête basée sur les vues et fonctions de gestion dynamiques, introduites avec SQL Server 2005. Elle permet de lister l&#8217;ensemble des requêtes actuellement en cours d&#8217;exécution dans une instance SQL Server, avec quelques statistiques et caractéristiques : &#8211; &#8230; <a href="https://blog.developpez.com/elsuket/p9047/moteur-de-base-de-donnees-sql-server/requetes_et_taches_cours_execution">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une requête basée sur les vues et fonctions de gestion dynamiques, introduites avec SQL Server 2005.</p>
<p>Elle permet de lister l&rsquo;ensemble des requêtes actuellement en cours d&rsquo;exécution dans une instance SQL Server, avec quelques statistiques et caractéristiques :</p>
<p>&#8211; le n° de session (SPID),<br />
&#8211; le nombre de threads mis en place pour résoudre la requête,<br />
&#8211; le nom du serveur,<br />
&#8211; le nom du login,<br />
&#8211; le <a href="http://blog.developpez.com/elsuket/p8122/moteur-de-base-de-donnees-sql-server/connaitre-le-pourcentage-d-avancement-d--2008/">pourcentage</a> d&rsquo;avancement d&rsquo;une instruction,<br />
&#8211; le nom de la base de données,<br />
&#8211; le statut de la session,<br />
&#8211; le temps écoulé depuis le début de l&rsquo;exécution,<br />
&#8211; le temps CPU consommé,<br />
&#8211; le nombre de lectures et d&rsquo;écritures,<br />
&#8211; le type d&rsquo;instruction,<br />
&#8211; le nombre de transactions ouvertes par la session,<br />
&#8211; le nombre de resultsets,<br />
&#8211; le type d&rsquo;attente,<br />
&#8211; le temps d&rsquo;attente pour ce type,<br />
&#8211; le type d&rsquo;attente précédent,<br />
&#8211; la ressource attendue,<br />
&#8211; le nom du programme / job qui exécute la requête,<br />
&#8211; l&rsquo;instruction SQL en cours d&rsquo;exécution dans le lot,<br />
&#8211; le lot SQL complet,<br />
&#8211; le plan de requête,<br />
&#8211; les hashs de requête et de plan,<br />
&#8211; le nombre d&rsquo;exécutions du plan,<br />
&#8211; la date de génération du plan,<br />
&#8211; l&rsquo;adresse IP de la machine exécutant la requête.</p>
<p>Toute suggestion est la bienvenue !</p>
<p><span id="more-102"></span></p>
<p><strong>Mise à jour du 13/05/2011</strong></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 /></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 - 13/05/2011 <br />
------------------------------- <br />
SET NOCOUNT ON <br />
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED <br />
&nbsp;<br />
;WITH <br />
&nbsp; CTE AS <br />
&nbsp; ( &nbsp;<br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;CASE ES.login_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'NT AUTHORITY\SYSTEM' THEN CASE &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN ES.program_name LIKE 'SQLAgent%' THEN 'SQLAgent' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE ES.program_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE ES.login_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; END AS Login <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ES.session_id AS SPID <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.blocking_session_id AS BlkBy <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.wait_type <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.wait_time <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.last_wait_type <br />
&nbsp; &nbsp; &nbsp; &nbsp; , COUNT(*) AS Threads <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CAST(ER.percent_complete AS NUMERIC(5,2)) AS percent_complete <br />
&nbsp; &nbsp; &nbsp; &nbsp; , DB_NAME(ER.database_id) AS DB <br />
&nbsp; &nbsp; &nbsp; &nbsp; , UPPER(ER.command) AS Command <br />
&nbsp; &nbsp; &nbsp; &nbsp; , UPPER(ER.status) AS Status <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4))) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4)) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4)) <br />
&nbsp; &nbsp; &nbsp; &nbsp; END + ':' + <br />
&nbsp; &nbsp; &nbsp; &nbsp; CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2))) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; &nbsp; &nbsp; END + ':' + &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2))) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; &nbsp; &nbsp; END AS Launched <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.cpu_time / 1000 AS CPU <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.reads AS Reads <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.writes AS Writes <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.open_transaction_count AS NbTran <br />
&nbsp; &nbsp; &nbsp; &nbsp; , SUBSTRING <br />
&nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ESQLT.text, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ER.statement_start_offset / 2 + 1, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN ER.statement_end_offset = - 1 THEN LEN(CAST(ESQLT.text AS nvarchar(max))) * 2 &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE ER.statement_end_offset &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END - ER.statement_start_offset <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) / 2 + 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS StatementInBatch <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ESQLT.text AS Batch <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN ER.command = 'UPDATE STATISTIC' THEN 'Updating stats on ' + REPLACE(REPLACE(SUBSTRING(ESQLT.text, CHARINDEX('[dbo]', ESQLT.text), CHARINDEX(' ', ESQLT.text, CHARINDEX('[dbo]', ESQLT.text)) - &nbsp;CHARINDEX('[dbo]', ESQLT.text)), '[', ''), ']', '') <br />
&nbsp; &nbsp; &nbsp; &nbsp; END AS info <br />
&nbsp; &nbsp; &nbsp; &nbsp; , CASE &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN ES.program_name LIKE 'SQLAgent - TSQL JobStep%' THEN 'Job : ' + J.name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN ES.program_name LIKE 'Microsoft SQL Server Management Studio%' THEN 'SSMS' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN ES.program_name LIKE 'LiteSpeed for SQL Server%' THEN 'LiteSpeed' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN ES.program_name = 'Microsoft SQL Server Analysis Services' THEN 'SSAS' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE ES.program_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; END AS Program <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ES.host_name AS Host <br />
&nbsp; &nbsp; &nbsp; &nbsp; , EC.client_net_address AS IP <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.plan_handle <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;sys.dm_exec_sessions ES (nolock) <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.dm_exec_connections (nolock) EC &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON ES.session_id = EC.session_id <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.dm_exec_requests ER (nolock) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON ES.session_id = ER.session_id <br />
&nbsp; &nbsp; LEFT JOIN &nbsp;msdb.dbo.sysjobs J (nolock) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON REPLACE(SUBSTRING(CAST(J.job_id AS char(36)), CHARINDEX('-', J.job_id, 18) + 1, LEN(J.job_id)), '-', '') = <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RIGHT(LEFT(REPLACE(ES.program_name, 'SQLAgent - TSQL JobStep (Job 0x', ''), 32), 16) <br />
&nbsp; &nbsp; CROSS APPLY &nbsp;sys.dm_exec_sql_text(ER.sql_handle) ESQLT <br />
&nbsp; &nbsp; WHERE &nbsp; &nbsp;ES.session_id &lt;&gt; @@SPID <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;ES.is_user_process = 1 <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;(J.name NOT LIKE 'cdc%' OR J.name IS NULL) <br />
&nbsp; &nbsp; AND &nbsp; &nbsp;ES.is_user_process = 1 <br />
&nbsp; &nbsp; GROUP BY &nbsp;ES.session_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.blocking_session_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ES.host_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ES.login_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.percent_complete <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.database_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.status <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.start_time <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.cpu_time <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.reads <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.writes <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.command <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.open_transaction_count <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.statement_start_offset <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.statement_end_offset <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ESQLT.text <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.wait_type <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.wait_time <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.last_wait_type <br />
&nbsp; &nbsp; &nbsp; &nbsp; , J.name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ES.program_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , EC.client_net_address <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ER.plan_handle <br />
&nbsp; ) <br />
SELECT &nbsp; &nbsp;C.Login <br />
&nbsp; &nbsp; , C.SPID <br />
&nbsp; &nbsp; , C.BlkBy <br />
&nbsp; &nbsp; , C.wait_type <br />
&nbsp; &nbsp; , C.wait_time <br />
&nbsp; &nbsp; , C.last_wait_type <br />
&nbsp; &nbsp; , C.Threads <br />
&nbsp; &nbsp; , C.percent_complete AS [%] <br />
&nbsp; &nbsp; , C.DB <br />
&nbsp; &nbsp; , C.Command <br />
&nbsp; &nbsp; , C.Status <br />
&nbsp; &nbsp; , C.Launched <br />
&nbsp; &nbsp; , C.CPU <br />
&nbsp; &nbsp; , C.Reads <br />
&nbsp; &nbsp; , C.Writes <br />
&nbsp; &nbsp; , C.NbTran <br />
&nbsp; &nbsp; , C.StatementInBatch <br />
&nbsp; &nbsp; , C.Batch <br />
&nbsp; &nbsp; , C.info <br />
&nbsp; &nbsp; , C.Program <br />
&nbsp; &nbsp; , C.Host <br />
&nbsp; &nbsp; , C.IP <br />
&nbsp; &nbsp; , C.plan_handle <br />
FROM &nbsp; &nbsp;CTE AS C <br />
ORDER BY &nbsp;C.SPID</div></td></tr></tbody></table></div>
<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 /></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 - 25/06/2010 <br />
------------------------------- <br />
SET NOCOUNT ON <br />
&nbsp;<br />
;WITH <br />
&nbsp; CTE_THREADS AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;session_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , COUNT(*) AS nbThreads <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;sys.dm_exec_sessions <br />
&nbsp; &nbsp; GROUP BY &nbsp;session_id <br />
&nbsp; ) <br />
SELECT &nbsp; &nbsp;ES.session_id SPID <br />
&nbsp; &nbsp; , CT.nbThreads <br />
&nbsp; &nbsp; , ER.blocking_session_id BlkBy <br />
&nbsp; &nbsp; , ES.host_name AS Host <br />
&nbsp; &nbsp; , CASE ES.login_name <br />
&nbsp; &nbsp; &nbsp; WHEN 'NT AUTHORITY\SYSTEM' THEN CASE &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN ES.program_name LIKE 'SQLAgent%' THEN 'SQLAgent' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE ES.program_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; ELSE ES.login_name <br />
&nbsp; &nbsp; END AS Login <br />
&nbsp; &nbsp; , CAST(ER.percent_complete AS NUMERIC(5,2)) AS [%] <br />
&nbsp; &nbsp; , DB_NAME(ER.database_id) AS DB <br />
&nbsp; &nbsp; , UPPER(ER.status) AS Status <br />
&nbsp; &nbsp; , CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4))) <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4)) <br />
&nbsp; &nbsp; &nbsp; ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 3600 AS VARCHAR(4)) <br />
&nbsp; &nbsp; END + ':' + <br />
&nbsp; &nbsp; CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2))) <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; &nbsp; ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) / 60 % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; END + ':' + &nbsp;<br />
&nbsp; &nbsp; CASE LEN(CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2))) <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN '0' + CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; &nbsp; ELSE CAST(DATEDIFF(second, ER.start_time, GETDATE()) % 60 AS VARCHAR(2)) <br />
&nbsp; &nbsp; END AS Launched <br />
&nbsp; &nbsp; , ER.cpu_time / 1000 AS CPU <br />
&nbsp; &nbsp; , ER.reads AS Reads <br />
&nbsp; &nbsp; , ER.writes AS Writes <br />
&nbsp; &nbsp; , UPPER(ER.command) AS Command <br />
&nbsp; &nbsp; , ER.open_transaction_count NbTran <br />
&nbsp; &nbsp; , ER.open_resultset_count AS NbRsltSet <br />
&nbsp; &nbsp; , ER.wait_type <br />
&nbsp; &nbsp; , ER.wait_time <br />
&nbsp; &nbsp; , ER.last_wait_type <br />
&nbsp; &nbsp; , ER.wait_resource <br />
&nbsp; &nbsp; , CASE <br />
&nbsp; &nbsp; &nbsp; WHEN ES.program_name LIKE 'SQLAgent - TSQL JobStep%' THEN 'Job : ' + J.name <br />
&nbsp; &nbsp; &nbsp; WHEN ES.program_name LIKE 'Microsoft SQL Server Management Studio%' THEN 'SQL Qry' <br />
&nbsp; &nbsp; &nbsp; ELSE ES.program_name <br />
&nbsp; &nbsp; END AS Program <br />
&nbsp; &nbsp; , SUBSTRING( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ESQLT.text, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ER.statement_start_offset / 2 + 1, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN ER.statement_end_offset = - 1 THEN LEN(CAST(ESQLT.text AS nvarchar(max))) * 2 &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE ER.statement_end_offset &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END - ER.statement_start_offset <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) / 2 <br />
&nbsp; &nbsp; ) AS StatementInBatch <br />
&nbsp; &nbsp; , ESQLT.text AS Batch <br />
&nbsp; &nbsp; , QP.query_plan <br />
&nbsp; &nbsp; , ER.query_hash &nbsp;<br />
&nbsp; &nbsp; , ER.query_plan_hash <br />
&nbsp; &nbsp; , QS.execution_count <br />
&nbsp; &nbsp; , QS.creation_time <br />
&nbsp; &nbsp; , EC.client_net_address AS IP <br />
FROM &nbsp; &nbsp;sys.dm_exec_sessions ES (nolock) <br />
INNER JOIN &nbsp;sys.dm_exec_connections (nolock) EC &nbsp;<br />
&nbsp; &nbsp; &nbsp; ON ES.session_id = EC.session_id <br />
INNER JOIN &nbsp;sys.dm_exec_requests ER (nolock) <br />
&nbsp; &nbsp; &nbsp; ON ES.session_id = ER.session_id <br />
INNER JOIN &nbsp;CTE_THREADS AS CT <br />
&nbsp; &nbsp; &nbsp; ON ES.session_id = CT.session_id <br />
LEFT JOIN &nbsp;msdb.dbo.sysjobs J (nolock) <br />
&nbsp; &nbsp; &nbsp; ON REPLACE(SUBSTRING(CAST(J.job_id AS CHAR(36)), CHARINDEX('-', J.job_id, 18) + 1, LEN(J.job_id)), '-', '') = <br />
&nbsp; &nbsp; &nbsp; &nbsp; RIGHT(LEFT(REPLACE(ES.program_name, 'SQLAgent - TSQL JobStep (Job 0x', ''), 32), 16) <br />
CROSS APPLY &nbsp;sys.dm_exec_sql_text(ER.sql_handle) ESQLT <br />
OUTER APPLY &nbsp;sys.dm_exec_query_plan (ER.plan_handle) AS QP <br />
LEFT JOIN &nbsp;sys.dm_exec_query_stats AS QS <br />
&nbsp; &nbsp; &nbsp; ON ER.plan_handle = QS.plan_handle <br />
WHERE &nbsp; &nbsp;ES.session_id &lt;&gt; @@SPID <br />
AND &nbsp; &nbsp;(J.name IS NULL OR J.name NOT LIKE 'cdc.%') <br />
ORDER BY &nbsp;ES.session_id</div></td></tr></tbody></table></div>
<p>ElSüket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Utilisation des variables de type table ou des tables temporaires, et performances</title>
		<link>https://blog.developpez.com/elsuket/p7739/moteur-de-base-de-donnees-sql-server/variable_table_temporaire_performance</link>
		<comments>https://blog.developpez.com/elsuket/p7739/moteur-de-base-de-donnees-sql-server/variable_table_temporaire_performance#comments</comments>
		<pubDate>Sat, 13 Jun 2009 18:55:43 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voilà deux types de tables souvent utilisées mais mal maîtrisées, surtout au regard des performances qu&#8217;elles offrent, qui ne sont pas très bonnes. Voyons pourquoi &#8230; SQL Server permet de stocker dans des variables table ou des tables temporaires (locales &#8230; <a href="https://blog.developpez.com/elsuket/p7739/moteur-de-base-de-donnees-sql-server/variable_table_temporaire_performance">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voilà deux types de tables souvent utilisées mais mal maîtrisées, surtout au regard des performances qu&rsquo;elles offrent, qui ne sont pas très bonnes.<br />
Voyons pourquoi &#8230;</p>
<p><span id="more-80"></span></p>
<p>SQL Server permet de stocker dans des variables table ou des tables temporaires (locales à la session ou globales à l&rsquo;instance) des données.</p>
<p><strong>Pour déclarer une variable table</strong>, il suffit d&rsquo;écrire, par exemple :</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 /></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 - 13/06/2009 - <br />
--------------------------------- <br />
DECLARE @Tb TABLE <br />
( <br />
&nbsp; uneColonne INT <br />
)</div></td></tr></tbody></table></div>
<p>=> Avantages : comme toute variable, elle est détruite dès la fin de la session utilisateur<br />
=> Inconvénients : elle n&rsquo;est pas indexable comme une table, et aucune statistique n&rsquo;est maintenue sur les colonnes.</p>
<p><strong>Pour créer une table temporaire locale à la session</strong>, il suffit d&rsquo;écrire, par exemple :</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 /></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 - 13/06/2009 - <br />
--------------------------------- <br />
CREATE TABLE #Tb <br />
( <br />
&nbsp; uneColonne VARCHAR(50) <br />
)</div></td></tr></tbody></table></div>
<p>et pour créer une une table temporaire globale à l&rsquo;instance SQL Server, il suffit d&rsquo;écrire, par exemple :</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">CREATE TABLE ##Tb <br />
( <br />
&nbsp; uneColonne VARCHAR(50) <br />
)</div></td></tr></tbody></table></div>
<p>=> Avantages : des statistiques sont maintenues sur les colonnes, qui sont de plus indexables<br />
=> Inconvénients : il est préférable de supprimer la table à la fin de la session, même si elle est automatiquement détruite lors de la fin de celle-ci.</p>
<p>Si vous pensiez que ces tables sont stockées uniquement dans la RAM du serveur, vous avez fait fausse route, car comme toute table, le moteur de base de données se doit de les persister.<br />
Néanmoins les pages que contiennent ces tables demeurent dans le cache de données.</p>
<p>Alors, où sont persistées ces tables ?</p>
<p><img src="http://blog.developpez.com/media/tableVariable.PNG" width="895" height="608" alt="" /></p>
<p><strong>Voici le code commenté :</strong></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 /></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 - 13/06/2009 - <br />
--------------------------------- <br />
&nbsp;<br />
DECLARE @Tb &nbsp;TABLE <br />
( <br />
&nbsp; uneColonne INT <br />
) <br />
&nbsp;<br />
-- Récupération de la structure de la variable table <br />
SELECT T.name AS nomTable, <br />
&nbsp; &nbsp; C.name AS nomColonne <br />
FROM TempDB.sys.columns AS C <br />
JOIN TempDB.sys.tables AS T ON C.object_id = T.object_id</div></td></tr></tbody></table></div>
<p>Comme vous pouvez le voir, SQL Server n&rsquo;attribue pas le nom de votre table, mais une suite d&rsquo;hexadécimaux.<br />
Cela permet de garantir que deux sessions qui ont des variables tables qui portent le même nom n&rsquo;utilisent pas les mêmes données. </p>
<p>En effet si nous exécutons :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">DECLARE @Tb1 TABLE &nbsp;<br />
( &nbsp;<br />
&nbsp; uneColonne1 INT &nbsp;<br />
) &nbsp;<br />
&nbsp;<br />
DECLARE @Tb2 TABLE &nbsp;<br />
( &nbsp;<br />
&nbsp; uneColonne2 INT &nbsp;<br />
) &nbsp;<br />
&nbsp;<br />
SELECT T.name AS nomTable, &nbsp;<br />
&nbsp; &nbsp; C.name AS nomColonne &nbsp;<br />
FROM TempDB.sys.columns AS C &nbsp;<br />
JOIN TempDB.sys.tables AS T ON C.object_id = T.object_id &nbsp;<br />
&nbsp;<br />
WAITFOR DELAY '00:00:05'</div></td></tr></tbody></table></div>
<p>Nous obtenons :</p>
<p><img src="http://blog.developpez.com/media/tableVariable2.PNG" width="841" height="493" alt="" /></p>
<p>Et si nous tentons d&rsquo;afficher la structure de ces tables, dans l&rsquo;explorateur d&rsquo;objets, on obtient le message d&rsquo;erreur suivant :</p>
<p><img src="http://blog.developpez.com/media/tableVariableErreur.PNG" width="611" height="131" alt="" /></p>
<p>Il en va quelque peut différement pour les tables temporaires locales à la session.<br />
Si nous exécutons :</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 /></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 - 13/06/2009 - <br />
--------------------------------- <br />
CREATE TABLE #TEST <br />
( <br />
&nbsp; uneColonne INT <br />
) <br />
&nbsp;<br />
SELECT T.name AS nomTable, <br />
&nbsp; &nbsp; C.name AS nomColonne <br />
FROM TempDB.sys.columns AS C <br />
JOIN TempDB.sys.tables AS T ON C.object_id = T.object_id</div></td></tr></tbody></table></div>
<p>Nous obtenons :</p>
<blockquote><pre>
nomTable			nomColonne
------------------------------------------
#TEST___...___000000000003	uneColonne
</pre>
</blockquote>
<p>où les points de suspension remplacent un grand nombre d&rsquo;underscores.</p>
<p>Un &laquo;&nbsp;numéro&nbsp;&raquo; est ainsi attribué à chaque table temporaire locale créée, pour les mêmes raisons que vous la variable table :<br />
cela permet de garantir que deux sessions qui ont des tables tmeporaires locales qui portent le même nom n&rsquo;utilisent pas les mêmes données.</p>
<p>Enfin, voyons ce qui se passe pour une table temporaire globale :</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 /></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 - 13/06/2009 - <br />
--------------------------------- <br />
CREATE TABLE ##TEST <br />
( <br />
&nbsp; uneColonne INT <br />
) <br />
&nbsp;<br />
SELECT T.name AS nomTable, <br />
&nbsp; &nbsp; C.name AS nomColonne <br />
FROM TempDB.sys.columns AS C <br />
JOIN TempDB.sys.tables AS T ON C.object_id = T.object_id</div></td></tr></tbody></table></div>
<p>Nous obtenons le résultat suivant :</p>
<p><img src="http://blog.developpez.com/media/tableTemporaireGlobale.PNG" width="836" height="382" alt="" /></p>
<p>Là, le nom de la table est celui que l&rsquo;on a donné dans la requête. Il est dès lors impossible de créer une table temporaire globale portant le même nom : ouvrons une autre session et exécutons :</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 /></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 - 13/06/2009 - <br />
--------------------------------- <br />
CREATE TABLE ##TEST <br />
( <br />
&nbsp; uneColonne INT <br />
)</div></td></tr></tbody></table></div>
<p>La console de SSMS affiche alors :</p>
<blockquote><p>Msg 2714, Niveau 16, État 6, Ligne 1<br />
Il existe déjà un objet nommé &lsquo;##TEST&rsquo; dans la base de données.</p></blockquote>
<p><strong>Passons maintenant aux performances</strong> : pourquoi le fait d&rsquo;utiliser une variable table ou une table temporaire est-il contre-performant ?</p>
<p>=> Les variables table et les tables temporaires étant des tables, elles doivent être persistées pour respecter l&rsquo;ACIDité de la transaction qui les requiert. Dès lors on duplique des données qui existent déjà &#8230;</p>
<p>=> Les variables table et les tables temporaires sont stockées dans TempDB, qui joue un rôle majeur dans le fonctionnement de SQL Server, notamment pour les travaux de jointure et d&rsquo;aggrégation, les magasins de version (SQL Server 2005 et ultérieur), et de nombreuses tâches que le moteur de base de données effectue en arrière plan</p>
<p>=> En plus des opérations que le moteur de bases de données effectue en RAM, il doit effectuer des opérations sur disque pour persister les données (enregistrement des données dans les pages de TempDB et dans le fichier du journal des transactions). Un accès disque étant en moyenne 1000 fois plus lent qu&rsquo;un accès en RAM, &#8230;</p>
<p>=> En peuplant une variable table ou une table temporaire, on oblige le moteur de base de données à stocker deux fois en RAM les données, ce qui rend donc le cache de données moins performant, surtout dans le cas où ce type de table a un cardinal élevé. Imaginez ce que cela peut faire si plusieurs utilisateurs exécutent très souvent une procédure stockée qui requiert une variable table &#8230;</p>
<p>=> Le moteur de base de données ne maintient pas de statistiques de colonne pour les variable table; en conséquence, un plan de requête efficace ne peut pas être trouvé.</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Une macro Excel pour dépouiller les statistiques IO</title>
		<link>https://blog.developpez.com/elsuket/p9942/moteur-de-base-de-donnees-sql-server/macro_excel_pour_depouiller_les_stat</link>
		<comments>https://blog.developpez.com/elsuket/p9942/moteur-de-base-de-donnees-sql-server/macro_excel_pour_depouiller_les_stat#comments</comments>
		<pubDate>Wed, 04 May 2011 07:05:25 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[L&#8217;option de session SET STATISTICS IO ON permet de révéler la quantité d&#8217;activité générée sur les disques par une requête. Comme je dépouille assez souvent le résultat qui s&#8217;affiche dans la console de SQL Server Management Studio, j&#8217;en suis venu &#8230; <a href="https://blog.developpez.com/elsuket/p9942/moteur-de-base-de-donnees-sql-server/macro_excel_pour_depouiller_les_stat">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>L&rsquo;option de session SET STATISTICS IO ON permet de révéler la quantité d&rsquo;activité générée sur les disques par une requête.<br />
Comme je dépouille assez souvent le résultat qui s&rsquo;affiche dans la console de SQL Server Management Studio, j&rsquo;en suis venu à écrire une macro qui fait ce travail pour moi en un clin d’œil <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p><span id="more-134"></span></p>
<p>Lorsque j&rsquo;ai trouvé une requête dont je sais que l&rsquo;activité disque est importante, je cherche à savoir pourquoi c&rsquo;est le cas.<br />
Je dois parfois ré-exécuter la requête sur le système pour comprendre ce que fait le moteur de base de données, et analyser quelles sont les tables qui subissent le plus de lectures.</p>
<p>Si l&rsquo;on s&rsquo;en tient à ce que propose SQL Server Management Studio, on obtient :</p>
<p><img src="http://blog.developpez.com/media/stats_io_0.png" width="1188" height="279" alt="" /></p>
<p>Il se peut que la requête contient un grand nombre de tables, et dans ce cas la lecture ce ce résultat peut être longue, surtout si l&rsquo;on fait du tuning à longueur de journée <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /><br />
J&rsquo;ai donc créé la <a href="http://cid-7b2c2e997eda3aa2.office.live.com/self.aspx/.Public/IO%20Stats%20Parser.zip">feuille Excel</a> que vous trouverez compressée.</p>
<p>Il suffit de copier le résultat affiché dans la console dans cette feuille, et d&rsquo;exécuter la macro.<br />
Dans le ruban d&rsquo;Office 2007 ou 2010, après avoir sélectionné <em>View</em>, on peut voir les macros en cliquant sur le bouton du même nom :</p>
<p><img src="http://blog.developpez.com/media/stats_io_1.png" width="1135" height="164" alt="" /></p>
<p>La fenêtre suivante s&rsquo;affiche :</p>
<p><img src="http://blog.developpez.com/media/stats_io_2.png" width="383" height="368" alt="" /></p>
<p>Et il suffit de cliquer sur <em>&laquo;&nbsp;Run&nbsp;&raquo;</em>. Le résultat obtenu pour la même requête est alors :</p>
<p><img src="http://blog.developpez.com/media/stats_io_3.png" width="418" height="450" alt="" /></p>
<p>Bon tuning !</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>Trouver les derniers grossissements automatiques de fichiers</title>
		<link>https://blog.developpez.com/elsuket/p9847/moteur-de-base-de-donnees-sql-server/trouver_les_derniers_grossissements_auto</link>
		<comments>https://blog.developpez.com/elsuket/p9847/moteur-de-base-de-donnees-sql-server/trouver_les_derniers_grossissements_auto#comments</comments>
		<pubDate>Wed, 30 Mar 2011 05:44:12 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[La trace SQL Profiler par défaut permet de retrouver les grossissements automatiques des fichiers de toutes les bases de données hébergées par une instance SQL Server. Voyons comment retrouver ces événements : De nombreux grossissements automatiques des fichiers de la &#8230; <a href="https://blog.developpez.com/elsuket/p9847/moteur-de-base-de-donnees-sql-server/trouver_les_derniers_grossissements_auto">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>La trace SQL Profiler par défaut permet de retrouver les grossissements automatiques des fichiers de toutes les bases de données hébergées par une instance SQL Server.</p>
<p>Voyons comment retrouver ces événements :</p>
<p><span id="more-108"></span></p>
<p>De nombreux grossissements automatiques des fichiers de la base de données peuvent indiquer :</p>
<p>&#8211; que les fichiers de la base de données ont été mal taillés lors de la création de la base de données<br />
&#8211; que l&rsquo;incrément choisi pour le grossissement automatique est trop faible (par défaut c&rsquo;est 1MB pour un fichier de données !)<br />
&#8211; que des transactions (comme des recréations d&rsquo;index), ou un changement d&rsquo;un module SQL ou dans l&rsquo;application supportée par la base de données génèrent beaucoup de données, et envisager des corrections.</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 - 30/03/2011 <br />
------------------------------- <br />
-- Recherche de l'UNC du fichier de trace par défaut <br />
DECLARE &nbsp;@trace_file_path nvarchar(260) &nbsp;<br />
SELECT &nbsp;@trace_file_path = path <br />
FROM &nbsp;sys.traces <br />
WHERE &nbsp;id = 1 -- identifiant de la trace par défaut <br />
&nbsp;<br />
-- Extraction des données <br />
SELECT &nbsp;DatabaseName <br />
&nbsp; , FileName <br />
&nbsp; , HostName <br />
&nbsp; , ApplicationName <br />
&nbsp; , SessionLoginName <br />
&nbsp; , Duration <br />
&nbsp; , StartTime <br />
&nbsp; , EndTime <br />
FROM &nbsp;sys.fn_trace_gettable (@trace_file_path, DEFAULT) <br />
WHERE &nbsp;EventClass IN (92, 93) -- Evénements &quot;Data File Auto Grow&quot; et &quot;Log File Auto Grow&quot; <br />
--AND &nbsp;DatabaseName = DB_NAME() -- Pour retrouver les grossissements automatiques de fichiers pour la base de données courante</div></td></tr></tbody></table></div>
<p>On peut trouver la liste des événements et leur identifiant dans la documentation de la procédure stockée <a href="http://msdn.microsoft.com/fr-fr/library/ms186265.aspx">sp_trace_setevent</a>.</p>
<p>J&rsquo;ai utilisé cette procédure dans le tutoriel <a href="http://elsuket.developpez.com/tutoriels/sqlserveur/fichier-trace-cote-serveur/"><em>Création de fichiers de trace SQL Server Profiler côté serveur</em></a></p>
<p>On pourra <a href="http://blog.developpez.com/elsuket/p8540/moteur-de-base-de-donnees-sql-server/trouver-l-espace-disque-occupe-par-les-f/">trouver l&rsquo;espace disque occupé par les fichiers, et l&rsquo;espace libre dans ceux-ci</a>.</p>
<p>Bonne gestion de fichiers !</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>Générer le script de mise à jour des types de données de colonnes dont le type est déprécié</title>
		<link>https://blog.developpez.com/elsuket/p9824/moteur-de-base-de-donnees-sql-server/generer_le_scrirpt_de_mise_a_jour_des_ty</link>
		<comments>https://blog.developpez.com/elsuket/p9824/moteur-de-base-de-donnees-sql-server/generer_le_scrirpt_de_mise_a_jour_des_ty#comments</comments>
		<pubDate>Mon, 21 Mar 2011 12:26:36 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici plusieurs scripts qui permettent d&#8217;automatiser le changement de types de données dépréciés text, ntext et image depuis SQL Server 2005, qui les a respectivement remplacés par varchar(max), nvarchar(max), et varbinary(max), et a rendu les valeurs stockées sous de tels &#8230; <a href="https://blog.developpez.com/elsuket/p9824/moteur-de-base-de-donnees-sql-server/generer_le_scrirpt_de_mise_a_jour_des_ty">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici plusieurs scripts qui permettent d&rsquo;automatiser le changement de types de données dépréciés <em>text</em>, <em>ntext</em> et <em>image</em> depuis SQL Server 2005, qui les a respectivement remplacés par varchar(max), nvarchar(max), et varbinary(max), et a rendu les valeurs stockées sous de tels types bien plus malléables (utilisations de fonctions de chaîne notamment)<br />
<span id="more-94"></span></p>
<p>Si vous n&rsquo;avez qu&rsquo;un petit nombre de colonnes dont le type est déprécié, et/ou que toutes vos bases de données sont toute a la même version (si on a plusieurs clients par exemple, ce n&rsquo;est pas toujours le cas), 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;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 /></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 - 21-03-2011 <br />
------------------------------- <br />
SET NOCOUNT ON <br />
GO <br />
&nbsp;<br />
DECLARE @sql varchar(max) <br />
&nbsp; , @cr char(2) = CHAR(13) + CHAR(10) <br />
&nbsp; , @tab char(1) = CHAR(9) <br />
&nbsp;<br />
SELECT &nbsp; &nbsp;@sql = CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN @sql IS NULL THEN '-- Number of rows for ' + T.name + ' : ' + CAST(PS.row_count AS varchar(19)) + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + 'ALTER TABLE ' + T.name + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + 'ALTER COLUMN ' + C.name + ' ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE TY.name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'text' THEN 'varchar(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'ntext' THEN 'nvarchar(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'image' THEN 'varbinary(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE C.is_nullable <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN ' NULL' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 0 THEN ' NOT NULL' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; ELSE @sql + @cr + '-- Number of rows for ' + T.name + ' : ' + CAST(PS.row_count AS varchar(19)) + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + 'ALTER TABLE ' + T.name + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + 'ALTER COLUMN ' + C.name + ' ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE TY.name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'text' THEN 'varchar(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'ntext' THEN 'nvarchar(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'image' THEN 'varbinary(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE C.is_nullable <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN ' NULL' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 0 THEN ' NOT NULL' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; END + @cr + 'GO' + @cr <br />
FROM &nbsp; &nbsp;sys.schemas AS S <br />
INNER JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; ON S.schema_id = T.schema_id <br />
INNER JOIN &nbsp;sys.dm_db_partition_stats AS PS <br />
&nbsp; &nbsp; &nbsp; ON PS.object_id = T.object_id <br />
INNER JOIN &nbsp;sys.columns AS C &nbsp;<br />
&nbsp; &nbsp; &nbsp; ON C.object_id = T.object_id <br />
INNER JOIN &nbsp;sys.types AS TY <br />
&nbsp; &nbsp; &nbsp; ON TY.system_type_id = C.system_type_id <br />
&nbsp; &nbsp; &nbsp; AND TY.system_type_id = TY.user_type_id <br />
WHERE &nbsp; &nbsp;S.name = 'dbo' <br />
AND &nbsp; &nbsp;TY.name IN ('image', 'text', 'ntext') <br />
AND &nbsp; &nbsp;PS.index_id IN (0, 1) -- Heap or Clustered index <br />
ORDER BY &nbsp;T.name, C.column_id <br />
&nbsp;<br />
PRINT &nbsp;@sql</div></td></tr></tbody></table></div>
<p>Comme PRINT est limité à afficher seulement les 8000 premiers caractères d&rsquo;une chaîne, il se peut que le script que vous obtenez soit incomplet.<br />
Dans ce cas une boucle devient nécessaire, pour n&rsquo;afficher qu&rsquo;une instruction par colonne dont le type est à changer :</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 /></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 - 21-03-2011 <br />
------------------------------- <br />
DECLARE @tables_with_deprecated_type TABLE <br />
( <br />
&nbsp; table_name sysname <br />
&nbsp; , column_name sysname <br />
&nbsp; , column_data_type_name sysname <br />
&nbsp; , is_column_nullable bit <br />
&nbsp; , table_row_count bigint <br />
) <br />
&nbsp;<br />
INSERT &nbsp; &nbsp;@tables_with_deprecated_type <br />
SELECT &nbsp; &nbsp;T.name <br />
&nbsp; &nbsp; , C.name <br />
&nbsp; &nbsp; , TY.name <br />
&nbsp; &nbsp; , C.is_nullable <br />
&nbsp; &nbsp; , PS.row_count <br />
FROM &nbsp; &nbsp;sys.schemas AS S <br />
INNER JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; ON S.schema_id = T.schema_id <br />
INNER JOIN &nbsp;sys.dm_db_partition_stats AS PS <br />
&nbsp; &nbsp; &nbsp; ON PS.object_id = T.object_id <br />
INNER JOIN &nbsp;sys.columns AS C &nbsp;<br />
&nbsp; &nbsp; &nbsp; ON C.object_id = T.object_id <br />
INNER JOIN &nbsp;sys.types AS TY <br />
&nbsp; &nbsp; &nbsp; ON TY.system_type_id = C.system_type_id <br />
&nbsp; &nbsp; &nbsp; AND TY.system_type_id = TY.user_type_id <br />
WHERE &nbsp; &nbsp;S.name = 'dbo' <br />
AND &nbsp; &nbsp;TY.name IN ('image', 'text', 'ntext') <br />
AND &nbsp; &nbsp;PS.index_id IN (0, 1) -- Heap or Clustered index <br />
ORDER BY &nbsp;T.name, C.column_id <br />
&nbsp;<br />
DECLARE &nbsp;@table_name sysname <br />
&nbsp; , @column_name sysname <br />
&nbsp; , @column_data_type_name sysname <br />
&nbsp; , @is_column_nullable bit <br />
&nbsp; , @table_row_count bigint <br />
&nbsp; --- <br />
&nbsp; , @sql varchar(max) <br />
&nbsp; , @cr char(2) = CHAR(13) + CHAR(10) <br />
&nbsp; , @tab char(1) = CHAR(9) <br />
&nbsp;<br />
WHILE EXISTS <br />
( <br />
&nbsp; SELECT &nbsp;* <br />
&nbsp; FROM &nbsp;@tables_with_deprecated_type <br />
) <br />
BEGIN <br />
&nbsp; SELECT &nbsp;TOP (1) @table_name = table_name <br />
&nbsp; &nbsp; , @column_name = column_name <br />
&nbsp; &nbsp; , @column_data_type_name = column_data_type_name <br />
&nbsp; &nbsp; , @is_column_nullable = is_column_nullable <br />
&nbsp; &nbsp; , @table_row_count = table_row_count <br />
&nbsp; FROM &nbsp;@tables_with_deprecated_type <br />
&nbsp; <br />
&nbsp; SET &nbsp;@sql = '-- Number of rows for ' + @table_name + ' : ' + CAST(@table_row_count AS varchar(20)) + @cr <br />
&nbsp; &nbsp; + 'ALTER TABLE ' + @table_name + @cr <br />
&nbsp; &nbsp; + 'ALTER COLUMN ' + @column_name + ' ' <br />
&nbsp; &nbsp; + CASE @column_data_type_name <br />
&nbsp; &nbsp; &nbsp; WHEN 'text' THEN 'varchar(max)' <br />
&nbsp; &nbsp; &nbsp; WHEN 'ntext' THEN 'nvarchar(max)' <br />
&nbsp; &nbsp; &nbsp; WHEN 'image' THEN 'varbinary(max)' <br />
&nbsp; &nbsp; END <br />
&nbsp; &nbsp; + CASE @is_column_nullable <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN ' NULL' <br />
&nbsp; &nbsp; &nbsp; WHEN 0 THEN ' NOT NULL' <br />
&nbsp; &nbsp; END + @cr + 'GO' + @cr <br />
&nbsp; &nbsp; <br />
&nbsp; PRINT &nbsp;@sql <br />
&nbsp; <br />
&nbsp; DELETE &nbsp;TOP (1) @tables_with_deprecated_type <br />
END</div></td></tr></tbody></table></div>
<p>Si en revanche on cherche à créer un tel script pour des bases de données dont le schéma est à des stades d&rsquo;évolutions différents (par exemple si l&rsquo;on a des clients qui n&rsquo;utilisent pas tous la même version de l&rsquo;application, et donc de la base de données), on peut alors tester l&rsquo;existence de la colonne et de son type déprécié.<br />
Cela permet d&rsquo;utiliser le script généré sans ce soucier de l&rsquo;existence ou non de la colonne, et/ou de son type.</p>
<p>Comme précédemment, si l&rsquo;on a un petit nombre de colonnes, le script suivant fonctionne (le but étant de ne pas dépasser la limite des 8000 caractères retournés par PRINT, comme décrit plus haut) :</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 /></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 - 21-03-2011 <br />
------------------------------- <br />
DECLARE @sql varchar(max) <br />
&nbsp; , @cr char(2) = CHAR(13) + CHAR(10) <br />
&nbsp; , @tab char(1) = CHAR(9) <br />
&nbsp;<br />
SELECT &nbsp; &nbsp;@sql = CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN @sql IS NULL THEN '-- Number of rows for ' + T.name + ' : ' + CAST(PS.row_count AS varchar(50)) + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + 'IF EXISTS' + @cr + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + '(' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'SELECT' + @tab + @tab + '*' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'FROM' + @tab + @tab + 'sys.tables AS T' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'INNER JOIN' + @tab + 'sys.columns AS C ON T.object_id = C.object_id' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'INNER JOIN' + @tab + 'sys.types AS TY ON TY.system_type_id = C.system_type_id' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'WHERE' + @tab + @tab + 'T.name = ''' + T.name + '''' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'AND' + @tab + @tab + 'C.name = ''' + C.name + '''' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'AND' + @tab + @tab + 'TY.name = ''' + TY.name + '''' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + ')' + @cr + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'ALTER TABLE ' + T.name + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + 'ALTER COLUMN ' + C.name + ' ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE TY.name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'text' THEN 'varchar(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'ntext' THEN 'nvarchar(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'image' THEN 'varbinary(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE C.is_nullable <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN ' NULL' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 0 THEN ' NOT NULL' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; ELSE @sql + @cr + '-- Number of rows for ' + T.name + ' : ' + CAST(PS.row_count AS varchar(50)) + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + 'IF EXISTS' + @cr + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + '(' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'SELECT' + @tab + @tab + '*' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'FROM' + @tab + @tab + 'sys.tables AS T' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'INNER JOIN' + @tab + 'sys.columns AS C ON T.object_id = C.object_id' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'INNER JOIN' + @tab + 'sys.types AS TY ON TY.system_type_id = C.system_type_id' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'WHERE' + @tab + @tab + 'T.name = ''' + T.name + '''' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'AND' + @tab + @tab + 'C.name = ''' + C.name + '''' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + @tab + 'AND' + @tab + @tab + 'TY.name = ''' + TY.name + '''' + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + ')' + @cr + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'ALTER TABLE ' + T.name + @cr <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + 'ALTER COLUMN ' + C.name + ' ' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE TY.name <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'text' THEN 'varchar(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'ntext' THEN 'nvarchar(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 'image' THEN 'varbinary(max)' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + CASE C.is_nullable <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 1 THEN ' NULL' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN 0 THEN ' NOT NULL' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END <br />
&nbsp; &nbsp; &nbsp; &nbsp; END + @cr + 'GO' + @cr + @cr <br />
FROM &nbsp; &nbsp;sys.schemas AS S <br />
INNER JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; ON S.schema_id = T.schema_id <br />
INNER JOIN &nbsp;sys.dm_db_partition_stats AS PS <br />
&nbsp; &nbsp; &nbsp; ON PS.object_id = T.object_id <br />
INNER JOIN &nbsp;sys.columns AS C &nbsp;<br />
&nbsp; &nbsp; &nbsp; ON C.object_id = T.object_id <br />
INNER JOIN &nbsp;sys.types AS TY <br />
&nbsp; &nbsp; &nbsp; ON TY.system_type_id = C.system_type_id <br />
&nbsp; &nbsp; &nbsp; AND TY.system_type_id = TY.user_type_id <br />
WHERE &nbsp; &nbsp;1 = 1 <br />
AND &nbsp; &nbsp;S.name = 'dbo' <br />
AND &nbsp; &nbsp;TY.name IN ('image', 'text', 'ntext') <br />
ORDER BY &nbsp;T.name, C.column_id <br />
GO</div></td></tr></tbody></table></div>
<p>Dans le cas contraire, on peut recourir, de façon similaire, à une boucle :</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 /></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 - 21-03-2011 <br />
------------------------------- <br />
SET NOCOUNT ON <br />
GO <br />
&nbsp;<br />
DECLARE @tables_with_deprecated_type TABLE <br />
( <br />
&nbsp; table_name sysname <br />
&nbsp; , column_name sysname <br />
&nbsp; , column_data_type_name sysname <br />
&nbsp; , is_column_nullable bit <br />
&nbsp; , table_row_count bigint <br />
) <br />
&nbsp;<br />
INSERT &nbsp; &nbsp;@tables_with_deprecated_type <br />
SELECT &nbsp; &nbsp;T.name <br />
&nbsp; &nbsp; , C.name <br />
&nbsp; &nbsp; , TY.name <br />
&nbsp; &nbsp; , C.is_nullable <br />
&nbsp; &nbsp; , PS.row_count <br />
FROM &nbsp; &nbsp;sys.schemas AS S <br />
INNER JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; ON S.schema_id = T.schema_id <br />
INNER JOIN &nbsp;sys.dm_db_partition_stats AS PS <br />
&nbsp; &nbsp; &nbsp; ON PS.object_id = T.object_id <br />
INNER JOIN &nbsp;sys.columns AS C &nbsp;<br />
&nbsp; &nbsp; &nbsp; ON C.object_id = T.object_id <br />
INNER JOIN &nbsp;sys.types AS TY <br />
&nbsp; &nbsp; &nbsp; ON TY.system_type_id = C.system_type_id <br />
&nbsp; &nbsp; &nbsp; AND TY.system_type_id = TY.user_type_id <br />
WHERE &nbsp; &nbsp;1 = 1 <br />
AND &nbsp; &nbsp;S.name = 'dbo' <br />
AND &nbsp; &nbsp;TY.name IN ('image', 'text', 'ntext') <br />
AND &nbsp; &nbsp;PS.index_id IN (0, 1) -- Heap or Clustered index <br />
ORDER BY &nbsp;T.name, C.column_id <br />
&nbsp;<br />
DECLARE &nbsp;@table_name sysname <br />
&nbsp; , @column_name sysname <br />
&nbsp; , @column_data_type_name sysname <br />
&nbsp; , @is_column_nullable bit <br />
&nbsp; , @table_row_count bigint <br />
&nbsp; --- <br />
&nbsp; , @sql varchar(max) <br />
&nbsp; , @cr char(2) = CHAR(13) + CHAR(10) <br />
&nbsp; , @tab char(1) = CHAR(9) <br />
&nbsp;<br />
WHILE EXISTS <br />
( <br />
&nbsp; SELECT &nbsp;* <br />
&nbsp; FROM &nbsp;@tables_with_deprecated_type <br />
) <br />
BEGIN <br />
&nbsp; SELECT &nbsp;TOP (1) @table_name = table_name <br />
&nbsp; &nbsp; , @column_name = column_name <br />
&nbsp; &nbsp; , @column_data_type_name = column_data_type_name <br />
&nbsp; &nbsp; , @is_column_nullable = is_column_nullable <br />
&nbsp; &nbsp; , @table_row_count = table_row_count <br />
&nbsp; FROM &nbsp;@tables_with_deprecated_type <br />
&nbsp; <br />
&nbsp; SET &nbsp;@sql = '-- Number of rows for ' + @table_name + ' : ' + CAST(@table_row_count AS varchar(20)) + @cr <br />
&nbsp; &nbsp; + 'IF EXISTS' + @cr + <br />
&nbsp; &nbsp; + '(' + @cr <br />
&nbsp; &nbsp; + @tab + 'SELECT' + @tab + @tab + '*' + @cr <br />
&nbsp; &nbsp; + @tab + 'FROM' + @tab + @tab + 'sys.tables AS T' + @cr <br />
&nbsp; &nbsp; + @tab + 'INNER JOIN' + @tab + 'sys.columns AS C ON T.object_id = C.object_id' + @cr <br />
&nbsp; &nbsp; + @tab + 'INNER JOIN' + @tab + 'sys.types AS TY ON TY.system_type_id = C.system_type_id' + @cr <br />
&nbsp; &nbsp; + @tab + 'WHERE' + @tab + @tab + 'T.name = ''' +@table_name + '''' + @cr <br />
&nbsp; &nbsp; + @tab + 'AND' + @tab + @tab + 'C.name = ''' + @column_name + '''' + @cr <br />
&nbsp; &nbsp; + @tab + 'AND' + @tab + @tab + 'TY.name = ''' + @column_data_type_name + '''' + @cr <br />
&nbsp; &nbsp; + ')' + @cr + <br />
&nbsp; &nbsp; 'ALTER TABLE ' + @table_name + @cr <br />
&nbsp; &nbsp; + 'ALTER COLUMN ' + @column_name + ' ' <br />
&nbsp; &nbsp; + CASE @column_data_type_name <br />
&nbsp; &nbsp; &nbsp; WHEN 'text' THEN 'varchar(max)' <br />
&nbsp; &nbsp; &nbsp; WHEN 'ntext' THEN 'nvarchar(max)' <br />
&nbsp; &nbsp; &nbsp; WHEN 'image' THEN 'varbinary(max)' <br />
&nbsp; &nbsp; END <br />
&nbsp; &nbsp; + CASE @is_column_nullable <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN ' NULL' <br />
&nbsp; &nbsp; &nbsp; WHEN 0 THEN ' NOT NULL' <br />
&nbsp; &nbsp; END + @cr + 'GO' + @cr <br />
&nbsp; &nbsp; <br />
&nbsp; PRINT &nbsp;@sql <br />
&nbsp; <br />
&nbsp; DELETE &nbsp;TOP (1) @tables_with_deprecated_type <br />
END <br />
GO</div></td></tr></tbody></table></div>
<p>Le nombre de lignes de la table est imprimé dans tous les cas, et pour les tables volumineuses, on exécutera la changement de type avec précaution !</p>
<p>Bonne mise à jour !</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>1</slash:comments>
		</item>
		<item>
		<title>Retrouver le dossier par défaut des sauvegardes des bases de données sous SQL Server 2005 et suivants</title>
		<link>https://blog.developpez.com/elsuket/p9782/moteur-de-base-de-donnees-sql-server/retrouver_le_dossier_par_defaut_des_sauv</link>
		<comments>https://blog.developpez.com/elsuket/p9782/moteur-de-base-de-donnees-sql-server/retrouver_le_dossier_par_defaut_des_sauv#comments</comments>
		<pubDate>Wed, 02 Mar 2011 16:24:39 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voyons comment retrouver le dossier dans lequel sont stockés par défaut les sauvegardes de vos bases de données de deux façons : &#8211; Avec SQL Server Management Studio &#8211; Avec procédure stockée étendue non documentée xp_instance_regread En effet avec SQL &#8230; <a href="https://blog.developpez.com/elsuket/p9782/moteur-de-base-de-donnees-sql-server/retrouver_le_dossier_par_defaut_des_sauv">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voyons comment retrouver le dossier dans lequel sont stockés par défaut les sauvegardes de vos bases de données de deux façons :</p>
<p>&#8211; Avec <em>SQL Server Management Studio</em><br />
&#8211; Avec procédure stockée étendue non documentée <em>xp_instance_regread</em><br />
<span id="more-132"></span></p>
<p>En effet avec <em>SQL Server Management Studio</em>, on peut bien retrouver où seront, par défaut, stockés les fichiers de la base de données, mais pas leurs sauvegardes :</p>
<p>Si nous regardons dans les <em>Propriétés</em>/<em>Properties</em> de l&rsquo;instance :</p>
<p><img src="http://blog.developpez.com/media/backup_default_directory_1.jpg" width="334" height="583" alt="" /></p>
<p>en ouvrant la page &laquo;&nbsp;Database Settings&nbsp;&raquo;/&nbsp;&raquo;Options&nbsp;&raquo;, nous obtenons :</p>
<p><img src="http://blog.developpez.com/media/backup_default_directory_20_01.png" width="922" height="632" alt="" /></p>
<p>C&rsquo;est en fait dans ce dossier que les fichiers de sauvegarde seront stockés par défaut.<br />
Un petit manque de précision de Microsoft !</p>
<p>Le chemin du dossier est également stocké dans la base de registres, sous la clé suivante :</p>
<p><em>HKEY_LOCAL_MACHINE\Software\Microsoft\MSSQLServer\MSSQLServer</em> pour la valeur <em>BackupDirectory</em>.</p>
<p>On peut donc s&rsquo;amuser à la rechercher à l&rsquo;aide du bien connu <em>Regedit</em>, mais on peut aussi l&rsquo;obtenir à l&rsquo;aide d&rsquo;une procédure étendue système non documentée qui permet de lire les valeurs stockées dans la base de registres : <em>xp_instance_regread</em></p>
<p><font face="Courier New" size="2"><br />
<font color = "blue">EXEC</font> <font color = "black">master.dbo.xp_instance_regread</font><br />
    <font color = "red">N&rsquo;HKEY_LOCAL_MACHINE&rsquo;</font><font color = "silver">,</font><br />
    <font color = "red">N&rsquo;Software\Microsoft\MSSQLServer\MSSQLServer&rsquo;</font><font color = "silver">,</font><br />
    <font color = "red">N&rsquo;BackupDirectory&rsquo;</font><br />
</font></p>
<p>Nous retourne également :</p>
<p><img src="http://blog.developpez.com/media/backup_default_directory_3.jpg" width="266" height="67" alt="" /></p>
<p>En effet si vous exécutons l&rsquo;instruction suivante :</p>
<p><font face="Courier New" size="2"><br />
<font color = "blue">BACKUP</font> <font color = "blue">DATABASE</font> <font color = "maroon">ELSUKET</font> <font color = "blue"><br />TO</font> <font color = "maroon">DISK</font> <font color = "silver">=</font> <font color = "red">&lsquo;ELSUKET.bak&rsquo;</font> </font>*</p>
<p>Et que nous explorons le système de gestion de fichiers :</p>
<p><img src="http://blog.developpez.com/media/backup_default_directory_4.jpg" width="546" height="309" alt="" /></p>
<p>Malheureusement pour changer de dossier, nous n&rsquo;avons que les deux solutions suivantes :</p>
<p>&#8211; Spécifier dans l&rsquo;instruction BACKUP, le chemin complet du dossier qui recevra les fichiers de sauvegardes de bases de données<br />
&#8211; Modifier la valeur de la clé de registre citée plus haut</p>
<p>Bonnes sauvegardes !</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>3</slash:comments>
		</item>
		<item>
		<title>Lister les caractéristiques des indexes sous SQL Server 2005 et 2008</title>
		<link>https://blog.developpez.com/elsuket/p9762/moteur-de-base-de-donnees-sql-server/indexation/lister_les_caracteristiques_des_indexes__2008</link>
		<comments>https://blog.developpez.com/elsuket/p9762/moteur-de-base-de-donnees-sql-server/indexation/lister_les_caracteristiques_des_indexes__2008#comments</comments>
		<pubDate>Tue, 22 Feb 2011 09:28:29 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>
		<category><![CDATA[Snippets]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une requête qui nous permet de retrouver pour tout index : &#8211; la liste de ses colonnes clé &#8211; la liste de ses colonnes incluses &#8211; la définition de son filtre &#8211; le script de création de cet index &#8230; <a href="https://blog.developpez.com/elsuket/p9762/moteur-de-base-de-donnees-sql-server/indexation/lister_les_caracteristiques_des_indexes__2008">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une requête qui nous permet de retrouver pour tout index :</p>
<p>&#8211; la liste de ses colonnes clé<br />
&#8211; la liste de ses colonnes incluses<br />
&#8211; la définition de son filtre<br />
&#8211; le script de création de cet index</p>
<p><span id="more-29"></span></p>
<p>Voici une première requête qui retourne la définition de tous les index d&rsquo;une base de données.<br />
On peut bien sûr ajouter des filtres afin de voir la définition des index sur une table, ou la définition d&rsquo;un index en particulier.</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 /></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 - 22/02/2011 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;DISTINCT S.name AS schema_name <br />
&nbsp; &nbsp; , T.name AS table_name <br />
&nbsp; &nbsp; , I.name AS index_name <br />
&nbsp; &nbsp; , LEFT(KC.key_column_list, LEN(KC.key_column_list) - 1) AS key_column_list <br />
&nbsp; &nbsp; , LEFT(KCI.included_key_column_list, LEN(KCI.included_key_column_list) - 1) AS included_key_column_list <br />
&nbsp; &nbsp; , REPLACE(REPLACE(REPLACE(REPLACE(I.filter_definition, '[', ''), ']', ''), '(', ''), ')', '') AS filter_definition <br />
FROM &nbsp; &nbsp;sys.schemas AS S <br />
INNER JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; ON S.schema_id = T.schema_id <br />
INNER JOIN &nbsp;sys.indexes AS I &nbsp;<br />
&nbsp; &nbsp; &nbsp; ON T.object_id = I.object_id <br />
INNER JOIN &nbsp;sys.index_columns AS IC <br />
&nbsp; &nbsp; &nbsp; ON IC.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; AND IC.index_id = I.index_id <br />
INNER JOIN &nbsp;sys.columns AS C <br />
&nbsp; &nbsp; &nbsp; ON IC.object_id = C.object_id <br />
&nbsp; &nbsp; &nbsp; AND IC.column_id = C.column_id <br />
CROSS APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;CS.name + ',' <br />
&nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns AS CS <br />
&nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS ICS <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON CS.object_id = ICS.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND CS.column_id = ICS.column_id <br />
&nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;IC.object_id = ICS.object_id <br />
&nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;IC.index_id = ICS.index_id <br />
&nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;ICS.is_included_column = 0 <br />
&nbsp; &nbsp; &nbsp; ORDER BY &nbsp;ICS.index_column_id <br />
&nbsp; &nbsp; &nbsp; FOR XML PATH ('') <br />
&nbsp; &nbsp; ) AS KC (key_column_list) <br />
OUTER APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;CSI.name + ',' <br />
&nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns AS CSI <br />
&nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS ICSI <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON CSI.object_id = ICSI.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND CSI.column_id = ICSI.column_id <br />
&nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;IC.object_id = ICSI.object_id <br />
&nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;IC.index_id = ICSI.index_id <br />
&nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;ICSI.is_included_column = 1 <br />
&nbsp; &nbsp; &nbsp; ORDER BY &nbsp;ICSI.index_column_id <br />
&nbsp; &nbsp; &nbsp; FOR XML PATH ('') <br />
&nbsp; &nbsp; ) AS KCI (included_key_column_list) <br />
WHERE &nbsp; &nbsp;S.name = 'dbo' <br />
--AND &nbsp; &nbsp;T.name = 'maTable' <br />
--AND &nbsp; &nbsp;I.name = 'monIndex' <br />
ORDER BY &nbsp;T.name, I.name</div></td></tr></tbody></table></div>
<p><strong>Et une autre donnant le script de définition de l&rsquo;index :</strong></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 /></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 - 22/02/2011 <br />
------------------------------- <br />
;WITH <br />
&nbsp; CTE AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;DISTINCT S.name AS schema_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , T.name AS table_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , I.name AS index_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , LEFT(KC.key_column_list, LEN(KC.key_column_list) - 1) AS key_column_list <br />
&nbsp; &nbsp; &nbsp; &nbsp; , LEFT(KCI.included_key_column_list, LEN(KCI.included_key_column_list) - 1) AS included_key_column_list <br />
&nbsp; &nbsp; &nbsp; &nbsp; , REPLACE(REPLACE(REPLACE(REPLACE(I.filter_definition, '[', ''), ']', ''), '(', ''), ')', '') AS filter_definition <br />
&nbsp; &nbsp; &nbsp; &nbsp; , ROW_NUMBER() OVER(ORDER BY T.name, I.name) AS n <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;sys.schemas AS S <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON S.schema_id = T.schema_id <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.indexes AS I &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON T.object_id = I.object_id <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS IC <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON IC.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND IC.index_id = I.index_id <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.columns AS C <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON IC.object_id = C.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND IC.column_id = C.column_id <br />
&nbsp; &nbsp; CROSS APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;CS.name + ',' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns AS CS <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS ICS <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON CS.object_id = ICS.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND CS.column_id = ICS.column_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;IC.object_id = ICS.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;IC.index_id = ICS.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;ICS.is_included_column = 0 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ORDER BY &nbsp;ICS.index_column_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FOR XML PATH ('') <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS KC (key_column_list) <br />
&nbsp; &nbsp; OUTER APPLY &nbsp;( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SELECT &nbsp; &nbsp;CSI.name + ',' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; &nbsp;sys.columns AS CSI <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INNER JOIN &nbsp;sys.index_columns AS ICSI <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON CSI.object_id = ICSI.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND CSI.column_id = ICSI.column_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp; &nbsp;IC.object_id = ICSI.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;IC.index_id = ICSI.index_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND &nbsp; &nbsp;ICSI.is_included_column = 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ORDER BY &nbsp;ICSI.index_column_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FOR XML PATH ('') <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS KCI (included_key_column_list) <br />
&nbsp; &nbsp; WHERE &nbsp; &nbsp;S.name = 'dbo' <br />
&nbsp; &nbsp; --AND &nbsp; &nbsp;T.name = 'maTable' <br />
&nbsp; &nbsp; --AND &nbsp; &nbsp;I.name = 'monIndex' <br />
&nbsp; ) <br />
SELECT &nbsp;'CREATE INDEX ' + index_name &nbsp;<br />
&nbsp; + ' ON ' + schema_name + '.' + table_name <br />
&nbsp; + '(' + key_column_list + ')' <br />
&nbsp; + CASE WHEN included_key_column_list IS NOT NULL THEN ' INCLUDE(' + included_key_column_list + ')' ELSE '' END <br />
&nbsp; + CASE WHEN filter_definition IS NOT NULL THEN ' WHERE ' + filter_definition ELSE '' END <br />
FROM &nbsp;CTE</div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connaître la taille du cache alloué aux bases de données d&#8217;une instance</title>
		<link>https://blog.developpez.com/elsuket/p9741/moteur-de-base-de-donnees-sql-server/connaitre_la_taille_du_cache_alloue_aux_</link>
		<comments>https://blog.developpez.com/elsuket/p9741/moteur-de-base-de-donnees-sql-server/connaitre_la_taille_du_cache_alloue_aux_#comments</comments>
		<pubDate>Wed, 09 Feb 2011 09:40:21 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une petite requête qui retourne la répartition de la mémoire allouée aux données pour toutes les bases de données d&#8217;une instance SQL Server : 12345678910111213------------------------------- -- Nicolas SOUQUET - 09/02/2011 ------------------------------- SELECT &#160; &#160;CASE &#160; &#160; &#160; WHEN GROUPING(D.name) &#8230; <a href="https://blog.developpez.com/elsuket/p9741/moteur-de-base-de-donnees-sql-server/connaitre_la_taille_du_cache_alloue_aux_">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une petite requête qui retourne la répartition de la mémoire allouée aux données pour toutes les bases de données d&rsquo;une instance SQL Server :<br />
<span id="more-107"></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 /></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/02/2011 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;CASE <br />
&nbsp; &nbsp; &nbsp; WHEN GROUPING(D.name) = 1 THEN 'TOTAL' <br />
&nbsp; &nbsp; &nbsp; ELSE D.name &nbsp;<br />
&nbsp; &nbsp; END AS database_name <br />
&nbsp; &nbsp; , CAST(COUNT_BIG(*) / 128.0 AS decimal(10,2)) AS cached_size_MB <br />
FROM &nbsp; &nbsp;sys.dm_os_buffer_descriptors AS OSBD <br />
INNER JOIN &nbsp;sys.databases AS D ON OSBD.database_id = D.database_id <br />
--WHERE &nbsp; &nbsp;D.name = 'maBD' <br />
GROUP BY &nbsp;D.name WITH ROLLUP <br />
ORDER BY &nbsp;cached_size_MB DESC</div></td></tr></tbody></table></div>
<p>Bon monitoring !</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Lazywriter, Checkpoint &amp; Ghost Cleanup : Le Bon, La Brute et Le Truand de la gestion mémoire de SQL Server</title>
		<link>https://blog.developpez.com/elsuket/p9529/moteur-de-base-de-donnees-sql-server/lazywriter_checkpoint_aamp_ghost_cleanup</link>
		<comments>https://blog.developpez.com/elsuket/p9529/moteur-de-base-de-donnees-sql-server/lazywriter_checkpoint_aamp_ghost_cleanup#comments</comments>
		<pubDate>Wed, 24 Nov 2010 08:44:58 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Toute modification de données se fait d&#8217;abord sur les pages de la base de données qui sont en mémoire. Toute page qui subit une modification mais qui n&#8217;a pas encore été copiée sur disque dur est alors qualifiée de &#171;&#160;sale&#160;&#187;, &#8230; <a href="https://blog.developpez.com/elsuket/p9529/moteur-de-base-de-donnees-sql-server/lazywriter_checkpoint_aamp_ghost_cleanup">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Toute modification de données se fait d&rsquo;abord sur les pages de la base de données qui sont en mémoire.<br />
Toute page qui subit une modification mais qui n&rsquo;a pas encore été copiée sur disque dur est alors qualifiée de &laquo;&nbsp;sale&nbsp;&raquo;, ou &laquo;&nbsp;dirty&nbsp;&raquo; dans la littérature.</p>
<p>En effet, SQL Server, comme la plupart des SGBDR, travaille exclusivement en mémoire vive, pour la simple raison que son accès est au moins 1000 fois plus rapide qu&rsquo;un accès aux disques durs, si performants qu&rsquo;ils soient.</p>
<p>Mais alors comment sont persistées ces changements sur les disques durs qui supportent la base de données ?<br />
<span id="more-106"></span><br />
Comme les trois as de la gâchette du célèbre film sont à la recherche d&rsquo;un chargement d&rsquo;or disparu, ces trois processus flairent avec précision, quand on les &laquo;&nbsp;sonne&nbsp;&raquo;, les pages de données qui ont été modifiées pour optimiser le fonctionnement du moteur de base de données.</p>
<p>Techniquement, chaque page de la base de données qui est chargée en RAM contient un compteur qui représente le nombre de fois où la page a été accédée, et un drapeau qui indique si la page est sale.<br />
A intervalles de temps réguliers, le processus LazyWriter et Checkpoint scanne la RAM et décrémente le compteur.<br />
A chaque fois que la page est accédée, ce compteur est incrémenté.<br />
Lorsque la valeur de ce compteur est à zéro, SQL Server vérifie si la page est &laquo;&nbsp;sale&nbsp;&raquo;.<br />
Si c&rsquo;est le cas, les changements de la page sont écrits sur disque et la page est libérée.<br />
Sinon, la page est directement libérée.</p>
<p>=> <strong>Le Bon : Lazywriter</strong></p>
<p>Pourquoi &laquo;&nbsp;Le Bon&nbsp;&raquo; ? Parce que son travail est de garantir un certain nombre de pages libres en RAM, prêtes à recevoir des données.</p>
<p>Avec cette méthode donc, les pages les plus fréquemment accédées restent en mémoire, alors que celles qui le sont moins sont libérées, et permettent l&rsquo;accès à d&rsquo;autres pages de la base de données.</p>
<p>Imaginons un moment que ce processus n&rsquo;existe pas.<br />
Alors si la taille de ma base de données est plus grande que la taille de la RAM disponible sur le serveur qui supporte la base de données, on ne pourrait plus accéder à aucune table une fois que la RAM serait peuplée par les tables dernièrement accédées.</p>
<p>C&rsquo;est d&rsquo;ailleurs tout à l&rsquo;image de l&rsquo;utilisation d&rsquo;une base de données : en général, les dernières données accédées sont celles qui sont le plus souvent réutilisées peu après.<br />
Celles qui en revanche on été écrites il y un moment sont beaucoup moins manipulées.</p>
<p>S&rsquo;il y a donc beaucoup de pages libres, ce processus aura peu de travail, car il est conçu pour conserver un minimum de pages toujours libres en RAM.<br />
En revanche, si ce processus est exécuté très souvent, cela peut traduire une pression mémoire.<br />
Pour visualiser les exécutions de ce processus, on peut utiliser le compteur de performance <em>SQLServer:Buffer Manager / Lazy writes/sec</em> dans le <em>Moniteur de Performances</em>.</p>
<p>=> <strong>La Brute: Checkpoint</strong></p>
<p>Checkpoint écrit aussi les pages &laquo;&nbsp;sales&nbsp;&raquo; de la RAM sur disque, mais son but n&rsquo;est pas de garantir un minimum de pages toujours libres en RAM.</p>
<p>Il est exécuté :</p>
<p>&#8211; par défaut toutes les minutes<br />
&#8211; lors de l&rsquo;exécution d&rsquo;une instruction ALTER DATABASE<br />
&#8211; lors de l&rsquo;arrêt du service SQL Server</p>
<p>En effet, il est programmé pour garantir un temps de rétablissement de la base de données aussi court que possible.<br />
Le rétablissement d&rsquo;une base de données, durant lequel la base de données est inaccessible, se fait par la lecture complète du fichier du journal des transactions, à la recherche de transactions qui auraient été validées mais pas écrites sur disque lors de l&rsquo;arrêt de la base de données.<br />
Cette étape est appelée &laquo;&nbsp;REDO&nbsp;&raquo;.<br />
Ce processus peut donc être très long s&rsquo;il s&rsquo;agit de bases de données OLTP supportant un fort trafic.</p>
<p>Or ce que l&rsquo;on recherche, c&rsquo;est qu&rsquo;une telle base de données ne soit jamais inaccessible, ou au pire qu&rsquo;elle le soit pour une durée aussi courte que possible.<br />
Pour garantir un rétablissement en une minute (valeur par défaut de l&rsquo;option de configuration <em>recovery interval (min)</em>, ce processus écrit toutes les pages &laquo;&nbsp;sales&nbsp;&raquo; sur disque et ajoute une entrée dans le fichier du journal des transactions pour indiquer que tous les changements avant cette entrée sont maintenant persistés dans le fichier du journal des transactions.</p>
<p>Il faut noter que Checkpoint écrit <strong>toutes</strong> les pages &laquo;&nbsp;sales&nbsp;&raquo; sur disque, pas seulement celles des transactions validées. C&rsquo;est pour cela qu&rsquo;il est &laquo;&nbsp;La Brute&nbsp;&raquo;.<br />
Cela signifie donc que la page peut être &laquo;&nbsp;sale&nbsp;&raquo; pour une transaction qui va peut-être être annulée.<br />
En fait, quand l&rsquo;annulation de la transaction aura lieu, la page sera de nouveau marquée &laquo;&nbsp;sale&nbsp;&raquo;, et écrite plus tard sur disque.</p>
<p>Enfin, si la base de données à été arrêtée après que les pages aient été écrites sur disque, mais avant que la transaction ait été validée, une partie du processus de rétablissement annulera une telle transaction. Cette étape est appelée &laquo;&nbsp;UNDO&nbsp;&raquo;.</p>
<p>On peut bien évidemment changer la valeur de l&rsquo;option de configuration <em>recovery interval (min)</em>, mais cela n&rsquo;est pas conseillé.<br />
En effet, si l&rsquo;on augmente ce temps, évidemment ce processus s&rsquo;exécutera moins souvent.<br />
Mais quand il s&rsquo;exécutera, il aura plus de pages à écrire sur disque, ce qui peut se transformer en contention disque.</p>
<p>Pour visualiser les exécutions de ce processus, on peut utiliser le compteur de performance <em>SQLServer:Buffer Manager</em> / <em>Checkpoint pages/sec</em> dans le <em>Moniteur de Performances</em>.</p>
<p>=> <strong>Le Truand : Ghost Cleanup</strong></p>
<p>Pareillement à LazyWriter et Checkpoint, Ghost Cleanup est un processus d&rsquo;arrière-plan.<br />
Son rôle est de supprimer les clés fantômes, c&rsquo;est-à-dire une valeur de clé d&rsquo;un index qui vient d&rsquo;être supprimée.<br />
En effet, la maintenance d&rsquo;un index sur une instruction DELETE ne supprime pas physiquement la valeur de clé : elle le marque comme supprimé; il est donc fantôme : c&rsquo;est &laquo;&nbsp;Le Truand&nbsp;&raquo;.</p>
<p>Exposé en tant que tel, on peut le voir comme un défaut, mais il s&rsquo;agit en fait d&rsquo;une optimisation.<br />
Cela permet en effet aux transactions DELETE de s&rsquo;exécuter plus vite, mais aussi d&rsquo;être annulées plus vite (il n&rsquo;est pas besoin de réinsérer la ligne).</p>
<p>C&rsquo;est donc Ghost Cleanup qui va ensuite supprimer physiquement les valeurs de clé de l&rsquo;index marquées comme fantôme, ce qui a donc pour effet de grouper les entrées/sorties disque.</p>
<p>=> <strong>Comment voir ces processus à l&rsquo;aide d&rsquo;une requête ?</strong></p>
<p>En exécutant la requête suivante :</p>
<p><font face="Courier New" size="2"><font color = "blue">SELECT</font> <font color = "silver">*</font><br />
<font color = "blue">FROM</font>   <font color = "maroon">sys</font><font color = "silver">.</font><font color = "maroon">dm_exec_requests</font><br /><font color = "blue">WHERE</font>  <font color = "maroon">command</font> <font color = "silver">=</font> <font color = "red">&lsquo;LAZY WRITER&rsquo;</font><br /><font color = "blue">OR</font>     <font color = "maroon">command</font> <font color = "silver">=</font> <font color = "red">&lsquo;CHECKPOINT&rsquo;</font><br /><font color = "blue">OR</font>     <font color = "maroon">command</font> <font color = "silver">=</font> <font color = "red">&lsquo;GHOST CLEANUP&rsquo;</font></p>
<p>Bonne gestion des buffers !</p>
<p>ElSüket <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></font></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Le reconstruction des index et la mise à jour des statistiques de colonnes</title>
		<link>https://blog.developpez.com/elsuket/p9517/moteur-de-base-de-donnees-sql-server/le_reconstruction_des_index_et_la_mise_a</link>
		<comments>https://blog.developpez.com/elsuket/p9517/moteur-de-base-de-donnees-sql-server/le_reconstruction_des_index_et_la_mise_a#comments</comments>
		<pubDate>Sat, 20 Nov 2010 06:07:43 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Lors de la reconstruction des index (ALTER INDEX &#8230; REBUILD), les statistiques de colonne qui constituent la clé de l&#8217;index sont recalculées avec l&#8217;échantillonnage maximal. Que se passe-t-il si par la suite on souhaite mettre à jour les statistiques pour &#8230; <a href="https://blog.developpez.com/elsuket/p9517/moteur-de-base-de-donnees-sql-server/le_reconstruction_des_index_et_la_mise_a">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Lors de la reconstruction des index (ALTER INDEX &#8230; REBUILD), les statistiques de colonne qui constituent la clé de l&rsquo;index sont recalculées avec l&rsquo;échantillonnage maximal.</p>
<p>Que se passe-t-il si par la suite on souhaite mettre à jour les statistiques pour les colonnes non-indexées ?<br />
<span id="more-98"></span><br />
Si l&rsquo;on éxécute :</p>
<p><font face="Courier New" size="2"><font color = "blue">UPDATE</font> <font color = "blue">STATISTICS</font> <font color = "maroon">dbo.maTable</font> </font></p>
<p>Sans aucune option, toutes les statistiques attachées à la table sont recalculées avec un échantillonnage par défaut.<br />
On perd donc l&rsquo;avantage de la reconstruction des index, qui utilise pour le recalcul des statistiques un échantillonnage de 100%.<br />
Il suffit pour éviter ce comportement d&rsquo;ajouter l&rsquo;option COLUMNS comme suit :</p>
<p><font face="Courier New" size="2"><font color = "blue">UPDATE STATISTICS</font> <font color = "maroon">dbo.maTable</font> <font color = "blue">WITH</font> <font color = "green">COLUMNS</font> </font></p>
<p>Voici un petit pour comprendre ce que fait SQL Server.<br />
Notez que je n&rsquo;ai pas changé les options de statistiques dans ma base de données, ce qui signifie qu&rsquo;elles sont créées et maintenues automatiquement.</p>
<p>Créons délibérément la table suivante :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE TABLE test_statistique <br />
( <br />
&nbsp; test_statistique_id int NOT NULL IDENTITY CONSTRAINT PKtest_statistique PRIMARY KEY <br />
&nbsp; , nom_test_statistique char(4000) NOT NULL <br />
)</div></td></tr></tbody></table></div>
<p>C&rsquo;est à dire que pour toute ligne insérée dans la table, nous consommerons 8 (int )+ 4000 octets.<br />
De cette façon, nous dépasserons facilement les 8Mo d&rsquo;espace occupé par la table.<br />
En effet, pour une table ayant une taille inférieure à 8Mo, SQL Server utilise l&rsquo;échantillonnage maximal pour collecter les statistiques de colonne.<br />
Ce n&rsquo;est plus le cas lorsque la taille de la table dépasse les 8Mo, ou l&rsquo;échantillonnage est alors utilisé.</p>
<p>Peuplons la table comme suit :</p>
<p><font face="Courier New" size="2"><font color = "blue">INSERT INTO</font> <font color = "maroon">dbo.test_statistique </font><font color = "maroon">(</font><font color = "maroon">nom_test_statistique</font><font color = "maroon">)</font><font color = "blue"> VALUES </font><font color = "maroon">(</font><font color = "red">&lsquo; &lsquo;</font><font color = "maroon">)</font><br /><font color = "blue">GO </font><font color = "black">10000</font> </font> </p>
<p>Exécutons la requête suivante, de sorte que des statistiques soient automatiquement créées  pour la colonne nom_test_statistique :</p>
<p><font face="Courier New" size="2"><font color = "blue">SELECT</font> <font color = "silver">*</font><br /><font color = "blue">FROM</font>   <font color = "maroon">dbo.test_statistique</font><br />
<br /><font color = "blue">WHERE</font>  <font color = "maroon">nom_test_statistique</font> <font color = "silver">=</font> <font color = "red">&lsquo;a&rsquo;</font> </font></p>
<p>Il existe maintenant les statistiques suivantes :</p>
<p><img src="http://blog.developpez.com/media/stats.png" width="271" height="201" alt="" /></p>
<p>Voyons comment ont été échantillonnées les statistiques :</p>
<p><font face="Courier New" size="2"><font color = "blue">DBCC SHOW_STATISTICS</font> <font color = "maroon">(</font><font color = "maroon">test_statistique</font><font color = "silver">,</font> <font color = "maroon">_WA_Sys_00000002_7f60ed59</font><font color = "maroon">)</font> <font color = "blue">WITH STAT_HEADER</font><br />
<font face="Courier New" size="2"><font color = "blue">DBCC SHOW_STATISTICS</font> <font color = "maroon">(</font><font color = "maroon">test_statistique</font><font color = "silver">,</font> <font color = "maroon">PKtest_statistique</font><font color = "maroon">)</font> <font color = "blue">WITH STAT_HEADER</font></p>
<p>Nous donne :</p>
<p><img src="http://blog.developpez.com/media/stats_1.png" width="921" height="43" alt="" /><img src="http://blog.developpez.com/media/stats_2.png" width="851" height="41" alt="" /></p>
<p>Reconstruisons l&rsquo;index sous-jacent à la clé primaire :</p>
<p><font face="Courier New" size="2"><font color = "blue">ALTER</font> <font color = "blue">INDEX</font> <font color = "maroon">PKtest_statistique</font> <font color = "blue">ON</font> <font color = "maroon">dbo.</font><font color = "maroon">test_statistique</font> <font color = "blue">REBUILD</font> </font></p>
<p>Puis rééxécutons <font face="Courier New" size="2"><font color = "blue">DBCC SHOW_STATISTICS</font> <font color = "maroon">(</font><font color = "maroon">test_statistique</font><font color = "silver">,</font> <font color = "maroon">PKtest_statistique</font><font color = "maroon">)</font> <font color = "blue">WITH STAT_HEADER</font></p>
<p>Nous obtenons :</p>
<p><img src="http://blog.developpez.com/media/stats_3.png" width="853" height="44" alt="" /></p>
<p>L&rsquo;échantillonnage est donc bien de 100% lors de la reconstruction de l&rsquo;index.<br />
C&rsquo;est normal puisque la table a du être parcourue dans son entier pour construire l&rsquo;index.</p>
<p>Exécutons maintenant :</p>
<p><font face="Courier New" size="2"><font color = "blue">UPDATE STATISTICS</font> <font color = "maroon">dbo.test_statistique</font> <font color = "blue">WITH</font> <font color = "green">COLUMNS</font> </font></p>
<p>Puis rééxécutons les deux instructions <font face="Courier New" size="2"><font color = "blue">DBCC SHOW_STATISTICS</font> :</p>
<p><img src="http://blog.developpez.com/media/stats_4.png" width="924" height="104" alt="" /></p>
<p>Les statistiques de la clé primaire n&rsquo;ont pas été touchées, et seules celles de la colonne nom_test_statistique ont été recalculées.</p>
<p>Voyons la différence sans l&rsquo;option <font color = "blue">WITH</font> <font color = "green">COLUMNS</font> </font> :</p>
<p><img src="http://blog.developpez.com/media/stats_5.png" width="929" height="116" alt="" /></p>
<p>Le bénéfice de la reconstruction de l&rsquo;index de la clé primaire est donc perdu !<br />
On l&rsquo;a vu donc, il est indispensable d&rsquo;utiliser l&rsquo;option <font color = "blue">WITH</font> <font color = "green">COLUMNS</font> </font>de l&rsquo;instruction <font face="Courier New" size="2"><font color = "blue">UPDATE</font> <font color = "blue">STATISTICS</font> pour maintenir correctement les statistiques de vos tables.</p>
<p>Bonnes statistiques !</p>
<p>ElSüket <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></font></font></font></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rechercher les index inutiles</title>
		<link>https://blog.developpez.com/elsuket/p9496/moteur-de-base-de-donnees-sql-server/indexation/rechercher_les_index_inutiles</link>
		<comments>https://blog.developpez.com/elsuket/p9496/moteur-de-base-de-donnees-sql-server/indexation/rechercher_les_index_inutiles#comments</comments>
		<pubDate>Tue, 16 Nov 2010 10:48:15 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Si les index représentent l&#8217;optimisation la plus simple à mettre en place, on souhaite néanmoins conserver le minimum d&#8217;entre-eux, car leur maintenance lors de l&#8217;exécution de requêtes de modifications de données (INSERT, UPDATE, DELETE) peut être coûteuse, surtout sur des &#8230; <a href="https://blog.developpez.com/elsuket/p9496/moteur-de-base-de-donnees-sql-server/indexation/rechercher_les_index_inutiles">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Si les index représentent l&rsquo;optimisation la plus simple à mettre en place, on souhaite néanmoins conserver le minimum d&rsquo;entre-eux, car leur maintenance lors de l&rsquo;exécution de requêtes de modifications de données (INSERT, UPDATE, DELETE) peut être coûteuse, surtout sur des tables volumineuses.<br />
Voyons comment collecter cette information &#8230;<br />
<span id="more-28"></span><br />
La requête suivante retourne tous les index de la base de données en cours pour lesquels seule la maintenance a eu lieu (mais qui n&rsquo;ont servi aucune requête de type SELECT (IUS.user_lookups + IUS.user_scans + IUS.user_seeks = 0):</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 /></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 - 16/11/2010 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;T.name AS table_name <br />
&nbsp; &nbsp; , PS.row_count <br />
&nbsp; &nbsp; , I.name AS index_name <br />
&nbsp; &nbsp; , dbo.nico(I.object_id, I.index_id) AS index_key <br />
&nbsp; &nbsp; , IUS.user_lookups + IUS.user_scans + IUS.user_seeks AS total_user_searches <br />
&nbsp; &nbsp; , IUS.user_updates <br />
&nbsp; &nbsp; , IUS.system_lookups + IUS.system_scans + IUS.system_seeks AS total_system_searches <br />
&nbsp; &nbsp; , IUS.system_updates <br />
FROM &nbsp; &nbsp;sys.dm_db_index_usage_stats AS IUS <br />
INNER JOIN &nbsp;sys.indexes AS I <br />
&nbsp; &nbsp; &nbsp; ON IUS.database_id = DB_ID() <br />
&nbsp; &nbsp; &nbsp; AND IUS.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; AND IUS.index_id = I.index_id <br />
INNER JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; ON I.object_id = T.object_id <br />
INNER JOIN &nbsp;sys.dm_db_partition_stats AS PS &nbsp;<br />
&nbsp; &nbsp; &nbsp; ON PS.object_id = T.object_id <br />
&nbsp; &nbsp; &nbsp; AND PS.index_id BETWEEN 0 AND 1 <br />
LEFT JOIN &nbsp;sys.objects AS O <br />
&nbsp; &nbsp; &nbsp; ON O.parent_object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; AND O.type = 'PK' <br />
&nbsp; &nbsp; &nbsp; AND O.name = I.name <br />
WHERE &nbsp; &nbsp;IUS.user_lookups + IUS.user_scans + IUS.user_seeks = 0 <br />
AND &nbsp; &nbsp;O.object_id IS NULL <br />
ORDER BY &nbsp;IUS.user_updates DESC --PS.row_count DESC</div></td></tr></tbody></table></div>
<p>On exclut les indexes sous-jacents à une clé primaire, puisque leur suppression obligerait celle de la contrainte.</p>
<p>Si l&rsquo;on souhaite extraire la clé de l&rsquo;index, il faudra alors créer la petite fonction suivante :</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 /></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 - 16/11/2010 <br />
------------------------------- <br />
CREATE FUNCTION dbo.ufn_GetIndexKey <br />
&nbsp; ( <br />
&nbsp; &nbsp; @_object_id int <br />
&nbsp; &nbsp; , @_index_id int <br />
&nbsp; ) <br />
&nbsp; RETURNS varchar(max) <br />
AS <br />
BEGIN &nbsp;<br />
&nbsp; DECLARE @index_key varchar(max) <br />
&nbsp; <br />
&nbsp; SELECT &nbsp; &nbsp;@index_key = CASE WHEN @index_key IS NULL THEN C.name ELSE @index_key + + ', ' + C.name END &nbsp;<br />
&nbsp; FROM &nbsp; &nbsp;sys.indexes AS I <br />
&nbsp; INNER JOIN &nbsp;sys.index_columns AS IC <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON I.object_id = IC.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; AND I.index_id = IC.index_id <br />
&nbsp; INNER JOIN &nbsp;sys.columns AS C <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON IC.object_id = C.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; AND IC.column_id = C.column_id <br />
&nbsp; WHERE &nbsp; &nbsp;I.object_id = @_object_id <br />
&nbsp; AND &nbsp; &nbsp;I.index_id = @_index_id <br />
&nbsp; ORDER BY &nbsp;IC.index_column_id <br />
&nbsp;<br />
&nbsp; RETURN @index_key <br />
END</div></td></tr></tbody></table></div>
<p>Que l&rsquo;on peut utiliser directement comme suit :</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">SELECT &nbsp; &nbsp;T.name AS table_name <br />
&nbsp; &nbsp; , PS.row_count <br />
&nbsp; &nbsp; , I.name AS index_name <br />
&nbsp; &nbsp; , dbo.ufn_GetIndexKey (I.object_id, I.index_id) AS index_key <br />
&nbsp; &nbsp; , IUS.user_lookups + IUS.user_scans + IUS.user_seeks AS total_user_searches <br />
&nbsp; &nbsp; , IUS.user_updates <br />
&nbsp; &nbsp; , IUS.system_lookups + IUS.system_scans + IUS.system_seeks AS total_system_searches <br />
&nbsp; &nbsp; , IUS.system_updates <br />
FROM &nbsp; &nbsp;sys.dm_db_index_usage_stats AS IUS <br />
INNER JOIN &nbsp;sys.indexes AS I <br />
&nbsp; &nbsp; &nbsp; ON IUS.database_id = DB_ID() <br />
&nbsp; &nbsp; &nbsp; AND IUS.object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; AND IUS.index_id = I.index_id <br />
INNER JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; ON I.object_id = T.object_id <br />
INNER JOIN &nbsp;sys.dm_db_partition_stats AS PS &nbsp;<br />
&nbsp; &nbsp; &nbsp; ON PS.object_id = T.object_id <br />
&nbsp; &nbsp; &nbsp; AND PS.index_id BETWEEN 0 AND 1 <br />
LEFT JOIN &nbsp;sys.objects AS O <br />
&nbsp; &nbsp; &nbsp; ON O.parent_object_id = I.object_id <br />
&nbsp; &nbsp; &nbsp; AND O.type = 'PK' <br />
&nbsp; &nbsp; &nbsp; AND O.name = I.name <br />
WHERE &nbsp; &nbsp;IUS.user_lookups + IUS.user_scans + IUS.user_seeks = 0 <br />
AND &nbsp; &nbsp;O.object_id IS NULL <br />
ORDER BY &nbsp;IUS.user_updates DESC --PS.row_count DESC</div></td></tr></tbody></table></div>
<p>Il ne reste alors plus qu&rsquo;à juger de la pertinence de la suppression de l&rsquo;index, car leur création est assez coûteuse.<br />
En effet, si on supprime un index et qu&rsquo;on se rend compte qu&rsquo;il aurait pu servir des requêtes :</p>
<p>&#8211; dans le cas où on dispose d&rsquo;une édition <em>Standard</em> de SQL Server, on doit recréer l&rsquo;index et cela bloque la table<br />
&#8211; dans le cas où on dispose d&rsquo;une édition <em>Enterprise</em> de SQL Server, on peut recréer l&rsquo;index en ligne, mais cela utilise massivement la base de données système TempDB dans laquelle est effectuée le tri, plus l&rsquo;espace disque nécessaire à la copie de l&rsquo;index, et enfin le coût de maintenance de deux index au lieu d&rsquo;un.</p>
<p>Bonne indexation !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Activer et configurer le coordinateur de transactions distribuées : le service MSDTC</title>
		<link>https://blog.developpez.com/elsuket/p8347/moteur-de-base-de-donnees-sql-server/activer_et_configurer_le_coordinateur_de</link>
		<comments>https://blog.developpez.com/elsuket/p8347/moteur-de-base-de-donnees-sql-server/activer_et_configurer_le_coordinateur_de#comments</comments>
		<pubDate>Mon, 16 Nov 2009 21:56:53 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Pour exécuter des transactions explicites (à plusieurs instructions) depuis SQL Server vers un autre serveur de base de données, nous devons configurer un serveur lié qui représente une abstraction du serveur distant vue par le serveur local, et activer le &#8230; <a href="https://blog.developpez.com/elsuket/p8347/moteur-de-base-de-donnees-sql-server/activer_et_configurer_le_coordinateur_de">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Pour exécuter des transactions explicites (à plusieurs instructions) depuis SQL Server vers un autre serveur de base de données, nous devons configurer un serveur lié qui représente une abstraction du serveur distant vue par le serveur local, et activer le service de coordination des transactions distribuées.<br />
La configuration de ce service est assez camouflée à l&rsquo;utilisateur &#8230;<br />
Voyons comment y accéder et paramétrer ce service :<br />
<span id="more-93"></span><br />
MSDTC est considéré comme un service de composant, et ceux-ci sont configurables à partir de la console des outils d&rsquo;administration de la machine :</p>
<p><img src="http://blog.developpez.com/media/msdtc01.PNG" width="596" height="230" alt="" /></p>
<p>Nous obtenons immédiatement la boîte de dialogue suivante :</p>
<p><img src="http://blog.developpez.com/media/msdtc02.PNG" width="434" height="334" alt="" /></p>
<p>et nous choisissons le bouton <em>Débloquer</em> pour avoir accès à la console :</p>
<p><img src="http://blog.developpez.com/media/msdtc03.PNG" width="639" height="479" alt="" /></p>
<p>En double-cliquant sur <em>Services de composants</em>, nous pouvons accéder à tous les services de composants de la machine :</p>
<p><img src="http://blog.developpez.com/media/msdtc04.PNG" width="639" height="480" alt="" /></p>
<p>Cliquons sur l&rsquo;icône de notre machine : nous avons maintenant le moyen de démarrer le service MSDTC :</p>
<p><img src="http://blog.developpez.com/media/msdtc07.PNG" width="404" height="473" alt="" /></p>
<p>Une fois que nous avons démarré le service, nous pouvons accéder aux options de configuration de sécurité qui régissent la communication au niveau des transactions entre notre machine et les machines auxquelles nous devrons nous connecter pour les exécuter :</p>
<p><img src="http://blog.developpez.com/media/msdtc08.png" width="443" height="430" alt="" /></p>
<p>Une fois toutes ces options configurées, nous allons terminer en configurant le service.<br />
Nous pouvons configurer les services à partir du <em>Poste de travail</em> :</p>
<p><img src="http://blog.developpez.com/media/msdtc12.PNG" width="247" height="263" alt="" /></p>
<p>Nous obtenons la console suivante :</p>
<p><img src="http://blog.developpez.com/media/msdtc13.PNG" width="545" height="343" alt="" /></p>
<p>Il nous suffit alors de double-cliquer sur la node <em>Services</em> pour en obtenir la liste.<br />
Nous sélectionnons alors <em>Distributed Transaction Coordinator</em> :</p>
<p><img src="http://blog.developpez.com/media/msdtc09.png" width="433" height="221" alt="" /></p>
<p>Passons ce service en démarrage automatique, ce qui lui permettra de démarrer systématiquement après un redémarrage de la machine :</p>
<p><img src="http://blog.developpez.com/media/msdtc10.png" width="410" height="468" alt="" /></p>
<p>Terminons en validant le tout :</p>
<p><img src="http://blog.developpez.com/media/msdtc11.png" width="410" height="474" alt="" /></p>
<p>N&rsquo;oubliez pas d&rsquo;ouvrir le port 135, et d&rsquo;autoriser l&rsquo;exécutable C:\Windows\system32\msdtc.exe dans votre pare-feu.</p>
<p>Bonnes transactions distribuées !</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sur quelles colonnes sont collectées les statistiques ?</title>
		<link>https://blog.developpez.com/elsuket/p9313/moteur-de-base-de-donnees-sql-server/sur_quelles_colonnes_sont_collectees_les</link>
		<comments>https://blog.developpez.com/elsuket/p9313/moteur-de-base-de-donnees-sql-server/sur_quelles_colonnes_sont_collectees_les#comments</comments>
		<pubDate>Fri, 24 Sep 2010 04:00:00 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une petite requête qui permet de connaître les colonnes sur lesquelles sont collectées les statistiques. Elle est assez utile pour les statistiques créées autmatiquement, dont le nom est assez abscons (_WA_Sys_&#8230;.) 12345678910111213SELECT &#160; &#160;S.name AS statistic_name &#160; &#160; , &#8230; <a href="https://blog.developpez.com/elsuket/p9313/moteur-de-base-de-donnees-sql-server/sur_quelles_colonnes_sont_collectees_les">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une petite requête qui permet de connaître les colonnes sur lesquelles sont collectées les statistiques.<br />
Elle est assez utile pour les statistiques créées autmatiquement, dont le nom est assez abscons (_WA_Sys_&#8230;.)<br />
<span id="more-105"></span></p>
<pre>

<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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT &nbsp; &nbsp;S.name AS statistic_name <br />
&nbsp; &nbsp; , C.name AS column_name <br />
FROM &nbsp; &nbsp;sys.stats AS S <br />
INNER JOIN &nbsp;sys.stats_columns AS SC <br />
&nbsp; &nbsp; &nbsp; ON S.object_id = SC.object_id <br />
&nbsp; &nbsp; &nbsp; AND S.stats_id = SC.stats_id <br />
INNER JOIN &nbsp;sys.columns AS C <br />
&nbsp; &nbsp; &nbsp; ON SC.object_id = C.object_id <br />
&nbsp; &nbsp; &nbsp; AND SC.column_id = C.column_id <br />
INNER JOIN &nbsp;sys.TABLES AS T <br />
&nbsp; &nbsp; &nbsp; ON T.object_id = C.object_id <br />
WHERE &nbsp; &nbsp; &nbsp; &nbsp;T.name = 'maTable' <br />
ORDER BY &nbsp; &nbsp;S.name, C.name, SC.stats_column_id</div></td></tr></tbody></table></div>

</pre>
<p>Bonne gestion de statistiques <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>0</slash:comments>
		</item>
		<item>
		<title>Trouver les requêtes en cours de blocage</title>
		<link>https://blog.developpez.com/elsuket/p9282/moteur-de-base-de-donnees-sql-server/trouver_les_requetes_en_cours_de_blocage</link>
		<comments>https://blog.developpez.com/elsuket/p9282/moteur-de-base-de-donnees-sql-server/trouver_les_requetes_en_cours_de_blocage#comments</comments>
		<pubDate>Mon, 13 Sep 2010 14:16:54 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Il est utile de voir quelles sont les ressources mises en jeu dans le blocage de requêtes en cours d&#8217;exécution dans une instance SQL Server. Voici donc une requête retournant quelques informations relatives aux requêtes bloquées par d&#8217;autres : 1234567891011121314151617181920212223242526272829303132333435363738394041SELECT &#8230; <a href="https://blog.developpez.com/elsuket/p9282/moteur-de-base-de-donnees-sql-server/trouver_les_requetes_en_cours_de_blocage">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Il est utile de voir quelles sont les ressources mises en jeu dans le blocage de requêtes en cours d&rsquo;exécution dans une instance SQL Server.<br />
Voici donc une requête retournant quelques informations relatives aux requêtes bloquées par d&rsquo;autres :<br />
<span id="more-67"></span></p>
<pre>

<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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT &nbsp; &nbsp; &nbsp; &nbsp;TL.resource_type <br />
&nbsp; &nbsp; &nbsp; &nbsp; , D.name AS database_name <br />
&nbsp; &nbsp; &nbsp; &nbsp; , TL.resource_associated_entity_id AS blk_object <br />
&nbsp; &nbsp; &nbsp; &nbsp; , TL.request_mode <br />
&nbsp; &nbsp; &nbsp; &nbsp; , TL.request_session_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , WT.blocking_session_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; , WT.wait_duration_ms <br />
&nbsp; &nbsp; &nbsp; &nbsp; , SUBSTRING <br />
&nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SQL.text <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , ER.statement_start_offset / 2, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN ER.statement_end_offset = -1 THEN LEN(CONVERT(nvarchar(max), SQL.text)) * 2 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE ER.statement_end_offset <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END - ER.statement_start_offset <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) / 2 + 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS query_text <br />
&nbsp; &nbsp; &nbsp; &nbsp; , SUBSTRING <br />
&nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BSQL.text <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , BER.statement_start_offset / 2, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CASE <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WHEN BER.statement_end_offset = -1 THEN LEN(CONVERT(nvarchar(max), BSQL.text)) * 2 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ELSE BER.statement_end_offset <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; END - BER.statement_start_offset <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) / 2 + 1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; ) AS blk_query_text <br />
&nbsp; &nbsp; &nbsp; &nbsp; , WT.resource_description <br />
FROM &nbsp; &nbsp; &nbsp; &nbsp;sys.dm_tran_locks AS TL <br />
INNER JOIN &nbsp; &nbsp;sys.dm_os_waiting_tasks AS WT <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON TL.lock_owner_address = WT.resource_address <br />
INNER JOIN &nbsp; &nbsp;sys.dm_exec_requests AS ER <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON WT.session_id = ER.session_id <br />
INNER JOIN &nbsp; &nbsp;sys.dm_exec_requests AS BER <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON WT.blocking_session_id = BER.session_id <br />
INNER JOIN &nbsp; &nbsp;sys.databases AS D <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON TL.resource_database_id = D.database_id <br />
CROSS APPLY &nbsp; &nbsp;sys.dm_exec_sql_text (ER.sql_handle) AS SQL <br />
CROSS APPLY &nbsp; &nbsp;sys.dm_exec_sql_text (BER.sql_handle) AS BSQL</div></td></tr></tbody></table></div>

</pre>
<p>Bon débloquage <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Obtenir la liste des deadlocks rétrospectivement</title>
		<link>https://blog.developpez.com/elsuket/p9234/moteur-de-base-de-donnees-sql-server/obtenir_la_liste_des_deadlocks_retrospec</link>
		<comments>https://blog.developpez.com/elsuket/p9234/moteur-de-base-de-donnees-sql-server/obtenir_la_liste_des_deadlocks_retrospec#comments</comments>
		<pubDate>Wed, 25 Aug 2010 13:20:43 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une requête qui permet de retrouver la liste des deadlocks qui ont eu lieu dans une instance SQL Server. Elle se base sur la session d&#8217;événements étendus par défaut de SQL Server 2008&#8230; Les événements étendus sont une nouvelle &#8230; <a href="https://blog.developpez.com/elsuket/p9234/moteur-de-base-de-donnees-sql-server/obtenir_la_liste_des_deadlocks_retrospec">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une requête qui permet de retrouver la liste des deadlocks qui ont eu lieu dans une instance SQL Server.<br />
Elle se base sur la session d&rsquo;événements étendus par défaut de SQL Server 2008&#8230;<br />
<span id="more-103"></span></p>
<p>Les événements étendus sont une nouvelle fonctionnalité introduite avec SQL Server, qui permet de tracer des événements suivant les paramètres de la session.<br />
Les données peuvent ensuite être dépouillées à l&rsquo;aide des données exposées de façon structurée sous la forme de documents XML.</p>
<p>Mais il en existe une, démarrée par défaut, qui trace certains événements assez sévères, et qui permet en outre de retrouver les deadlocks et les requêtes qui y ont participé de façon rétrospective, à l&rsquo;aide de la requête suivante :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">;WITH <br />
&nbsp; -- Récupération des documents XML capturés par la session <br />
&nbsp; xml_event_payload AS <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;CAST(T.target_data AS xml) AS data <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;sys.dm_xe_session_targets AS T <br />
&nbsp; &nbsp; INNER JOIN &nbsp;sys.dm_xe_sessions AS S <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ON S.address = T.event_session_address <br />
&nbsp; &nbsp; WHERE &nbsp; &nbsp;S.name = 'system_health' <br />
&nbsp; ), <br />
&nbsp; prepare AS -- Extraction des événements de deadlock <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp; &nbsp;ED.event_xml.value('(./data/value)[1]', 'varchar(max)') AS deadlock_data <br />
&nbsp; &nbsp; FROM &nbsp; &nbsp;xml_event_payload AS XEP <br />
&nbsp; &nbsp; CROSS APPLY &nbsp;data.nodes('/RingBufferTarget/event') AS ED (event_xml) <br />
&nbsp; &nbsp; WHERE &nbsp; &nbsp;ED.event_xml.value('./@name', 'varchar(32)') = 'xml_deadlock_report' <br />
&nbsp; ), <br />
&nbsp; well_form_xml_doc AS -- Formation correcte du document XML (mal formé par défaut) <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp;REPLACE(REPLACE(deadlock_data, '&lt;victim-list&gt;', '&lt;deadlock&gt;&lt;victim-list&gt;'), '&lt;process-list&gt;','&lt;/victim-list&gt;&lt;process-list&gt;') AS deadlock_data <br />
&nbsp; &nbsp; FROM &nbsp;prepare <br />
&nbsp; ), <br />
&nbsp; del_victim_list AS -- Formation correcte du document XML (mal formé par défaut) <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT &nbsp;CAST(STUFF(deadlock_data, PATINDEX('%&lt;victim-list&gt;%', deadlock_data), PATINDEX('%&lt;/victim-list&gt;%', deadlock_data) + 14 - PATINDEX('%&lt;victim-list&gt;%', deadlock_data), '') AS xml) AS deadlock_data <br />
&nbsp; &nbsp; &nbsp; , ROW_NUMBER() OVER(ORDER BY deadlock_data) AS n <br />
&nbsp; &nbsp; FROM &nbsp;well_form_xml_doc <br />
&nbsp; ) &nbsp; &nbsp;<br />
SELECT &nbsp; &nbsp;n <br />
&nbsp; &nbsp; , D.name AS database_name <br />
&nbsp; &nbsp; , DC.deadlock_characteristics.value('./@lasttranstarted', 'datetime') AS occurence_date_time <br />
&nbsp; &nbsp; , DC.deadlock_characteristics.value('(./inputbuf)[1]', 'varchar(max)') AS query <br />
&nbsp; &nbsp; , deadlock_data <br />
FROM &nbsp; &nbsp;del_victim_list <br />
CROSS APPLY &nbsp;deadlock_data.nodes('/deadlock-list/deadlock/process-list/process') AS DC (deadlock_characteristics) <br />
INNER JOIN &nbsp;sys.databases AS D ON D.database_id = DC.deadlock_characteristics.value('./@currentdb', 'int') <br />
WHERE &nbsp; &nbsp;DC.deadlock_characteristics.value('./@lasttranstarted', 'datetime') &gt; '20100823 00:00:00.000' <br />
ORDER BY &nbsp;del_victim_list.n</div></td></tr></tbody></table></div>
<p>Chaque événement capturé par la session consiste en un document XML.<br />
La requête triture les données XML retournées par la session, car ceux-ci sont mal formés pour les deadlocks.</p>
<p>La colonne <strong>n</strong> retourne une numéro arbitraire qui correspond à une occurence de deadlock.<br />
Dès lors toute les requêtes ayant le même numéro ont participé au deadlock.</p>
<p><img src="http://img265.imageshack.us/img265/3803/deadlocksfromxe.png" alt="" title="" /></p>
<p>En cliquant dans la colonne <strong>deadlock_data</strong>, on obtient le document XML généré par l&rsquo;occurence d&rsquo;un deadlock, avec quelques informations en plus, comme le niveau d&rsquo;isolation, le nom de l&rsquo;application et de la transaction, &#8230;</p>
<p>Bon backtrack !</p>
<p>ElSuket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lister les colonnes des index d&#8217;une base de données</title>
		<link>https://blog.developpez.com/elsuket/p8701/moteur-de-base-de-donnees-sql-server/indexation/lister_les_colonnes_des_index_d_une_base</link>
		<comments>https://blog.developpez.com/elsuket/p8701/moteur-de-base-de-donnees-sql-server/indexation/lister_les_colonnes_des_index_d_une_base#comments</comments>
		<pubDate>Mon, 08 Mar 2010 12:36:14 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une petite requête qui permet de lister les colonnes de tous les index d&#8217;une base de données, avec leur type et l&#8217;ordre des colonnes dans la clé de l&#8217;index : 123456789101112131415161718192021------------------------------- -- Nicolas SOUQUET - 08/03/2010 ------------------------------- -- SQL &#8230; <a href="https://blog.developpez.com/elsuket/p8701/moteur-de-base-de-donnees-sql-server/indexation/lister_les_colonnes_des_index_d_une_base">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une petite requête qui permet de lister les colonnes de tous les index d&rsquo;une base de données, avec leur type et l&rsquo;ordre des colonnes dans la clé de l&rsquo;index :<br />
<span id="more-26"></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 /></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 - 08/03/2010 <br />
------------------------------- <br />
-- SQL Server 2005 et 2008 <br />
SELECT &nbsp; &nbsp;T.name AS nom_table <br />
&nbsp; &nbsp; , I.type_desc AS type_index <br />
&nbsp; &nbsp; , I.name AS nom_index <br />
&nbsp; &nbsp; , C.name AS nom_colonne <br />
&nbsp; &nbsp; , IC.key_ordinal AS position_colonne <br />
&nbsp; &nbsp; , IC.is_included_column AS is_included <br />
FROM &nbsp; &nbsp;sys.tables AS T <br />
INNER JOIN &nbsp;sys.indexes AS I <br />
&nbsp; &nbsp; &nbsp; ON T.object_id = I.object_id <br />
INNER JOIN &nbsp;sys.index_columns AS IC <br />
&nbsp; &nbsp; &nbsp; ON I.object_id = IC.object_id <br />
&nbsp; &nbsp; &nbsp; AND I.index_id = IC.index_id <br />
INNER JOIN &nbsp;sys.columns AS C <br />
&nbsp; &nbsp; &nbsp; ON IC.object_id = C.object_id <br />
&nbsp; &nbsp; &nbsp; AND IC.column_id = C.column_id <br />
--WHERE &nbsp; &nbsp;T.name = 'maTable' <br />
ORDER BY &nbsp;T.name, I.name, IC.key_ordinal</div></td></tr></tbody></table></div>
<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 /></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 - 20/07/2010 <br />
------------------------------- <br />
-- SQL Server 2000 <br />
&nbsp;<br />
SELECT &nbsp; &nbsp;T.name AS table_name <br />
&nbsp; &nbsp; , I.name AS index_name <br />
&nbsp; &nbsp; , CASE I.indid <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN 'CLUSTER' <br />
&nbsp; &nbsp; &nbsp; ELSE 'NON-CLUSTER' <br />
&nbsp; &nbsp; END AS index_type <br />
&nbsp; &nbsp; , C.name AS column_name <br />
&nbsp; &nbsp; , IK.keyno AS index_key_col_pos <br />
FROM &nbsp; &nbsp;sysindexes AS I <br />
INNER JOIN &nbsp;sysobjects AS T <br />
&nbsp; &nbsp; &nbsp; ON I.id = T.id <br />
INNER JOIN &nbsp;sysindexkeys AS IK <br />
&nbsp; &nbsp; &nbsp; ON I.id = IK.id <br />
&nbsp; &nbsp; &nbsp; AND I.indid = IK.indid <br />
INNER JOIN &nbsp;syscolumns AS C <br />
&nbsp; &nbsp; &nbsp; ON IK.id = C.id <br />
&nbsp; &nbsp; &nbsp; AND IK.colid = C.colid <br />
WHERE &nbsp; &nbsp;T.type = 'U' <br />
AND &nbsp; &nbsp;I.name NOT LIKE '%_!WA!_Sys!_%' ESCAPE '!' <br />
AND &nbsp; &nbsp;I.indid &gt; 0 <br />
ORDER BY &nbsp;T.name, I.name</div></td></tr></tbody></table></div>
<p>Bonne indexation !</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Configurer les protocoles de connexion réseau à SQL Server : l&#8217;utilitaire SQL Server Configuration Manager</title>
		<link>https://blog.developpez.com/elsuket/p7723/moteur-de-base-de-donnees-sql-server/configurer_les_protocoles_de_connexion_a</link>
		<comments>https://blog.developpez.com/elsuket/p7723/moteur-de-base-de-donnees-sql-server/configurer_les_protocoles_de_connexion_a#comments</comments>
		<pubDate>Mon, 08 Jun 2009 23:03:43 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[SQL Server 2005 a introduit l&#8217;outil SQL Server Configuration Manager, qui permet de gérer les fonctionnalités des instances SQL Server hébergées par un serveur, mais aussi la configuration du réseau. Ces problèmes sont souvent abordés sur le forum, et sont &#8230; <a href="https://blog.developpez.com/elsuket/p7723/moteur-de-base-de-donnees-sql-server/configurer_les_protocoles_de_connexion_a">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>SQL Server 2005 a introduit l&rsquo;outil <em>SQL Server Configuration Manager</em>, qui permet de gérer les fonctionnalités des instances SQL Server hébergées par un serveur, mais aussi la configuration du réseau.<br />
Ces problèmes sont souvent abordés sur le <a href="http://www.developpez.net/forums/f49/bases-donnees/ms-sql-server/">forum</a>, et sont souvent résolus par une description des manipulations à effectuer sous cet utilitaire.</p>
<p>Les voici ici &#8230;</p>
<p><span id="more-127"></span></p>
<p>L&rsquo;outil <em>SQL Server Configuration Manager</em> sert à configurer les instances de SQL Server seulement sur la machine qui le supporte (pas d&rsquo;accès distant possible).<br />
On peut accéder à celui-ci de deux façons :</p>
<p>&#8211; Soit par le menu <em>Démarrer</em>, en choisissant successivement <em>Programmes</em>|<em>Microsoft SQL Server 2008</em>|<em>Outils de configuration</em>|<em>Gestionnaire de configuration SQL Server</em></p>
<p>&#8211; Soit par la commande <em>Exécuter</em> du menu <em>Démarrer</em>, en saisissant :</p>
<pre>
	- pour SQL Server 2005 : SQLServerManager.msc
	- pour SQL Server 2008 : SQLServerManager10.msc
</pre>
<p>Dans les deux cas, l&rsquo;interface affichée est :</p>
<p><img src="http://blog.developpez.com/media/sscm.PNG" width="561" height="223" alt="" /></p>
<p>Pour configurer les protocoles d&rsquo;accès réseau à l&rsquo;instance SQL Server, il suffit, dans le volet de gauche, de double-cliquer sur &laquo;&nbsp;<em>Configuration du réseau SQL Server</em>&laquo;&nbsp;, puis de faire de même sur &laquo;&nbsp;<em>Protocoles pour monInstanceDeSQLServer</em>&laquo;&nbsp;.</p>
<p>Après une installation fraîche de SQL Server, on obtient l&rsquo;affichage suivant :</p>
<p><img src="http://blog.developpez.com/media/sscmprotocoles.PNG" width="529" height="180" alt="" /></p>
<p>Une boite de dialogue différente s&rsquo;affiche pour chacun des protocoles.<br />
Nous ne verrons ici que la boîte de dialogue &laquo;&nbsp;TCP/IP&nbsp;&raquo;, qui s&rsquo;affiche par un double-clic sur le protocole de même nom :</p>
<p><img src="http://blog.developpez.com/media/sscmtcpip.PNG" width="395" height="440" alt="" /></p>
<p>Il suffit de cliquer dans la liste déroulante sur &laquo;&nbsp;oui&nbsp;&raquo; pour activer le protocole TCP/IP.</p>
<p>Passons à l&rsquo;onglet &laquo;&nbsp;<em>Adresses IP</em>&nbsp;&raquo; :</p>
<p><img src="http://blog.developpez.com/media/sscmadressesip.PNG" width="395" height="440" alt="" /></p>
<p>Ici vous devez choisir oui dans la liste déroulante de l&rsquo;option &laquo;&nbsp;Actif&nbsp;&raquo;, puis vous pouvez configurer trois adresses IP et leurs ports (le port par défaut d&rsquo;écoute d&rsquo;une instance SQL Server, si elle est la seule hébergé sur le serveur, est 1433.<br />
Notez que le port 1434 est également utilisé par défaut pour les connexions d&rsquo;administration dédiées).</p>
<p>Dès que vous avez terminé la configuration, après validation de la configuration, vous obtenez la boîte de dialogue suivante :</p>
<p><img src="http://blog.developpez.com/media/sscmredemarre.PNG" width="744" height="126" alt="" /></p>
<p>Vous pouvez redémarrer le service SQL Server toujours dans cet utilitaire : dans le volet de gauche de la console, choisissez &laquo;&nbsp;Service SQL Server&nbsp;&raquo;, puis choisissez le service de l&rsquo;instance que vous venez de configurer en effectuant un clic-droit :</p>
<p><img src="http://blog.developpez.com/media/sscmredemarre2.PNG" width="590" height="266" alt="" /></p>
<p>Deux options s&rsquo;offrent à vous pour redémarrer le service : le bouton de la barre d&rsquo;outils, ou l&rsquo;option &laquo;&nbsp;<em>Redémarrer</em>&laquo;&nbsp;.<br />
Il est important de configurer cela dès l&rsquo;installation d&rsquo;une nouvelle instance de SQL Server, car tout redémarrage du service entraîne la perte des caches de procédure et de données du moteur de base de données &#8230;</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Compresser tous les backups sans modifier du code ou un plan de maintnenance avec SQL Server 2008</title>
		<link>https://blog.developpez.com/elsuket/p9040/moteur-de-base-de-donnees-sql-server/compresser_tous_les_backups_sans_modifie_2008</link>
		<comments>https://blog.developpez.com/elsuket/p9040/moteur-de-base-de-donnees-sql-server/compresser_tous_les_backups_sans_modifie_2008#comments</comments>
		<pubDate>Wed, 23 Jun 2010 09:44:49 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[SQL Server 2008 a introduit la compression des sauvegardes, qui, bien que consommatrice de CPU, permet de gagner en temps d&#8217;exécution et en espace disque. Si l&#8217;on a porté une procédure stockée de gestion des sauvegardes ou un plan de &#8230; <a href="https://blog.developpez.com/elsuket/p9040/moteur-de-base-de-donnees-sql-server/compresser_tous_les_backups_sans_modifie_2008">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>SQL Server 2008 a introduit la compression des sauvegardes, qui, bien que consommatrice de CPU, permet de gagner en temps d&rsquo;exécution et en espace disque.<br />
Si l&rsquo;on a porté une procédure stockée de gestion des sauvegardes ou un plan de maintenance, on peut s&rsquo;éviter de modifier leur code pour les compression à l&rsquo;aide d&rsquo;une option de serveur : <em>backup compression default</em></p>
<p>Il suffit pour cela 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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">EXEC sp_configure 'backup compression default', '1'<br />
GO<br />
RECONFIGURE<br />
GO</div></td></tr></tbody></table></div>
<p>pour activer la compression de toutes les sauvegardes.</p>
<p>Et bon backups <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>0</slash:comments>
		</item>
		<item>
		<title>Installer le iFilter pour fichiers PDF pour la recherche full-text</title>
		<link>https://blog.developpez.com/elsuket/p8960/moteur-de-base-de-donnees-sql-server/full-text/installer_le_ifilter_pour_fichiers_pdf_p</link>
		<comments>https://blog.developpez.com/elsuket/p8960/moteur-de-base-de-donnees-sql-server/full-text/installer_le_ifilter_pour_fichiers_pdf_p#comments</comments>
		<pubDate>Tue, 01 Jun 2010 13:26:18 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Full-Text]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici comment installer le iFilter pour les fichiers PDF sous SQL Server 2008 : => Télécharger le iFilter PDF Il suffit de se rendre sur cette page. Les différentes versions des iFilters PDF apparaissent sous la section Updates/Programs. => Installer &#8230; <a href="https://blog.developpez.com/elsuket/p8960/moteur-de-base-de-donnees-sql-server/full-text/installer_le_ifilter_pour_fichiers_pdf_p">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici comment installer le iFilter pour les fichiers PDF sous SQL Server 2008 :<br />
<span id="more-164"></span></p>
<p>=> <strong>Télécharger le iFilter PDF</strong></p>
<p>Il suffit de se rendre sur cette <a href="http://www.adobe.com/support/downloads/product.jsp?product=1&amp;platform=Windows">page</a>.<br />
Les différentes versions des iFilters PDF apparaissent sous la section <em>Updates/Programs</em>.</p>
<p>=> <strong>Installer le iFilter PDF</strong></p>
<p>Après avoir téléchargé le iFilter, il suffit de l&rsquo;installer comme on installe toute application</p>
<p>=> <strong>Faire rechercher à SQL Server tous les iFilters</strong></p>
<p>Il suffit pour cela d&rsquo;exécuter dans une fenêtre de requête, sous SQL Server Management Studio :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">-- Demande au service de recherche en texte intégral de charger tous les filtres disponibles <br />
EXEC sp_fulltext_service 'load_os_resources',1 <br />
&nbsp;<br />
-- Demande au service de recherche en texte intégral de ne pas vérifier la signature des fichiers de filtre <br />
EXEC sp_fulltext_service 'verify_signature', 0 <br />
&nbsp;<br />
-- Demande au service de recherche en texte intégral de mettre à jour les filtres et langages <br />
EXEC sp_fulltext_service 'update_languages', 1</div></td></tr></tbody></table></div>
<p>Et d&rsquo;exécuter la requête suivante pour vérifier l&rsquo;installation du filtre :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT &nbsp;* <br />
FROM &nbsp;sys.fulltext_document_types <br />
WHERE &nbsp;document_type = '.pdf'</div></td></tr></tbody></table></div>
<p>En effet dès SQL Server 2008, comme le moteur de recherche de texte intégral est intégré à celui de base de données, il n&rsquo;y a plus besoin de redémarrer le service correspondant.<br />
l&rsquo;option <em>update_languages</em> permet cela, et apparaît seulement sous SQL Server 2008.</p>
<p>Et bonne recherches de texte !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Administrer les services SQL Server à distance</title>
		<link>https://blog.developpez.com/elsuket/p8943/moteur-de-base-de-donnees-sql-server/administrer_les_services_sql_server_a_di</link>
		<comments>https://blog.developpez.com/elsuket/p8943/moteur-de-base-de-donnees-sql-server/administrer_les_services_sql_server_a_di#comments</comments>
		<pubDate>Fri, 28 May 2010 05:15:59 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Jour férié, je jette un œil à mes e-mails car l&#8217;entreprise dans laquelle je travaille a plusieurs sites de développement à travers le monde et qu&#8217;aujourd&#8217;hui n&#8217;est donc pas férié pour tout le monde. Un développeur me précise qu&#8217;il ne &#8230; <a href="https://blog.developpez.com/elsuket/p8943/moteur-de-base-de-donnees-sql-server/administrer_les_services_sql_server_a_di">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Jour férié, je jette un œil à mes e-mails car l&rsquo;entreprise dans laquelle je travaille a plusieurs sites de développement à travers le monde et qu&rsquo;aujourd&rsquo;hui n&rsquo;est donc pas férié pour tout le monde.<br />
Un développeur me précise qu&rsquo;il ne peut plus accéder à l&rsquo;instance SQL Server Analysis Services.<br />
Je m&rsquo;empresse donc d&rsquo;établir une connexion VPN pour prendre le contrôle du serveur et voir ce qui s&rsquo;y passe, et là surprise : erreur de protocole.<br />
Je me penche donc vers la console de services sur ma machine pour voir si je peux gérer les services du serveur à distance, et la réponse est &#8230; oui !<br />
Voyons comment faire :<br />
<span id="more-100"></span><br />
Le étapes décrites ici ont été exécutées sous Windows 7, mais je pense qu&rsquo;on peut facilement les reproduire sur les versions antérieures.</p>
<p>Dans le menu démarrer, rechercher services.msc :</p>
<p><img src="http://blog.developpez.com/media/1.png" width="468" height="489" alt="" /></p>
<p>En cliquant sur le résultat, la console d&rsquo;administration des services s&rsquo;ouvre, et on peut alors choisir d&rsquo;administrer les services d&rsquo;une autre machine :</p>
<p><img src="http://blog.developpez.com/media/2.png" width="396" height="281" alt="" /></p>
<p>Le nom de la machine nous est immédiatement demandé :</p>
<p><img src="http://blog.developpez.com/media/3.png" width="525" height="253" alt="" /></p>
<p>Et après quelques secondes, nous obtenons la liste des services de la machine :</p>
<p><img src="http://blog.developpez.com/media/4.png" width="809" height="571" alt="" /></p>
<p>On peut alors gérer le service (démarrer, arrêter, redémarrer, &#8230;), changer son compte d&rsquo;exécution, le désactiver, &#8230;</p>
<p><strong>Attention à ne pas arrêter ou redémarrer le service SQL Server d&rsquo;une machine de production</strong> : la coupure de service est quasiment immédiate et peut conduire à des défauts d&rsquo;intégrité des bases de données au redémarrage du service, en plus de la <a href="http://blog.developpez.com/elsuket/p6630/indexation/purge-du-cache-de-plans/">perte des caches</a> et de la réinitialisation de données de performance collectées jusque-là &#8230;</p>
<p>Bonne administration !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Quelle différences y-a-t-il entre TRUNCATE et DELETE ?</title>
		<link>https://blog.developpez.com/elsuket/p8929/moteur-de-base-de-donnees-sql-server/quelle_differences_y_a_t_il_entre_trunca</link>
		<comments>https://blog.developpez.com/elsuket/p8929/moteur-de-base-de-donnees-sql-server/quelle_differences_y_a_t_il_entre_trunca#comments</comments>
		<pubDate>Fri, 21 May 2010 06:03:41 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[TRUNCATE et DELETE peuvent avoir le même effet sur une table si le DELETE n&#8217;a pas de clause WHERE. Mais est-ce bien la même chose qui se passe au niveau des données ? En réalité, ces deux instructions ont bien &#8230; <a href="https://blog.developpez.com/elsuket/p8929/moteur-de-base-de-donnees-sql-server/quelle_differences_y_a_t_il_entre_trunca">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>TRUNCATE et DELETE peuvent avoir le même effet sur une table si le DELETE n&rsquo;a pas de clause WHERE.<br />
Mais est-ce bien la même chose qui se passe au niveau des données ?</p>
<p><span id="more-9"></span></p>
<p>En réalité, ces deux instructions ont bien des éléments qui les différencient :</p>
<p>=> TRUNCATE est une instruction DDL, alors que DELETE est une instruction DML.<br />
Conséquence directe : TRUNCATE ne peut pas avoir de clause WHERE.</p>
<p>=> TRUNCATE ne peut pas être exécuté :
<ol>
<li>sur une table disposant de contraintes d&rsquo;intégrité (clé primaire référencée par au moins une table,  et clés étrangères)</li>
<li>sur une table qui est répliquée</li>
<li>dans une base de données répliquée par envoi de journaux</li>
</ol>
<p>DELETE peut l&rsquo;être si les contraintes d&rsquo;intégrité restent respectées.</p>
<p>=> TRUNCATE ne déclenche pas un trigger sur DELETE, ce qui est le cas pour DELETE.<br />
Donc l&rsquo;utilisation de TRUNCATE peut causer des problèmes de consistance des données, car si l&rsquo;on a supprimé les contraintes d&rsquo;intégrité pour pouvoir exécuter un TRUNCATE, le traitement du trigger sur DELETE ne sera pas exécuté non plus.</p>
<p>=> TRUNCATE enregistre dans le fichier du journal des transactions les pages de données désallouées, et supprime les pointeurs des index.<br />
C&rsquo;est ce qui fait que TRUNCATE est plus rapide à s&rsquo;exécuter que DELETE : TRUNCATE utilise très peu de verrous par rapport à DELETE, qui nécessite dont plus de ressources disque.<br />
En effet, DELETE enregistre dans le fichier du journal des transactions toutes les données de chaque ligne affectée par l&rsquo;instruction.<br />
En realité donc, TRUNCATE n&rsquo;efface pas les données contenues dans les pages, mais marque celles-ci comme réutilisables.<br />
DELETE en revanche supprime physiquement les données.</p>
<p>=> En conséquence, les données supprimées par un DELETE sont restaurables; les données &laquo;&nbsp;supprimées&nbsp;&raquo; par un TRUNCATE ne le sont pas.</p>
<p>=> TRUNCATE réinitialise la valeur d&rsquo;une colonne de type entier avec la propriété d&rsquo;auto-incrémentation (IDENTITY). DELETE laisse cette valeur inchangée.</p>
<p>Et bonne suppression de données <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>2</slash:comments>
		</item>
		<item>
		<title>Trouver l&#8217;espace disque occupé par les fichiers, et l&#8217;espace libre dans ceux-ci</title>
		<link>https://blog.developpez.com/elsuket/p8540/moteur-de-base-de-donnees-sql-server/trouver_l_espace_disque_occupe_par_les_f</link>
		<comments>https://blog.developpez.com/elsuket/p8540/moteur-de-base-de-donnees-sql-server/trouver_l_espace_disque_occupe_par_les_f#comments</comments>
		<pubDate>Wed, 12 May 2010 09:08:49 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Non documenté]]></category>
		<category><![CDATA[Utilitaires]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici quelques requêtes pour vous permettre d&#8217;auditer vos fichiers de base de données : => Par une requête 12345678910111213141516171819202122232425------------------------------- -- Nicolas SOUQUET - 26/01/2010 ------------------------------- ;WITH &#160; &#160; CTE AS &#160; &#160; ( &#160; &#160; &#160; SELECT name AS nomLogique, &#8230; <a href="https://blog.developpez.com/elsuket/p8540/moteur-de-base-de-donnees-sql-server/trouver_l_espace_disque_occupe_par_les_f">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici quelques requêtes pour vous permettre d&rsquo;auditer vos fichiers de base de données :<br />
<span id="more-96"></span><br />
=> <strong>Par une requête</strong></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 - 26/01/2010 <br />
------------------------------- <br />
;WITH &nbsp; <br />
&nbsp; CTE AS &nbsp; <br />
&nbsp; ( &nbsp; <br />
&nbsp; &nbsp; SELECT name AS nomLogique, &nbsp;<br />
&nbsp; &nbsp; &nbsp; physical_name AS nomPhysique, &nbsp;<br />
&nbsp; &nbsp; &nbsp; CASE is_percent_growth <br />
&nbsp; WHEN 0 THEN CAST(growth * 8 / 1024 AS VARCHAR(8)) + ' MB' <br />
&nbsp; ELSE CAST(growth AS VARCHAR(3)) + ' %' <br />
&nbsp; &nbsp; &nbsp; END AS accroissement, &nbsp;<br />
&nbsp; &nbsp; &nbsp; CAST((size * 8) / CAST(1024 AS NUMERIC(14, 2)) AS NUMERIC(14, 2)) AS tailleFichier_MB, &nbsp;<br />
&nbsp; &nbsp; &nbsp; CAST((FILEPROPERTY(name, 'SpaceUsed') * 8) / CAST(1024 AS NUMERIC(14, 2)) AS NUMERIC(14, 2)) AS espaceOccupe &nbsp;<br />
&nbsp; &nbsp; FROM sys.database_files &nbsp;<br />
&nbsp; ) &nbsp;<br />
SELECT nomLogique, &nbsp;<br />
&nbsp; nomPhysique, &nbsp;<br />
&nbsp; tailleFichier_MB, &nbsp;<br />
&nbsp; accroissement, &nbsp;<br />
&nbsp; espaceOccupe AS espaceOccupe_MB, &nbsp;<br />
&nbsp; tailleFichier_MB - espaceOccupe AS espaceLibre_MB, &nbsp;<br />
&nbsp; CAST((CAST(espaceOccupe AS NUMERIC(14, 2)) / tailleFichier_MB) * 100 AS NUMERIC(14, 2)) AS [%occupe], &nbsp;<br />
&nbsp; CAST((CAST(tailleFichier_MB - espaceOccupe AS NUMERIC(14, 2)) / tailleFichier_MB) * 100 AS NUMERIC(14, 2)) AS [%libre] &nbsp;<br />
FROM CTE</div></td></tr></tbody></table></div>
<p>=> <strong>Avec l&rsquo;instruction DBCC SHOWFILESTATS</strong> (<strong>non documentée</strong>):</p>
<p>Elle donne le nombre d&rsquo;étendues (extents) occupées et le nombre total d&rsquo;étendues allouées pour le fichier.<br />
Une étendue étant constituée de 8 pages, et une page faisant 8192 octets, il vous faudra donc multiplier les nombres obtenus par 64Ko.</p>
<p>=> <strong>Avec la procédure stockée système sp_spaceused</strong> :</p>
<p>Elle retourne deux ensemble de résultats :<br />
&#8211; l&rsquo;espace occupé pour toute la base de données, mais attention seulement l&rsquo;espace libre dans le fichier de données.<br />
&#8211; le nombre de Ko réservés (= taille du fichier), utilisés (colonne data), dédiés aux index et inutilisés.</p>
<p>=> <strong>Avec l&rsquo;instruction DBCC SQLPERF(logspace)</strong></p>
<p>Celle-ci ne procure que la taille totale du fichier du journal des transactions, ainsi que son pourcentage d&rsquo;occupation.</p>
<p>Bonne gestion d&rsquo;espace disque <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p>ElSuket.</p>
<p>=>=>=> <strong>12/05/2010 : MAJ :  un script pour connaître l&rsquo;espace occupé par et dans les fichiers, pour toutes les bases de données d&rsquo;une instance SQL Server :</strong></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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">------------------------------- <br />
-- 12/05/2010 - Nicolas SOUQUET <br />
------------------------------- <br />
SET NOCOUNT ON <br />
GO <br />
&nbsp;<br />
DECLARE @sql varchar(1024) <br />
SET @sql = 'SELECT name AS file_logical_name,' + CHAR(13) + CHAR(10) + CHAR(9) + <br />
&nbsp; 'physical_name AS file_physical_name,' + CHAR(13) + CHAR(10) + CHAR(9) + <br />
&nbsp; 'CASE is_percent_growth' + CHAR(13) + CHAR(10) + CHAR(9) + CHAR(9) + <br />
&nbsp; 'WHEN 0 THEN CAST(growth * 8 / 1024 AS varchar(8)) + '''' MB''''' + CHAR(13) + CHAR(10) + CHAR(9) + CHAR(9) + <br />
&nbsp; 'ELSE CAST(growth AS varchar(3)) + '''' %''''' + CHAR(13) + CHAR(10) + CHAR(9) + <br />
&nbsp; 'END AS file_growth,' + CHAR(13) + CHAR(10) + CHAR(9) + <br />
&nbsp; 'CAST((size * 8) / CAST(1024 AS numeric(14, 2)) AS numeric(14, 2)) AS file_size_MB,' + CHAR(13) + CHAR(10) + CHAR(9) + <br />
&nbsp; 'CAST((FILEPROPERTY(name, ''''SpaceUsed'''') * 8) / CAST(1024 AS numeric(14, 2)) AS numeric(14, 2)) AS file_used_space_MB' + CHAR(13) + CHAR(10) + <br />
&nbsp; 'FROM sys.database_files''' + CHAR(13) + CHAR(10) <br />
&nbsp; <br />
DECLARE @exec_sql varchar(1024) <br />
&nbsp;<br />
DECLARE @instance_database_file_space TABLE <br />
( <br />
&nbsp; database_name sysname <br />
&nbsp; , file_logical_name sysname <br />
&nbsp; , file_physical_name nvarchar(260) &nbsp;<br />
&nbsp; , file_growth varchar(8) <br />
&nbsp; , file_size_MB numeric(14,2) <br />
&nbsp; , file_used_space_MB numeric(14,2) <br />
&nbsp; , file_free_space_MB numeric(14,2) <br />
&nbsp; , file_used_space_percent numeric(5,2) <br />
&nbsp; , file_free_space_percent numeric(5,2) <br />
) <br />
&nbsp;<br />
DECLARE @database_file_space TABLE <br />
( <br />
&nbsp; file_logical_name sysname <br />
&nbsp; , file_physical_name nvarchar(260) &nbsp;<br />
&nbsp; , file_growth varchar(8) <br />
&nbsp; , file_size_MB numeric(14,2) <br />
&nbsp; , file_used_space_MB numeric(14,2) <br />
) <br />
&nbsp;<br />
DECLARE db_cur CURSOR LOCAL FAST_FORWARD FOR <br />
&nbsp; SELECT &nbsp;name <br />
&nbsp; FROM &nbsp;sys.databases <br />
&nbsp; WHERE &nbsp;source_database_id IS NULL <br />
FOR READ ONLY <br />
&nbsp;<br />
DECLARE @database_name sysname <br />
&nbsp;<br />
OPEN db_cur <br />
FETCH NEXT FROM db_cur INTO @database_name <br />
WHILE @@fetch_status = 0 <br />
BEGIN <br />
&nbsp; DELETE &nbsp;@database_file_space <br />
&nbsp;<br />
&nbsp; SET @exec_sql = 'EXEC ' + @database_name + '.dbo.sp_executeSQL N''' + @sql + '' <br />
&nbsp;<br />
&nbsp; BEGIN TRY <br />
&nbsp; &nbsp; INSERT &nbsp;@database_file_space <br />
&nbsp; &nbsp; EXEC &nbsp;(@exec_sql) <br />
&nbsp; END TRY <br />
&nbsp; BEGIN CATCH <br />
&nbsp; &nbsp; PRINT @database_name + ' : ' + ERROR_MESSAGE() <br />
&nbsp; END CATCH <br />
&nbsp; <br />
&nbsp; INSERT &nbsp;@instance_database_file_space <br />
&nbsp; SELECT &nbsp;@database_name <br />
&nbsp; &nbsp; , file_logical_name <br />
&nbsp; &nbsp; , file_physical_name <br />
&nbsp; &nbsp; , file_growth <br />
&nbsp; &nbsp; , file_size_MB <br />
&nbsp; &nbsp; , file_used_space_MB <br />
&nbsp; &nbsp; , file_size_MB - file_used_space_MB AS file_free_space_MB <br />
&nbsp; &nbsp; , CAST((CAST(file_used_space_MB AS numeric(14, 2)) / file_size_MB) * 100 AS numeric(14, 2)) AS file_used_space_percent <br />
&nbsp; &nbsp; , CAST((CAST(file_size_MB - file_used_space_MB AS numeric(14, 2)) / file_size_MB) * 100 AS numeric(14, 2)) AS file_free_space_percent <br />
&nbsp; FROM &nbsp;@database_file_space <br />
&nbsp; <br />
&nbsp; FETCH NEXT FROM db_cur INTO @database_name <br />
END <br />
CLOSE db_cur <br />
DEALLOCATE db_cur <br />
&nbsp;<br />
SELECT &nbsp;* <br />
FROM &nbsp;@instance_database_file_space</div></td></tr></tbody></table></div>
<p>Il arrive que la procédure stockée système sp_executeSQL ne soit pas trouvée dans la base de données.<br />
Quand tel est le cas, la liste des bases de données est affichée dans la console de SSMS.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Une procédure pour connaître l&#8217;état physique et l&#8217;utilisation des index</title>
		<link>https://blog.developpez.com/elsuket/p8901/moteur-de-base-de-donnees-sql-server/indexation/une_procedure_pour_connaitre_letait_phys</link>
		<comments>https://blog.developpez.com/elsuket/p8901/moteur-de-base-de-donnees-sql-server/indexation/une_procedure_pour_connaitre_letait_phys#comments</comments>
		<pubDate>Tue, 04 May 2010 14:26:11 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une petite procédure stockée qui permet de connaître l&#8217;état physique des index (nombre de pages du niveau feuille, fragmentation et taux d&#8217;utilisation des pages) en même temps que la façon dont ils sont utilisés (nombres de seeks et de &#8230; <a href="https://blog.developpez.com/elsuket/p8901/moteur-de-base-de-donnees-sql-server/indexation/une_procedure_pour_connaitre_letait_phys">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une petite procédure stockée qui permet de connaître l&rsquo;état physique des index (nombre de pages du niveau feuille, fragmentation et taux d&rsquo;utilisation des pages) en même temps que la façon dont ils sont utilisés (nombres de seeks et de scans, &#8230;).</p>
<p>Elle est utilisable pour collecter ces statistiques sur l&rsquo;ensemble d&rsquo;une base de données, ou bien sur une table en particulier<br />
<span id="more-27"></span></p>
<p>Voici le code :</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 /></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 - 04/05/2010 <br />
------------------------------- <br />
CREATE PROCEDURE ps_get_index_stats <br />
&nbsp; @_table_name sysname = NULL <br />
AS <br />
BEGIN <br />
&nbsp; SET NOCOUNT ON <br />
&nbsp;<br />
&nbsp; -- Si le nom de la table n'exsite pas, <br />
&nbsp; -- alors cela revient à passer NULL en object_id à la fonction sys.dm_db_index_physical_stats <br />
&nbsp; -- ce qui a pour effet de collecter toutes les statististiques de tous les index de la BD <br />
&nbsp; IF <br />
&nbsp; ( <br />
&nbsp; &nbsp; @_table_name IS NOT NULL <br />
&nbsp; &nbsp; AND NOT EXISTS <br />
&nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; SELECT &nbsp;* <br />
&nbsp; &nbsp; &nbsp; FROM &nbsp;sys.tables <br />
&nbsp; &nbsp; &nbsp; WHERE &nbsp;name = @_table_name <br />
&nbsp; &nbsp; ) <br />
&nbsp; ) <br />
&nbsp; BEGIN <br />
&nbsp; &nbsp; RAISERROR('The table %s does not exist', 16, 1, @_table_name) <br />
&nbsp; &nbsp; RETURN <br />
&nbsp; END <br />
&nbsp;<br />
&nbsp; SELECT &nbsp; &nbsp;D.name AS database_name <br />
&nbsp; &nbsp; &nbsp; , O.name AS table_name <br />
&nbsp; &nbsp; &nbsp; , I.name AS index_name <br />
&nbsp; &nbsp; &nbsp; , CASE IPS.index_type_desc <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 'CLUSTERED INDEX' THEN 'CL' <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 'NONCLUSTERED INDEX' THEN 'N-CL' <br />
&nbsp; &nbsp; &nbsp; &nbsp; ELSE IPS.index_type_desc <br />
&nbsp; &nbsp; &nbsp; END AS index_type <br />
&nbsp; &nbsp; &nbsp; , IUS.user_updates <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; &nbsp; &nbsp; , IPS.index_depth <br />
&nbsp; &nbsp; &nbsp; , IPS.page_count <br />
&nbsp; &nbsp; &nbsp; , CAST(IPS.avg_fragmentation_in_percent AS decimal(5, 2)) AS frag <br />
&nbsp; &nbsp; &nbsp; , CAST(IPS.avg_page_space_used_in_percent AS decimal(5, 2)) AS page_usage <br />
&nbsp; &nbsp; &nbsp; , STATS_DATE(IPS.object_id, IPS.index_id) AS last_update <br />
&nbsp; FROM &nbsp; &nbsp;sys.dm_db_index_physical_stats <br />
&nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; DB_ID() -- Base de données <br />
&nbsp; &nbsp; &nbsp; &nbsp; , OBJECT_ID(@_table_name) -- Table <br />
&nbsp; &nbsp; &nbsp; &nbsp; , NULL -- Index <br />
&nbsp; &nbsp; &nbsp; &nbsp; , NULL -- Partition <br />
&nbsp; &nbsp; &nbsp; &nbsp; , 'DETAILED' -- Niveau de détail <br />
&nbsp; &nbsp; &nbsp; ) IPS <br />
&nbsp; LEFT JOIN &nbsp;sys.dm_db_index_usage_stats AS IUS <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON IUS.database_id = IPS.database_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; AND IUS.object_id = IPS.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; AND IUS.index_id = IPS.index_id <br />
&nbsp; INNER JOIN &nbsp;sys.databases AS D <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON D.database_id = IPS.database_id <br />
&nbsp; INNER JOIN &nbsp;sys.indexes AS I <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON I.object_id = IPS.object_id <br />
&nbsp; &nbsp; &nbsp; &nbsp; AND I.index_id = IPS.index_id <br />
&nbsp; INNER JOIN &nbsp;sys.objects AS O <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON O.object_id = IPS.object_id <br />
&nbsp; WHERE &nbsp; &nbsp;IPS.index_level = 0 <br />
&nbsp; AND &nbsp; &nbsp;IPS.alloc_unit_type_desc &lt;&gt; 'LOB_DATA' <br />
END</div></td></tr></tbody></table></div>
<p>Et deux exemples d&rsquo;utilisation :</p>
<p>=> <code class="codecolorer text default"><span class="text">EXEC ps_get_index_stats</span></code></p>
<p>Collecte les statistiques de tous les index de la base de données</p>
<p>=> <code class="codecolorer text default"><span class="text">EXEC ps_get_index_stats 'maTable'</span></code></p>
<p>Collecte les statistiques de tous les index de la table <em>maTable</em></p>
<p>Vous pouvez bien sûr modifier son code pour pouvoir filtrer par base de données, par index et par partition.</p>
<p>Attention en revanche, car si l&rsquo;on passe des paramètres incorrects (valeurs négatives ou pas de valeur (NULL)) aux fonctions DB_ID() et OBJECT_ID(), cela a pour effet de collecter toutes les statistiques avec comme granularité la plus élevée.</p>
<p>On peut utiliser ce script pour décider de la <a href="http://blog.developpez.com/elsuket/p7712/agent-sql-server/une-procedure-stockee-pour-defragmenter/">reconstruction</a> ou de la réorganisation d&rsquo;un index &#8230;</p>
<p>Bonne indexation <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>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>Trouver le nombre de lignes de toutes les tables d&#8217;une base de données</title>
		<link>https://blog.developpez.com/elsuket/p8110/moteur-de-base-de-donnees-sql-server/trouver_le_nombre_de_lignes_de_toutes_le</link>
		<comments>https://blog.developpez.com/elsuket/p8110/moteur-de-base-de-donnees-sql-server/trouver_le_nombre_de_lignes_de_toutes_le#comments</comments>
		<pubDate>Sun, 27 Sep 2009 17:55:28 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Il est intéressant, pour suivre l&#8217;évolution d&#8217;une base de données, et pour prévoir l&#8217;espace disque nécessaire, de connaître le nombre de lignes que contient chaque table. Ce qui vient en premier à l&#8217;esprit lorsqu&#8217;on souhaite quantifier les lignes, c&#8217;est d&#8217;exécuter &#8230; <a href="https://blog.developpez.com/elsuket/p8110/moteur-de-base-de-donnees-sql-server/trouver_le_nombre_de_lignes_de_toutes_le">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Il est intéressant, pour suivre l&rsquo;évolution d&rsquo;une base de données, et pour prévoir l&rsquo;espace disque nécessaire, de connaître le nombre de lignes que contient chaque table.</p>
<p>Ce qui vient en premier à l&rsquo;esprit lorsqu&rsquo;on souhaite quantifier les lignes, c&rsquo;est d&rsquo;exécuter un SELECT COUNT(*) sur chacune des tables à travers un curseur sur chacune des tables de la base de données, ou encore d&rsquo;user de la procédure stockée système sp_spaceused sur le même modèle.<br />
Mais il est évident que ce n&rsquo;est pas performant et le résultat est long à obtenir.<br />
Voyons comment obtenir cela sans effort, ni pour nous, ni pour le moteur de base de données &#8230;</p>
<p><span id="more-87"></span></p>
<p>Les tables et vues système exposent ces informations, mais de manière différente entre SQL Server 2000 et ses successeurs.</p>
<p><strong>Regardons tout d&rsquo;abord comment on peut obtenir le nombre de lignes de toutes les tables de la base de données en cours sous SQL Server 2000 :</strong></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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--------------------------------- <br />
-- 27/09/2009 - Nicolas SOUQUET - <br />
--------------------------------- <br />
SELECT O.name AS nomTable, <br />
&nbsp; I.rowcnt AS nbLignes <br />
FROM sysindexes AS I <br />
JOIN sysobjects AS O <br />
&nbsp; ON I.id = O.id <br />
&nbsp; AND O.xtype = 'U' <br />
&nbsp; AND I.indid &lt; 2</div></td></tr></tbody></table></div>
<p>La colonne indid de la table sysindexes peut prendre les valeurs suivantes :<br />
&#8211; 0 si la table n&rsquo;est pas ordonnée en cluster (c&rsquo;est donc un segment mémoire, ou heap)<br />
&#8211; 1 si la table est ordonnée en cluster<br />
&#8211; 2 pour tous les indexes non-cluster posés sur la table.</p>
<p><strong>Voyons maintenant comment faire sous SQL Server 2005 et 2008 :</strong></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 />
-- 27/09/2009 - Nicolas SOUQUET - <br />
--------------------------------- <br />
SELECT T.name AS table_name, <br />
&nbsp; PS.row_count <br />
FROM sys.dm_db_partition_stats AS PS <br />
JOIN sys.tables AS T ON PS.object_id = T.object_id <br />
WHERE PS.index_id BETWEEN 0 AND 1 <br />
ORDER BY T.name</div></td></tr></tbody></table></div>
<p>Comme on peut le voir, les deux requêtes sont très simples et permettent de ne pas bloquer l&rsquo;accès aux tables, ce qui s&rsquo;avèrera forcément appréciable sur des tables dont on sait que le nombre de lignes est important.</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Trouver les contraintes qui ne sont pas fiables</title>
		<link>https://blog.developpez.com/elsuket/p8759/moteur-de-base-de-donnees-sql-server/trouver_les_contraintes_qui_ne_sont_pas_</link>
		<comments>https://blog.developpez.com/elsuket/p8759/moteur-de-base-de-donnees-sql-server/trouver_les_contraintes_qui_ne_sont_pas_#comments</comments>
		<pubDate>Fri, 26 Mar 2010 09:27:19 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Pour faciliter le chargement de données, il est parfois nécessaire de désactiver une contrainte de domaine (CHECK) ou de clé étrangère, puis de la réactiver dès la fin du chargement. Si l&#8217;on écrit : ALTER TABLE maTable CHECK CONSTRAINT maContrainte &#8230; <a href="https://blog.developpez.com/elsuket/p8759/moteur-de-base-de-donnees-sql-server/trouver_les_contraintes_qui_ne_sont_pas_">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Pour faciliter le chargement de données, il est parfois nécessaire de désactiver une contrainte de domaine (CHECK) ou de clé étrangère, puis de la réactiver dès la fin du chargement.</p>
<p>Si l&rsquo;on écrit :</p>
<p><code class="codecolorer text default"><span class="text">ALTER TABLE maTable CHECK CONSTRAINT maContrainte</span></code></p>
<p>La contrainte est alors marquée comme non-fiable, et le moteur de bases de données ne s&rsquo;en sert plus dans ses plans de requête.<br />
Pire, cela signifie que l&rsquo;intégrité des données qui ont été importées est alors mise en défaut.</p>
<p>Il faut donc écrire :</p>
<p><code class="codecolorer text default"><span class="text">ALTER TABLE maTable WITH CHECK CHECK CONSTRAINT maContrainte</span></code></p>
<p>Pour que les valeurs ajoutées pendant que la contrainte était désactivée soient vérifiées.</p>
<p>Voici donc une petite requête pour trouver les contraintes qui ne sont plus fiables pour le moteur de base de données &#8230;</p>
<p><span id="more-99"></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 /></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 - 26/03/2010 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;name AS constraint_name <br />
&nbsp; &nbsp; , CASE KO <br />
&nbsp; &nbsp; &nbsp; WHEN 0 THEN 1 <br />
&nbsp; &nbsp; &nbsp; WHEN 1 THEN 0 <br />
&nbsp; &nbsp; END AS OK <br />
FROM <br />
( <br />
&nbsp; SELECT &nbsp; &nbsp;O.name <br />
&nbsp; &nbsp; &nbsp; , CASE O.type_desc <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 'CHECK_CONSTRAINT' THEN CHK.is_not_trusted <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHEN 'FOREIGN_KEY_CONSTRAINT' THEN FK.is_not_trusted <br />
&nbsp; &nbsp; &nbsp; END AS KO <br />
&nbsp; FROM &nbsp; &nbsp;sys.objects AS O <br />
&nbsp; LEFT JOIN &nbsp;sys.check_constraints AS CHK <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON CHK.object_id = O.object_id <br />
&nbsp; LEFT JOIN &nbsp;sys.foreign_keys AS FK <br />
&nbsp; &nbsp; &nbsp; &nbsp; ON FK.object_id = O.object_id <br />
&nbsp; WHERE <br />
&nbsp; ( <br />
&nbsp; &nbsp; &nbsp; CHK.object_id IS NOT NULL <br />
&nbsp; &nbsp; &nbsp; OR FK.object_id IS NOT NULL <br />
&nbsp; ) <br />
) <br />
AS SUB (name, KO)</div></td></tr></tbody></table></div>
<p>Et une autre pour scripter leur réactivation :</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 /></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 - 26/03/2009 <br />
------------------------------- <br />
SELECT &nbsp; &nbsp;'ALTER TABLE ' + T.name + ' WITH CHECK CHECK CONSTRAINT ' + O.name AS script <br />
FROM &nbsp; &nbsp;sys.objects AS O <br />
LEFT JOIN &nbsp;sys.check_constraints AS CHK <br />
&nbsp; &nbsp; &nbsp; ON CHK.object_id = O.object_id <br />
LEFT JOIN &nbsp;sys.foreign_keys AS FK <br />
&nbsp; &nbsp; &nbsp; ON FK.object_id = O.object_id <br />
LEFT JOIN &nbsp;sys.tables AS T <br />
&nbsp; &nbsp; &nbsp; ON O.parent_object_id = T.object_id <br />
WHERE <br />
( <br />
&nbsp; CHK.is_not_trusted = 1 <br />
&nbsp; OR FK.is_not_trusted = 1 <br />
)</div></td></tr></tbody></table></div>
<p>Bonne vérification d&rsquo;intégrité !</p>
<p>ElSüket.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Télécharger les filtres pour la recherche en texte intégral dans des documents Office 2007</title>
		<link>https://blog.developpez.com/elsuket/p8702/moteur-de-base-de-donnees-sql-server/full-text/telecharger_les_filtres_pour_la_recherch_2007</link>
		<comments>https://blog.developpez.com/elsuket/p8702/moteur-de-base-de-donnees-sql-server/full-text/telecharger_les_filtres_pour_la_recherch_2007#comments</comments>
		<pubDate>Mon, 08 Mar 2010 13:34:36 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Full-Text]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici où vous pourrez trouver la liste des filtres pour les documents de type .docx., .xlsx, .pptx, &#8230; qui vous permettront d&#8217;utiliser la recherche en texte intégral dans ce type de documents sous SQL Server. Bonne indexation full-text ! ElSuket]]></description>
				<content:encoded><![CDATA[<p>Voici <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=60C92A37-719C-4077-B5C6-CAC34F4227CC&amp;displaylang=fr">où</a> vous pourrez trouver la liste des filtres pour les documents de type .docx., .xlsx, .pptx, &#8230; qui vous permettront d&rsquo;utiliser la recherche en texte intégral dans ce type de documents sous SQL Server.</p>
<p>Bonne indexation full-text !</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lister les types définis par l&#8217;utilisateur, avec les défauts et règles qui leur sont liés, et les scripter</title>
		<link>https://blog.developpez.com/elsuket/p8612/moteur-de-base-de-donnees-sql-server/lister_les_types_definis_par_l_utilisate</link>
		<comments>https://blog.developpez.com/elsuket/p8612/moteur-de-base-de-donnees-sql-server/lister_les_types_definis_par_l_utilisate#comments</comments>
		<pubDate>Tue, 09 Feb 2010 03:10:07 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une petite requête qui permet de retrouver la liste de tous les types définis par l&#8217;utilisateur &#8230; Comme tout type créé par l&#8217;utilisateur est une dérivation d&#8217;un type de base, les valeurs de la colonne user_type_id dans la vue &#8230; <a href="https://blog.developpez.com/elsuket/p8612/moteur-de-base-de-donnees-sql-server/lister_les_types_definis_par_l_utilisate">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Voici une petite requête qui permet de retrouver la liste de tous les types définis par l&rsquo;utilisateur &#8230;<br />
<span id="more-97"></span><br />
Comme tout type créé par l&rsquo;utilisateur est une dérivation d&rsquo;un type de base, les valeurs de la colonne user_type_id dans la vue sys.types progressent tandis que celles de la colonne system_type_id restent limitées au nombre de types &laquo;&nbsp;de base&nbsp;&raquo; livrés avec l&rsquo;instance SQL Server.</p>
<p>Dès lors la requête suivante :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">------------------------------- <br />
-- 09/02/2009 - Nicolas SOUQUET <br />
------------------------------- <br />
SELECT name <br />
FROM sys.types <br />
WHERE user_type_id &gt; system_type_id <br />
ORDER BY name</div></td></tr></tbody></table></div>
<p>Retourne la liste de tous les types définis par l&rsquo;utilisateur.<br />
Néanmoins on peut en exclure sysname qui est une dérivation du type NVARCHAR pour les noms d&rsquo;objets.</p>
<p>Si l&rsquo;on souhaite trouver le nom et la définition T-SQL des défauts et règles qui sont liés (respectivement par sp_binddefault et sp_bindrule) à ces types, il faudra 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 />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 />
-- 09/02/2010 - Nicolas SOUQUET <br />
------------------------------- <br />
SELECT T.name AS nomType <br />
&nbsp; , D.name AS nomDefaut <br />
&nbsp; , DD.definition AS defautSQL <br />
&nbsp; , R.name AS nomRegle <br />
&nbsp; , DR.definition AS regleSQL <br />
FROM sys.types AS T <br />
LEFT JOIN sys.objects AS D <br />
&nbsp; ON D.object_id = T.default_object_id <br />
LEFT JOIN sys.sql_modules AS DD <br />
&nbsp; ON D.object_id = DD.object_id <br />
LEFT JOIN sys.objects AS R <br />
&nbsp; ON R.object_id = T.rule_object_id <br />
LEFT JOIN sys.sql_modules AS DR <br />
&nbsp; ON D.object_id = DR.object_id <br />
WHERE T.user_type_id &gt; T.system_type_id <br />
--AND T.name &lt;&gt; 'sysname' <br />
ORDER BY T.name</div></td></tr></tbody></table></div>
<p>On peut mettre en parallèle les types définis par l&rsquo;utilisateur avec les types de base :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">------------------------------- <br />
-- 09/02/2010 - Nicolas SOUQUET <br />
------------------------------- <br />
SELECT T.name AS table_name <br />
&nbsp; , C.name AS column_name <br />
&nbsp; , TY.name AS user_type_name <br />
&nbsp; , TYO.name AS type_name <br />
&nbsp; , CASE <br />
&nbsp; &nbsp; WHEN TYO.name IN ('nchar', 'nvarchar') THEN C.max_length / 2 <br />
&nbsp; &nbsp; ELSE C.max_length <br />
&nbsp; END AS max_length <br />
&nbsp; , C.max_length AS nbBytes <br />
FROM sys.tables AS T <br />
JOIN sys.columns AS C <br />
&nbsp; ON T.object_id = C.object_id <br />
JOIN sys.types AS TY <br />
&nbsp; ON C.user_type_id = TY.user_type_id <br />
JOIN sys.types AS TYO <br />
&nbsp; ON TY.system_type_id = TYO.system_type_id <br />
&nbsp; AND TYO.user_type_id = TYO.system_type_id <br />
WHERE T.name = 'radiology_procedure_plan_ref' <br />
ORDER BY C.column_id</div></td></tr></tbody></table></div>
<p>Si l&rsquo;on souhaite scripter la liaison d&rsquo;un défaut à un type, nous exécuterons :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">------------------------------- <br />
-- 09/02/2010 - Nicolas SOUQUET <br />
------------------------------- <br />
SELECT 'EXEC sp_bindefault @defname = ''' + D.name + '''' + ', @objname = ''' + T.name + '''' <br />
FROM sys.types AS T <br />
JOIN sys.objects AS D <br />
&nbsp; ON D.object_id = T.default_object_id</div></td></tr></tbody></table></div>
<p>Et similairement, pour scripter la liaison d&rsquo;une règle à un type :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">------------------------------- <br />
-- 09/02/2010 - Nicolas SOUQUET <br />
------------------------------- <br />
SELECT 'EXEC sp_bindrule @rulename = ''' + R.name + '''' + ', @objname = ''' + T.name + '''' <br />
FROM sys.types AS T <br />
JOIN sys.objects AS R <br />
&nbsp; ON R.object_id = T.rule_object_id</div></td></tr></tbody></table></div>
<p>Bon typage ! <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>0</slash:comments>
		</item>
		<item>
		<title>Vérifier l&#8217;unicité d&#8217;une position avec le type GEOGRAPHY sous SQL Server 2008</title>
		<link>https://blog.developpez.com/elsuket/p8257/moteur-de-base-de-donnees-sql-server/indexation/verifier_l_unicite_d_une_position_avec_l_2008</link>
		<comments>https://blog.developpez.com/elsuket/p8257/moteur-de-base-de-donnees-sql-server/indexation/verifier_l_unicite_d_une_position_avec_l_2008#comments</comments>
		<pubDate>Thu, 29 Oct 2009 22:33:34 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Systèmes d&#039;information géographiques]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[SQL Server 2008 a introduit de nombreux nouveaux types de données, dont le type de données géographiques GEOGRAPHY. Ce n&#8217;est pas un type habituel, puisque c&#8217;est un type CLR.NET intégré à SQL Server. L&#8217;avantage présenté par l&#8217;intégration de ce type &#8230; <a href="https://blog.developpez.com/elsuket/p8257/moteur-de-base-de-donnees-sql-server/indexation/verifier_l_unicite_d_une_position_avec_l_2008">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>SQL Server 2008 a introduit de nombreux nouveaux types de données, dont le type de données géographiques GEOGRAPHY.<br />
Ce n&rsquo;est pas un type habituel, puisque c&rsquo;est un type CLR.NET intégré à SQL Server.</p>
<p>L&rsquo;avantage présenté par l&rsquo;intégration de ce type est l&rsquo;ensemble des méthodes standard &laquo;&nbsp;livrées&nbsp;&raquo; avec ce type, qui permettent d&rsquo;extraire très simplement une latitude (attribut Lat), une longitude (attribut Long), ou encore de connaître la distance entre deux points géographiques avec la méthode <a href="http://msdn.microsoft.com/fr-fr/library/bb933808.aspx">STDistance</a>.</p>
<p>Mais il devient alors plus complexe de garantir l&rsquo;unicité de positions dans une table où l&rsquo;on stocke la celle de plusieurs villes.<br />
En effet, si une colonne de ce type est spécifiée comme clé d&rsquo;une contrainte d&rsquo;unicité, le moteur de base de données SQL Server lève une exception.</p>
<p>Est-il possible de contourner ce problème ?</p>
<p><span id="more-160"></span></p>
<p>Si nous tentons de créer la table suivante :</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">CREATE TABLE dbo.TbCoordonneeVille <br />
( <br />
&nbsp; IDCoordonneeVille INT NOT NULL IDENTITY CONSTRAINT PK_TbCoordonneeVille PRIMARY KEY, <br />
&nbsp; nomVille VARCHAR(45) NOT NULL CONSTRAINT UQ_TbCoordonneeVille_nomVille UNIQUE, <br />
&nbsp; geoPositionVille GEOGRAPHY NOT NULL CONSTRAINT UQ_TbCoordonneeVille_geoPositionVille UNIQUE &nbsp;<br />
)</div></td></tr></tbody></table></div>
<p>Nous obtenons l&rsquo;erreur :</p>
<blockquote><p>Msg 1919, Niveau 16, État 1, Ligne 1<br />
La colonne &lsquo;geoPositionVille&rsquo; dans la table &lsquo;TbCoordonneeVille&rsquo; n&rsquo;est pas d&rsquo;un type valide lui permettant d&rsquo;être utilisée en tant que colonne clé dans un index.<br />
Msg 1750, Niveau 16, État 0, Ligne 1<br />
Impossible de créer la contrainte. Voir les erreurs précédentes.</p></blockquote>
<p>Nous sommes donc contraints de créer la table sans la contrainte d&rsquo;unicité sur la colonne geoPositionVille :</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">CREATE TABLE dbo.TbCoordonneeVille <br />
( <br />
&nbsp; IDCoordonneeVille INT NOT NULL IDENTITY CONSTRAINT PK_TbCoordonneeVille PRIMARY KEY, <br />
&nbsp; nomVille VARCHAR(45) NOT NULL CONSTRAINT UQ_TbCoordonneeVille_nomVille UNIQUE, <br />
&nbsp; geoPositionVille GEOGRAPHY NOT NULL <br />
)</div></td></tr></tbody></table></div>
<p>Comment faire pour garantir l&rsquo;unicité des positions des villes sans perdre les avantages offerts par le type GEOGRAPHY ?<br />
Il est possible de créer une contrainte d&rsquo;unicité sur des colonnes calculées persistantes.</p>
<p>Ajoutons donc deux colonnes calculées, une pour la latitude, et une autre pour la longitude.<br />
Attention, la casse sur les méthodes CLR est importante.</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">------------------------------- <br />
-- Nicolas SOUQUET - 29/10/2009 <br />
------------------------------- <br />
ALTER TABLE dbo.TbCoordonneeVille <br />
ADD latitudeVille AS (geoPositionVille.Lat) PERSISTED NOT NULL, <br />
&nbsp; longitudeVille AS (geoPositionVille.Long) PERSISTED NOT NULL</div></td></tr></tbody></table></div>
<p>Il nous suffit ensuite de créer une contrainte d&rsquo;unicité sur ces deux colonnes :</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">------------------------------- <br />
-- Nicolas SOUQUET - 29/10/2009 <br />
------------------------------- <br />
ALTER TABLE dbo.TbCoordonneeVille <br />
ADD CONSTRAINT UQ_TbCoordonneeVille_latitudeVille_longitudeVille <br />
&nbsp; UNIQUE (latitudeVille, longitudeVille)</div></td></tr></tbody></table></div>
<p>Essayons maintenant d&rsquo;insérer deux villes dont le nom est différent, mais dont les coordonnées sont identiques :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INSERT INTO dbo.TbCoordonneeVille (nomVille, geoPositionVille) <br />
VALUES ('Toulouse', GEOGRAPHY::STPointFromText('POINT(43.604503 1.444026)', 4326)) <br />
GO <br />
&nbsp;<br />
INSERT INTO dbo.TbCoordonneeVille (nomVille, geoPositionVille) <br />
VALUES ('Lyon', GEOGRAPHY::STPointFromText('POINT(43.604503 1.444026)', 4326)) <br />
GO</div></td></tr></tbody></table></div>
<p>La première instruction se passe sans problèmes.<br />
En revanche la seconde échoue, et nous obtenons l&rsquo;erreur suivante :</p>
<blockquote><p>Msg 2627, Niveau 14, État 1, Ligne 1<br />
Violation de la contrainte UNIQUE KEY &lsquo;UQ_TbCoordonneeVille_latitudeVille_longitudeVille&rsquo;. Impossible d&rsquo;insérer une clé en double dans l&rsquo;objet &lsquo;dbo.TbCoordonneeVille&rsquo;.<br />
L&rsquo;instruction a été arrêtée.</p></blockquote>
<p>Vérifions le contenu de la table :</p>
<p><img src="http://blog.developpez.com/media/geographyUnique1.PNG" width="1079" height="363" alt="" /></p>
<p>Une solution alternative est de créer une vue indexée, ce qui présentera un bon avantage si la table est souvent lue.<br />
Supprimons la table puis recréons-la :</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">DROP TABLE dbo.TbCoordonneeVille <br />
GO <br />
&nbsp;<br />
CREATE TABLE dbo.TbCoordonneeVille <br />
( <br />
&nbsp; IDCoordonneeVille INT NOT NULL IDENTITY CONSTRAINT PK_TbCoordonneeVille PRIMARY KEY, <br />
&nbsp; nomVille VARCHAR(45) NOT NULL CONSTRAINT UQ_TbCoordonneeVille_nomVille UNIQUE, <br />
&nbsp; geoPositionVille GEOGRAPHY NOT NULL <br />
)</div></td></tr></tbody></table></div>
<p>Créons ensuite la vue :</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 /></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 - 29/10/2009 <br />
------------------------------- <br />
CREATE VIEW dbo.VwCoordonneeVille <br />
&nbsp; WITH SCHEMABINDING <br />
AS <br />
SELECT nomVille, <br />
&nbsp; &nbsp; geoPositionVille.Lat AS latitudeVille, <br />
&nbsp; &nbsp; geoPositionVille.Long AS longitudeVille <br />
FROM dbo.TbCoordonneeVille</div></td></tr></tbody></table></div>
<p>Puis indexons-la :</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 /></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 - 29/10/2009 <br />
------------------------------- <br />
CREATE UNIQUE CLUSTERED INDEX IXUQC_VwCoordonneeVille_latitudeVille_longitudeVille <br />
ON dbo.VwCoordonneeVille(latitudeVille, longitudeVille)</div></td></tr></tbody></table></div>
<p>Et tentons les mêmes insertions que celles que nous avons faites pour tester la contrainte d&rsquo;unicité sur les colonnes calculées persistantes :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INSERT INTO dbo.TbCoordonneeVille (nomVille, geoPositionVille) <br />
VALUES ('Toulouse', GEOGRAPHY::STPointFromText('POINT(43.604503 1.444026)', 4326)) <br />
GO <br />
&nbsp;<br />
INSERT INTO dbo.TbCoordonneeVille (nomVille, geoPositionVille) <br />
VALUES ('Lyon', GEOGRAPHY::STPointFromText('POINT(43.604503 1.444026)', 4326)) <br />
GO</div></td></tr></tbody></table></div>
<p>Là encore, la première instruction se passe sans problème, mais la seconde échoue, provoquant l&rsquo;erreur suivante :</p>
<blockquote><p>Msg 2601, Niveau 14, État 1, Ligne 1<br />
Impossible d&rsquo;insérer une ligne de clé en double dans l&rsquo;objet &lsquo;dbo.VwCoordonneeVille&rsquo; avec un index unique &lsquo;IXUQC_VwCoordonneeVille_latitudeVille_longitudeVille&rsquo;.<br />
L&rsquo;instruction a été arrêtée.</p></blockquote>
<p>Interrogeons néanmoins la vue :</p>
<p><img src="http://blog.developpez.com/media/geographyUnique2.PNG" width="770" height="348" alt="" /></p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Les jointures triangulaires</title>
		<link>https://blog.developpez.com/elsuket/p6745/moteur-de-base-de-donnees-sql-server/les_jointures_triangulaires</link>
		<comments>https://blog.developpez.com/elsuket/p6745/moteur-de-base-de-donnees-sql-server/les_jointures_triangulaires#comments</comments>
		<pubDate>Sat, 08 Nov 2008 17:32:39 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Nous avons tous entendu qu’écrire du code ensembliste pour gérer des données dans une base de données est la meilleure façon d’obtenir des performances correctes. Il est vrai qu’il est difficile pour un développeur ayant une expérience du développement d’applications, &#8230; <a href="https://blog.developpez.com/elsuket/p6745/moteur-de-base-de-donnees-sql-server/les_jointures_triangulaires">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Nous avons tous entendu qu’écrire du code ensembliste pour gérer des données dans une base de données est la meilleure façon d’obtenir des performances correctes.</p>
<p>Il est vrai qu’il est difficile pour un développeur ayant une expérience du développement d’applications, en quelque langage de programmation que ce soit, de passer du code procédural, qui, en outre, traite des jeux de données extraits de bases de données « ligne par ligne », à un langage conçu pour manipuler des ensembles de données.</p>
<p>Nous n’aborderons pas ici l’utilisation, à proscrire, des curseurs et des boucles utilisant la commande WHILE, mais nous allons voir que, si l’on croit avoir écrit du code ensembliste, il s’agit en fait de code procédural, et qu’il peut s’avérer être contre-performant.<span id="more-68"></span></p>
<pre><strong>	-----------------------------------------</strong></pre>
<pre><strong>	1. Que sont les jointures triangulaires ?</strong></pre>
<pre><strong>	-----------------------------------------</strong></pre>
<p>Vous avez peut-être déjà aperçu du code dont le squelette ressemble à celui-ci :</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 /></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 - 08/11/2008 - <br />
--------------------------------- <br />
SELECT P.IDProduit, <br />
&nbsp; &nbsp; &nbsp; &nbsp; P.Commande, <br />
&nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; SELECT SUM(Q.Commande) <br />
&nbsp; &nbsp; FROM dbo.Produits Q <br />
&nbsp; &nbsp; WHERE Q.IDProduit &lt;= P.IDProduit <br />
&nbsp; &nbsp; ) AS Total, <br />
&nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; SELECT COUNT(Q.Commande) <br />
&nbsp; &nbsp; FROM dbo.Produits Q <br />
&nbsp; &nbsp; WHERE Q.IDProduit &lt;= P.IDProduit <br />
&nbsp; &nbsp; ) AS Nombre <br />
&nbsp;FROM dbo.Produits P</div></td></tr></tbody></table></div>
<p>Cette requête manipule des ensembles tout en effectuant des calculs d’agrégats, quoi de plus anodin pour un traitement en base de données ?</p>
<p>Et pourtant cette requête est peut-être pire en termes de performance qu’un traitement avec un curseur ou avec une boucle utilisant la commande WHILE : elle spécifie ce que l’on appelle une jointure triangulaire, c&rsquo;est-à-dire que les sous-requêtes qui la constituent spécifient des références en dehors d’elles-mêmes : dans l’exemple précédent, les calculs agrégés SUM et COUNT sont effectués sur l’alias Q de la table dbo.Produits, référençant la même table, mais d’alias P, en dehors de ces calculs, par une jointure.<br />
Que se passe-t-il lors de l’exécution ? Les calculs agrégés sont effectués pour chaque ligne de P.<br />
Attention, cette contre-performance ne provient :</p>
<p>&#8211; ni du calcul d’agrégats,<br />
&#8211; ni de l’inégalité spécifiant la jointure,<br />
&#8211; ni de l’auto-jointure.</p>
<p>La requête suivante :</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 /></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 - 08/11/2008 - <br />
--------------------------------- <br />
SELECT A.NomAbonne + ' ' + A.PrenomAbonne, <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT S.NomSport <br />
&nbsp; &nbsp; FROM dbo.TbSport S <br />
&nbsp; &nbsp; WHERE A.IDSport = S.IDSport <br />
&nbsp; ) <br />
FROM dbo.TbAbonne A</div></td></tr></tbody></table></div>
<p>produit tout à fait le même effet : à chaque ligne d’abonné lue, vous allez rechercher tous les sports pratiqués par celui-ci …</p>
<pre><strong>	------------------------------</strong></pre>
<pre><strong>	2. Un œil sur les performances</strong></pre>
<pre><strong>	------------------------------</strong></pre>
<p>Regardons rapidement ce que cela donne avec un jeu de données dont la cardinalité est très petite :</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 /></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 - 08/11/2008 - <br />
--------------------------------- <br />
CREATE TABLE TbSport <br />
( <br />
&nbsp; IDSport INT IDENTITY CONSTRAINT PK_TbSport PRIMARY KEY, <br />
&nbsp; NomSport VARCHAR(16) NOT NULL CONSTRAINT UQ_TbSport_NomSport UNIQUE <br />
) <br />
GO <br />
&nbsp;<br />
CREATE TABLE TbAbonne <br />
( <br />
&nbsp; IDAbonne INT IDENTITY CONSTRAINT PK_TbAbonne PRIMARY KEY, <br />
&nbsp; NomAbonne VARCHAR(32) NOT NULL, <br />
&nbsp; PrenomAbonne VARCHAR(32) NOT NULL, <br />
&nbsp; IDSport INT NOT NULL CONSTRAINT FK_TbAbonne_IDSport FOREIGN KEY (IDSport) REFERENCES dbo.TbSport <br />
) <br />
GO <br />
&nbsp;<br />
INSERT INTO dbo.TbSport VALUES ('Tennis') <br />
INSERT INTO dbo.TbSport VALUES ('Squash') <br />
INSERT INTO dbo.TbSport VALUES ('Tennis de table') <br />
INSERT INTO dbo.TbSport VALUES ('Paddle') <br />
INSERT INTO dbo.TbSport VALUES ('Pelote basque') <br />
GO <br />
&nbsp;<br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne1', 'PrenomAbonne1', 1) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne2', 'PrenomAbonne2', 1) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne3', 'PrenomAbonne3', 1) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne4', 'PrenomAbonne4', 2) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne5', 'PrenomAbonne5', 2) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne6', 'PrenomAbonne6', 2) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne7', 'PrenomAbonne7', 2) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne8', 'PrenomAbonne8', 2) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne9', 'PrenomAbonne9', 2) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne10', 'PrenomAbonne10', 3) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne11', 'PrenomAbonne11', 3) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne12', 'PrenomAbonne12', 3) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne13', 'PrenomAbonne13', 3) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne14', 'PrenomAbonne14', 3) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne15', 'PrenomAbonne15', 4) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne16', 'PrenomAbonne16', 4) <br />
INSERT INTO dbo.TbAbonne VALUES ('NomAbonne17', 'PrenomAbonne17', 5) <br />
GO <br />
&nbsp;<br />
-- Affiche le nombre de millisecondes requises pour analyser, compiler et exécuter chaque <br />
-- instruction du lot <br />
SET STATISTICS TIME ON <br />
GO <br />
&nbsp;<br />
PRINT '========&gt; Jointure triangulaire' <br />
SELECT A.NomAbonne + ' ' + A.PrenomAbonne, <br />
&nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; SELECT S.NomSport <br />
&nbsp; &nbsp; &nbsp; FROM dbo.TbSport S <br />
&nbsp; &nbsp; &nbsp; WHERE A.IDSport = S.IDSport <br />
&nbsp; &nbsp; ) <br />
FROM dbo.TbAbonne A <br />
GO <br />
&nbsp;<br />
PRINT '========&gt; Equi-jointure' <br />
SELECT A.NomAbonne + ' ' + A.PrenomAbonne, <br />
&nbsp; &nbsp; S.NomSport <br />
FROM dbo.TbAbonne A</div></td></tr></tbody></table></div>
<p>JOIN dbo.TbSport S ON A.IDSport = S.IDSport</p>
<p>Sur un Pentium Dual Core à 2,13 GHz avec 2Go de RAM, cela donne 16ms de temps total écoulé pour la 1e requête, contre 2ms pour la seconde, avec seulement 17 lignes affectées !</p>
<pre><strong>	------------------------------</strong></pre>
<pre><strong>	3. Pourquoi est-ce plus lent ?</strong></pre>
<pre><strong>	------------------------------</strong></pre>
<p>Pour rechercher le nombre de lignes lues par ce type de requête, soient la table et la requête suivantes :</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 - 08/11/2008 - <br />
--------------------------------- <br />
SELECT 1 Nombre <br />
INTO NombresDeUnACinq <br />
UNION SELECT 2 <br />
UNION SELECT 3 <br />
UNION SELECT 4 <br />
UNION SELECT 5 <br />
GO <br />
&nbsp;<br />
SELECT A.Nombre, <br />
&nbsp; ( <br />
&nbsp; &nbsp; SELECT COUNT(*) &nbsp;<br />
&nbsp; &nbsp; FROM NombresDeUnACinq ASUB &nbsp;<br />
&nbsp; &nbsp; WHERE ASUB.Nombre [TypeDeDemiJointure] A.Nombre <br />
&nbsp; ) Occurences <br />
FROM dbo.NombresDeUnACinq A <br />
ORDER BY Occurrences <br />
GO</div></td></tr></tbody></table></div>
<p>Si [TypeDeDemiJointure] est :</p>
<p>&#8211; une équi-jointure, alors nous avons lu 5 x 5 = 25 lignes.<br />
&#8211; une inégalité stricte , alors nous avons lu 5(4 + 3 + 2 + 1) = 50 lignes.<br />
&#8211; une inégalité, alors nous avons lu 5(5 + 4 + 3 + 2 + 1) = 75 lignes.<br />
&#8211; une différence, alors nous avons lu 5(2(4 + 3 + 2 + 1)) = 100 lignes.</p>
<p>On peut donc lire entre 5 et 20 fois plus de lignes qu’il n’en faut. Imaginez ce que cela donne avec un jeu de données dont la cardinalité est bien plus importante …</p>
<p>Voici donc l’origine de la dénomination de ce type de jointures : (les carrés noirs vérifient la clause)</p>
<p><img src="http://blog.developpez.com/media/jointuresTriangulaires.PNG" width="1210" height="362" alt="" /></p>
<pre><strong>	-------------</strong></pre>
<pre><strong>	4. Conclusion</strong></pre>
<pre><strong>	-------------</strong></pre>
<p>Comme nous l’avons vu, les jointures triangulaires s’avèrent être très mauvaises en termes de performances. Pour écrire du code ensembliste, il ne suffit donc pas de ne pas spécifier de curseur ou une boucle WHILE pour ne pas exécuter une requête sur le mode procédural : en effet cela revient au même que d’appeler une fonction SQL et de lui passer le paramètre servant de critère de recherche pour lui déléguer un traitement …</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Voir les statistiques du client avec SQL Server Management Studio</title>
		<link>https://blog.developpez.com/elsuket/p8315/moteur-de-base-de-donnees-sql-server/voir_les_statistiques_du_client_avec_sql</link>
		<comments>https://blog.developpez.com/elsuket/p8315/moteur-de-base-de-donnees-sql-server/voir_les_statistiques_du_client_avec_sql#comments</comments>
		<pubDate>Thu, 12 Nov 2009 23:14:00 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[SQL Server Management Studio]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Nombreux sont les boutons dans la barre d&#8217;outils de l&#8217;éditeur SQL proposé par SQL Server Management Studio (SSMS). L&#8217;un d&#8217;entre eux permet d&#8217;obtenir des statistiques sur l&#8217;exécution de requêtes, sur les échanges réseau entre SSMS et le moteur de base &#8230; <a href="https://blog.developpez.com/elsuket/p8315/moteur-de-base-de-donnees-sql-server/voir_les_statistiques_du_client_avec_sql">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Nombreux sont les boutons dans la barre d&rsquo;outils de l&rsquo;éditeur SQL proposé par <em>SQL Server Management Studio</em> (SSMS).</p>
<p>L&rsquo;un d&rsquo;entre eux permet d&rsquo;obtenir des statistiques sur l&rsquo;exécution de requêtes, sur les échanges réseau entre SSMS et le moteur de base de données, et sur le temps d&rsquo;exécution de la requête, comme par exemple le délai d&rsquo;attente de réponse du serveur.</p>
<p>Voyons comment les obtenir &#8230;<br />
<span id="more-144"></span><br />
Il suffit pour cela d&rsquo;activer le bouton &laquo;&nbsp;<em>Inclure les statistiques du client</em>&laquo;&nbsp;, pour voir celles-ci apparaître dans un nouvel onglet de la zone de résultat dès la première exécution d&rsquo;une requête :</p>
<p><img src="http://blog.developpez.com/media/statsclient1.png" width="832" height="667" alt="" /></p>
<p>La date et l&rsquo;heure de chaque exécution de la requête sont fournies, et les statistiques sont mises à jour d&rsquo;une exécution de requête à l&rsquo;autre, quelle que soit la requête que vous exécutez : les statistiques sont collectées pour une session, c&rsquo;est-à-dire une fenêtre de requête.</p>
<p>Les évolutions des valeurs de chaque colonnes sont symbolisées par des flèches qui indiquent le sens de l&rsquo;évolution des statistiques :</p>
<p><img src="http://blog.developpez.com/media/statsclient2.png" width="778" height="629" alt="" /></p>
<p>Le code de la procédure stockée étant très simple, les statistiques de profil de requête et de réseau n&rsquo;évoluent pas, mais les statistiques de temps ont varié au cours des 4 exécutions.</p>
<p>Cela nous permettra donc de mesurer avec facilité la façon dont sont échangées les données entre les applications et le serveur de base de données pour une requête donnée :</p>
<p>&#8211; temps réel d&rsquo;exécution pour le comparer au temps consacré à l&rsquo;échange de données,<br />
&#8211; quantité de données qui transite sur le réseau,<br />
&#8211; nombre de lignes moyen affecté par la requête, si l&rsquo;on fait varier d&rsquo;une exécution à l&rsquo;autre la valeur de paramètres, &#8230;</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quoi de neuf dans SQL Server 2008 ?</title>
		<link>https://blog.developpez.com/elsuket/p8313/moteur-de-base-de-donnees-sql-server/quoi_de_neuf_dans_sql_server_2008</link>
		<comments>https://blog.developpez.com/elsuket/p8313/moteur-de-base-de-donnees-sql-server/quoi_de_neuf_dans_sql_server_2008#comments</comments>
		<pubDate>Sun, 12 Jul 2009 17:48:07 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici la liste des nouvelles fonctionnalités de SQL Server 2008 ElSuket]]></description>
				<content:encoded><![CDATA[<p>Voici la <a href="http://www.microsoft.com/sqlserver/2008/en/us/whats-new.aspx">liste des nouvelles fonctionnalités</a> de SQL Server 2008</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Supprimer toutes les captures instantanées de base de données d&#8217;un coup</title>
		<link>https://blog.developpez.com/elsuket/p8302/snippets/supprimer_toutes_les_captures_instantane</link>
		<comments>https://blog.developpez.com/elsuket/p8302/snippets/supprimer_toutes_les_captures_instantane#comments</comments>
		<pubDate>Mon, 09 Nov 2009 21:42:31 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[Snippets]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Il est parfois nécessaire de supprimer toute les captures instantanées d&#8217;une base de données : par exemple pour la restaurer ou pour la supprimer. Voici donc un bout de code pour les supprimer toutes, d&#8217;un seul coup &#8230; 123456789101112------------------------------- -- &#8230; <a href="https://blog.developpez.com/elsuket/p8302/snippets/supprimer_toutes_les_captures_instantane">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Il est parfois nécessaire de supprimer toute les <a href="http://blog.developpez.com/elsuket/p7454/moteur-de-base-de-donnees-sql-server/creer-des-captures-instantanees-de-bases/">captures instantanées</a> d&rsquo;une base de données : par exemple pour la restaurer ou pour la supprimer.<br />
Voici donc un bout de code pour les supprimer toutes, d&rsquo;un seul coup &#8230;<br />
<span id="more-63"></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 /></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/11/2009 <br />
------------------------------- <br />
DECLARE @sql VARCHAR(MAX) = '' <br />
SELECT @sql = @sql + 'DROP DATABASE ' + name + ';' <br />
FROM sys.databases <br />
WHERE source_database_id IS NOT NULL <br />
AND name = 'maBaseDeDonneess' <br />
&nbsp;<br />
PRINT @sql <br />
&nbsp;<br />
--EXEC (@sql)</div></td></tr></tbody></table></div>
<p>Il suffit de décommenter EXEC (@sql) pour exécuter la suppression des captures instantanées, qui entraîne la suppression des fichiers de chacune d&rsquo;entre-elles.</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vérifier l&#8217;unicité de tuples NULLables avec les index filtrés sous SQL Server 2008</title>
		<link>https://blog.developpez.com/elsuket/p8256/moteur-de-base-de-donnees-sql-server/indexation/verifier_l_unicite_de_tuples_avec_les_in_2008</link>
		<comments>https://blog.developpez.com/elsuket/p8256/moteur-de-base-de-donnees-sql-server/indexation/verifier_l_unicite_de_tuples_avec_les_in_2008#comments</comments>
		<pubDate>Thu, 29 Oct 2009 21:40:56 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Indexation]]></category>
		<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Toute contrainte d&#8217;unicité entraîne la création implicite d&#8217;une index unique sur la table, dont la clé est constituée des colonnes spécifiées dans la contrainte d&#8217;unicité. Or, lors de l&#8217;insertion d&#8217;une nouvelle ligne ou de la modification d&#8217;une des colonnes constituant &#8230; <a href="https://blog.developpez.com/elsuket/p8256/moteur-de-base-de-donnees-sql-server/indexation/verifier_l_unicite_de_tuples_avec_les_in_2008">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Toute contrainte d&rsquo;unicité entraîne la création implicite d&rsquo;une index unique sur la table, dont la clé est constituée des colonnes spécifiées dans la contrainte d&rsquo;unicité.</p>
<p>Or, lors de l&rsquo;insertion d&rsquo;une nouvelle ligne ou de la modification d&rsquo;une des colonnes constituant la clé unique, SQL Server considère NULL comme une valeur.<br />
Cela est faux puisque NULL n&rsquo;est pas une valeur : c&rsquo;est l&rsquo;absence de valeur.</p>
<p>Avec SQL Server 2008 ont été introduits les index filtrés, qui permettent de spécifier les lignes candidates à l&rsquo;indexation, par l&rsquo;ajout d&rsquo;une simple clause WHERE.<br />
Dès lors, il est possible de contourner le problème posé par les contraintes d&rsquo;unicité en se servant de ce type d&rsquo;index &#8230;</p>
<p><span id="more-91"></span></p>
<p>Supposons que nous avons plusieurs applications qui doivent se connecter à notre base de données, et que l&rsquo;authentification des utilisateurs est gérée dans cette base de données à l&rsquo;aide de la table suivante :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE TABLE dbo.TbUtilisateur <br />
( <br />
&nbsp; IDUtilisateur INT NOT NULL IDENTITY CONSTRAINT PK_TbUtilisateur PRIMARY KEY, <br />
&nbsp; nomUtilisateur VARCHAR(30) NOT NULL, <br />
&nbsp; prenomUtilisateur VARCHAR(30) NOT NULL, <br />
&nbsp; identifiantUtilisateur VARCHAR(10) CONSTRAINT UQ_TbUtilisateur_identifiantUtilisateur UNIQUE, <br />
&nbsp; motDePasseUtilisateur VARCHAR(10) <br />
) <br />
&nbsp;<br />
ALTER TABLE dbo.TbUtilisateur <br />
ADD CONSTRAINT CHK_TbUtilisateur_identifiantUtilisateur_motDePasseUtilisateur <br />
&nbsp; CHECK ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; identifiantUtilisateur IS NULL <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND motDePasseUtilisateur IS NULL <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OR <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; identifiantUtilisateur IS NOT NULL <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND motDePasseUtilisateur IS NOT NULL <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) <br />
&nbsp; &nbsp; &nbsp; )</div></td></tr></tbody></table></div>
<p>Il est nécessaire que l&rsquo;identifiant qui permet à nos utilisateurs de se connecter soit unique.<br />
Notre application donne le droit aux administrateurs d&rsquo;enregistrer les nouveaux salariés.<br />
Lors de la première connexion de ceux-ci, il doivent spécifier un identifiant et un mot de passe que les administrateurs ne peuvent pas choisir à leur place, et il a été décidé que ces deux valeurs seront laissées à NULL jusqu&rsquo;à la première connexion de l&rsquo;utilisateur.</p>
<p>Le contenu de la table pourrait dont être le suivant :</p>
<p><img src="http://blog.developpez.com/media/filteredIndexUnique1.PNG" width="522" height="57" alt="" /></p>
<p>Essayons maintenant d&rsquo;enregistrer un nouvel utilisateur :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INSERT INTO dbo.TbUtilisateur <br />
( <br />
&nbsp; nomUtilisateur, <br />
&nbsp; prenomUtilisateur, <br />
&nbsp; identifiantUtilisateur, <br />
&nbsp; motDePasseUtilisateur <br />
) <br />
VALUES <br />
( <br />
&nbsp; 'DELANEY', <br />
&nbsp; 'Kalen', <br />
&nbsp; NULL, <br />
&nbsp; NULL <br />
)</div></td></tr></tbody></table></div>
<p>Cela provoque l&rsquo;erreur suivante :</p>
<blockquote><p>Msg 2627, Niveau 14, État 1, Ligne 1<br />
Violation de la contrainte UNIQUE KEY &lsquo;UQ_TbUtilisateur_identifiantUtilisateur&rsquo;. Impossible d&rsquo;insérer une clé en double dans l&rsquo;objet &lsquo;dbo.TbUtilisateur&rsquo;.<br />
L&rsquo;instruction a été arrêtée.</p></blockquote>
<p>Remplaçons donc la contrainte d&rsquo;unicité par un index filtré :</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 /></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 - 29/10/2009 <br />
------------------------------- <br />
ALTER TABLE dbo.TbUtilisateur <br />
DROP CONSTRAINT UQ_TbUtilisateur_identifiantUtilisateur <br />
GO <br />
&nbsp;<br />
CREATE UNIQUE NONCLUSTERED INDEX IUXQ_TbUtilisateur_F_identifiantUtilisateur <br />
ON dbo.TbUtilisateur(identifiantUtilisateur) <br />
WHERE identifiantUtilisateur IS NOT NULL</div></td></tr></tbody></table></div>
<p>Tentons de nouveau l&rsquo;insertion de ce nouvel utilisateur :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INSERT INTO dbo.TbUtilisateur <br />
( <br />
&nbsp; nomUtilisateur, <br />
&nbsp; prenomUtilisateur, <br />
&nbsp; identifiantUtilisateur, <br />
&nbsp; motDePasseUtilisateur <br />
) <br />
VALUES <br />
( <br />
&nbsp; 'DELANEY', <br />
&nbsp; 'Kalen', <br />
&nbsp; NULL, <br />
&nbsp; NULL <br />
)</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/filteredIndexUnique2.PNG" width="523" height="78" alt="" /></p>
<p>Pour vérifier, tentons d&rsquo;insérer un nouvel utilisateur avec le même identifiant de connexion que M. Brouard :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INSERT INTO dbo.TbUtilisateur <br />
( <br />
&nbsp; nomUtilisateur, <br />
&nbsp; prenomUtilisateur, <br />
&nbsp; identifiantUtilisateur, <br />
&nbsp; motDePasseUtilisateur <br />
) <br />
VALUES <br />
( <br />
&nbsp; 'RANDAL', <br />
&nbsp; 'Paul', <br />
&nbsp; 'FB', <br />
&nbsp; '***' <br />
)</div></td></tr></tbody></table></div>
<p>Cela provoque l&rsquo;erreur suivante :</p>
<blockquote><p>Msg 2601, Niveau 14, État 1, Ligne 1<br />
Impossible d&rsquo;insérer une ligne de clé en double dans l&rsquo;objet &lsquo;dbo.TbUtilisateur&rsquo; avec un index unique &lsquo;IUXQ_TbUtilisateur_F_identifiantUtilisateur&rsquo;.<br />
L&rsquo;instruction a été arrêtée.</p></blockquote>
<p>L&rsquo;unicité des identifiants de connexion est donc bien vérifiée, et laisse la place aux nouveaux entrants <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Du choix des types de données</title>
		<link>https://blog.developpez.com/elsuket/p8233/moteur-de-base-de-donnees-sql-server/du_choix_des_types_de_donnees</link>
		<comments>https://blog.developpez.com/elsuket/p8233/moteur-de-base-de-donnees-sql-server/du_choix_des_types_de_donnees#comments</comments>
		<pubDate>Sat, 24 Oct 2009 18:59:01 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[SQL général]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Lors de mes participations au forum SQL Server de ce site, je vois souvent des membres qui manipulent des données qui ne sont pas de type chaîne de caractère dans une colonne de ce type. Cela peut revenir à calculer &#8230; <a href="https://blog.developpez.com/elsuket/p8233/moteur-de-base-de-donnees-sql-server/du_choix_des_types_de_donnees">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Lors de mes participations au forum SQL Server de ce site, je vois souvent des membres qui manipulent des données qui ne sont pas de type chaîne de caractère dans une colonne de ce type.<br />
Cela peut revenir à calculer la racine carrée de carottes, et constitue donc un non-sens.<br />
Voici donc un inventaire de ce que j&rsquo;ai pu rencontrer jusqu&rsquo;ici, et qu&rsquo;il ne faut surtout pas faire pour transformer une base de données en dépotoir de données !</p>
<p><span id="more-154"></span><br />
=> <strong>Utiliser plusieurs colonnes de type BIT pour représenter un état</strong></p>
<p>Certes cela consomme moins d&rsquo;espace, mais l&rsquo;atomicité du sens de la valeur est alors perdue &#8230;<br />
Il sera donc avantageux d&rsquo;utiliser une colonne de type TINYINT qui consomme seulement un octet, en laissant la porte ouverte à de nouveaux états &#8230;</p>
<p>=> <strong>Utiliser le type TIME pour stocker une durée</strong></p>
<p>SQL Server 2008 a introduit plusieurs nouveaux types de données permettant de stocker des valeurs temporelles, notamment le type TIME, qui comme son nom l&rsquo;indique, permet de stocker un horaire, et non pas une durée.<br />
Si d&rsquo;aventure nous devons stocker une durée supérieure à 24h, comment allons-nous alors procéder ? Ce choix reste acceptable si l&rsquo;on est absolument certain que la durée ne dépassera jamais 24h, mais il est plus simple de stocker une durée comme un entier, ce qui permet d&rsquo;utiliser très simplement la fonction DATEADD().<br />
Une autre solution est de stocker la date de début et la date de fin de l&rsquo;opération, et d&rsquo;ajouter une colonne calculée qui spécifie la fonction DATEDIFF().</p>
<p>=> <strong>Utiliser le type DATETIME au lieu du type SMALLDATETIME</strong></p>
<p>Tout aussi regrettable, la confusion entre ces deux types de données :</p>
<p>&#8211; DATETIME nécessite 8 octets, et permet de stocker des dates avec une précision à 3ms,<br />
&#8211; SMALLDATETIME nécessite 4 octets, et permet de stocker des dates avec un précision à la minute.</p>
<p>Il est donc absurde de stocker des dates au type DATETIME pour une application qui n&rsquo;en a pas besoin, comme par exemple un centre de documentation qui propose l&rsquo;emprunt de livres &#8230;</p>
<p>Encore une fois cela a un impact important sur l&rsquo;indexation, puisqu&rsquo;il faudra plus de pages pour stocker la même donnée, et traverser plus de niveaux intermédiaires &#8230; il en résultera donc des lectures de pages supplémentaires et inutiles, pourrissant le cache de données, et ralentissant l&rsquo;exécution des requêtes &#8230;</p>
<p>=> <strong>Stocker des chaînes de caractères numériques ou forcément latins dans une colonne de type Unicode (NCHAR, NVARCHAR)</strong></p>
<p>Pourquoi stocker une référence, une adresse mail, un numéro de téléphone, ou un code postal en Unicode ?<br />
Tout simplement pour consommer deux fois plus d&rsquo;espace !<br />
En effet tout caractère stocké au type de données Unicode occupe 2 octets, contre seulement 1 en CHAR ou VARCHAR.</p>
<p>=> <strong>Utiliser le type VARCHAR au lieu de CHAR</strong></p>
<p>Si par exemple nous avons des codes qui contiennent des lettres, mais dont est certain qu&rsquo;ils seront toujours représentés sur 6 caractères, alors pourquoi stocker ceux-ci dans une colonne de type VARCHAR ?<br />
En effet le type VARCHAR fait consommer 2 octets en sus de tous les caractères de la chaîne, qui permettent de stocker l&rsquo;offset de fin de cette chaîne.<br />
Ce n&rsquo;est pas le cas lorsqu&rsquo;on stocke ce genre de données au type CHAR.</p>
<p>=> <strong>Stocker des dates dans une colonne de type CHAR | NCHAR | VARCHAR | NVARCHAR</strong></p>
<p>On se sert d&rsquo;une colonne de type chaîne pour stocker une date au format désiré, par exemple DDMMYYYY HH:mm:ss &#8230;<br />
Mais il y a pire encore : stocker ces dates au format Unicode (NCHAR, NVARCHAR) surtout quand on sait que les dates ne comprennent jamais de caractères Unicode.<br />
Rappelons donc que ces 4 types de données ne doivent servir exclusivement qu&rsquo;au stockage de chaînes de caractère, et que les types Unicode permettent de stocker des caractères non latins, comme ceux des langues arabes et asiatiques.</p>
<p>Conséquence directe de ce choix : la perte d&rsquo;intégrité des données, puisque dans une colonne de type chaîne de caractère, on peut stocker une représentation d&rsquo;une date, mais aussi n&rsquo;importe quelle autre chaîne de caractères.<br />
Bien sûr, certains me répondront que l&rsquo;on peut mettre une contrainte de domaine (CHECK) sur la colonne &#8230; outre le fait que la comparaison de chaînes est coûteux en ressources système, que ferez-vous en cas d&rsquo;erreur ?</p>
<p>Autre conséquence : comment interroger la table pour retourner les données qui ont été stockées entre deux dates ? Comment utiliser les fonctions consacrées aux dates comme DATEADD(), DATEDIFF(), &#8230; ?</p>
<p>Enfin l&rsquo;efficacité d&rsquo;un index sur une colonne de type chaîne de caractère est plus connue pour être faible.</p>
<p>Tout cela pour ne pas avoir utilisé le type DATETIME ou SMALLDATETIME &#8230; Il faut avouer que c&rsquo;est de l&rsquo;auto-flagellation !</p>
<p>=> <strong>Utiliser le type INT au lieu de SMALLINT, TINYINT ou BIT</strong></p>
<p>Voilà un précepte que l&rsquo;on rencontre aussi souvent qu&rsquo;il est incohérent.</p>
<p>Au nom de la simplicité (mais laquelle ?), nombreux sont ceux qui souhaitent stocker la valeur de clé primaire de tables de référence (jours de la semaine, quelques états possibles d&rsquo;une entité (en veille, en chargement, allumé, en cours d&rsquo;extinction), et j&rsquo;en passe &#8230;) dans une colonne de type INT.</p>
<p>Alors qu&rsquo;à l&rsquo;évidence, il n&rsquo;y aura jamais plus de 256 jours dans une semaine, stockons donc tout cela sur les 4 octets d&rsquo;une colonne de type INT, au lieu de stocker la même information dans une colonne de type TINYINT, pour seulement 1 octet.<br />
De cette façon on pourra avoir des indexes plus volumineux et moins efficaces lors des jointures, tout en pourrissant le cache de données !</p>
<p>=> <strong>Utiliser les types FLOAT ou REAL au lieu de NUMERIC ou DECIMAL</strong></p>
<p>Les types FLOAT et REAL, réservés aux valeurs numériques imprécises, sont appropriés dans le cas où l&rsquo;on a affaire à une application scientifique qui effectue des calculs en virgule flottante.</p>
<p>=> <strong>Utiliser les types MONEY ou SMALLMONEY au lieu de NUMERIC ou DECIMAL</strong></p>
<p>Il s&rsquo;agit ici plus d&rsquo;une anomalie que d&rsquo;autre chose, et je ne m&rsquo;explique toujours pas la présence des types de données MONEY et SMALLMONEY, alors que NUMERIC et DECIMAL conviennent tout à fait au même usage.<br />
Le pire, c&rsquo;est que les premiers fonctionnent très bien pour toute opération arithmétique de base, mais entraînent des imprécisions puisqu&rsquo;ils sont stockés comme des nombres à virgule flottante.<br />
Si on doit donc utiliser des pourcentages sur des valeurs monétaires, ou utiliser des taux de change, on préfèrera les types NUMERIC ou DECIMAL, qui sont précis.</p>
<p>=> <strong>Le comble de la médiocrité : le &laquo;&nbsp;type&nbsp;&raquo; sql_variant</strong></p>
<p>Ce pseudo-type de données est le pire qui ait été inventé : on peut tout y stocker, des chaînes de caractère, des entiers, des décimaux, un document XML, &#8230;</p>
<p>Voyons tous les inconvénients de ce &laquo;&nbsp;type&nbsp;&raquo; :<br />
&#8211; Il n&rsquo;est pas entièrement supporté par ODBC, qui convertit de plus toute valeur automatiquement en NVARCHAR(4000)<br />
&#8211; On ne peut bien évidemment pas l&rsquo;utiliser pour la définition d&rsquo;une colonne calculée,<br />
&#8211; On ne peut pas utiliser l&rsquo;opérateur LIKE sur une colonne de ce &laquo;&nbsp;type&nbsp;&raquo;,<br />
&#8211; Il ne peut pas être utilisé pour définir une clé primaire ou étrangère<br />
&#8211; On ne peut pas utiliser de fonction d&rsquo;aggrégation<br />
&#8211; On ne peut pas effectuer d&rsquo;opération arithmétique</p>
<p>Finalement tout doit être fait à l&rsquo;aide des fonctions CAST() ou CONVERT(), ce qui rend bien sûr un prédicat de filtre non <a href="http://blog.developpez.com/elsuket/p6886/moteur-de-base-de-donnees-sql-server/sql-searchable-arguments-ou-s-args/">SARG-able</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Créer des captures instantanées de bases de données</title>
		<link>https://blog.developpez.com/elsuket/p7454/moteur-de-base-de-donnees-sql-server/creer_des_captures_instantanees_de_bases</link>
		<comments>https://blog.developpez.com/elsuket/p7454/moteur-de-base-de-donnees-sql-server/creer_des_captures_instantanees_de_bases#comments</comments>
		<pubDate>Mon, 06 Apr 2009 22:06:03 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Même en phase de développement, il est important de sauvegarder une base de données. On peut estimer qu&#8217;il n&#8217;est pas nécessaire de mettre en place une stratégie de sauvegarde, et, comme une erreur arrive vite lors des tests unitaires, il &#8230; <a href="https://blog.developpez.com/elsuket/p7454/moteur-de-base-de-donnees-sql-server/creer_des_captures_instantanees_de_bases">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Même en phase de développement, il est important de sauvegarder une base de données.<br />
On peut estimer qu&rsquo;il n&rsquo;est pas nécessaire de mettre en place une stratégie de sauvegarde, et, comme une erreur arrive vite lors des tests unitaires, il faut que l&rsquo;on puisse replacer la base de données avec le jeu de données qui a été altéré par un test, sans perdre le travail de plusieurs développeurs.<br />
Si les captures instantanées de bases de données ne permettent pas de protéger complètement l&rsquo;intégrité d&rsquo;une base de données, elles sont très utiles si l&rsquo;on veut se prémunir des erreurs de l&rsquo;utilisateur pour &laquo;&nbsp;restaurer&nbsp;&raquo; les valeurs d&rsquo;une table ou récupérer une procédure stockée &#8230;<br />
<span id="more-75"></span><br />
Tout d&rsquo;abord, qu&rsquo;est-ce qu&rsquo;une capture instantanée de base de données ?<br />
C&rsquo;est une vue statique, en lecture seule, d&rsquo;une base de données source.<br />
Dès lors les possibilités offertes par cette fonctionnalité dépassent ce qui est décrit en introduction, et on peut tout à fait s&rsquo;en servir pour des statistiques, d&rsquo;autant que tout comme une base de données en ligne, on peut en supprimer les objets.</p>
<p>La commande T-SQL qui permet de créer une capture instantanée de base de données est simple :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE DATABASE maBD_Snapshot <br />
ON (NAME = nomDesFichiersLogiquesDeDonnees, FILENAME = 'C:\maBD_Snapshot.ext' <br />
AS SNAPSHOT OF maBD</div></td></tr></tbody></table></div>
<p>Après la création d&rsquo;une capture instantanée de base de données, vous noterez en lisant de contenu de la table système sys.databases que la colonne source_database_id est valuée seulement pour celle-ci.<br />
Vous verrez également sous Management Studio apparaître la node &laquo;&nbsp;Captures instantanées de base de données&nbsp;&raquo; sous la node &laquo;&nbsp;Bases de données&nbsp;&raquo;. En la déployant, vous trouverez la capture que vous venez de réaliser.</p>
<p>Ainsi, pour restaurer les valeurs d&rsquo;une table de la base de données en ligne avec les valeurs contenues avant une erreur, il suffit d&rsquo;écrire :</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 /></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/04/2009 - <br />
--------------------------------- <br />
UPDATE maBD.monSchema.maTable <br />
SET mesColonnes = SNAP.mesColonnes <br />
FROM maBD.monSchema.maTable AS CIBLE <br />
JOIN maBDSnapshot.monSchema.maTable AS SNAP ON CIBLE.PK_ID = SNAP ON.PK_ID</div></td></tr></tbody></table></div>
<p>Et pour restaurer la base de données à partir d&rsquo;une de ses captures instantanées :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">USE master &nbsp; <br />
RESTORE DATABASE maBD <br />
FROM DATABASE_SNAPSHOT = 'maBDSnaphot'</div></td></tr></tbody></table></div>
<p><strong>Attention :</strong> il est nécessaire que la capture instantanée de données que l&rsquo;on souhaite restaurer soit la <strong>seule</strong> capture instantanée de la base de données à restaurer. Dans le cas contraire, on obtiendra l&rsquo;erreur suivante, qui n&rsquo;en laisse rien voir :</p>
<blockquote><p>Msg 3137, Level 16, State 4, Line 1<br />
Impossible de restaurer la base de données. Le nom primaire ou le nom de la capture instantanée a été spécifié de façon incorrecte, toutes les autres captures instantanées ont été supprimées, ou il manque des fichiers.<br />
Msg 3013, Level 16, State 1, Line 1<br />
RESTORE DATABASE s&rsquo;est terminé anormalement.</p></blockquote>
<p>Il devient ensuite simple de créer un job qui se chargera de créer régulièrement une capture instantanée de votre base de données. La commande T-SQL de ce job pourrait être :</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 /></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/04/2009 - <br />
--------------------------------- <br />
-- Création d'une nouvelle capture instantanée de base de données <br />
DECLARE @nomSnapshot SYSNAME <br />
SELECT @nomSnapshot = 'maBD_' + REPLACE(REPLACE(CONVERT(CHAR(10), GETDATE(), 103) + '_' + CONVERT(CHAR(8), GETDATE(), 108), '/', '_'), ':', '_') <br />
&nbsp;<br />
DECLARE @SQL VARCHAR(256) <br />
SET @SQL = 'CREATE DATABASE ' + @nomSnapshot <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + ' ON (NAME = nomDesFichiersLogiquesDeDonneesDeMaBD, FILENAME = ''C:\' + @nomSnapshot + '.snap'')' <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + ' AS SNAPSHOT OF maBD' <br />
&nbsp;<br />
EXEC (@SQL) <br />
&nbsp;<br />
-- Suppression des anciennes captures instantanées de base de données <br />
DECLARE curSnapshots CURSOR FOR <br />
&nbsp; &nbsp; SELECT name <br />
&nbsp; &nbsp; FROM sys.databases <br />
&nbsp; &nbsp; WHERE source_database_id IS NOT NULL <br />
&nbsp; &nbsp; AND name &lt;&gt; @nomSnapshot <br />
FOR READ ONLY <br />
&nbsp;<br />
OPEN curSnapshots <br />
FETCH NEXT FROM curSnapshots INTO @nomSnapshot <br />
WHILE @@FETCH_STATUS = 0 <br />
BEGIN <br />
&nbsp; &nbsp; SET @SQL = 'DROP DATABASE ' + @nomSnapshot <br />
&nbsp; &nbsp; EXEC (@SQL) <br />
&nbsp; &nbsp; FETCH NEXT FROM curSnapshots INTO @nomSnapshot <br />
END <br />
&nbsp;<br />
DEALLOCATE curSnapshots</div></td></tr></tbody></table></div>
<p>Il vous suffit ensuite de planifier le job pour voir celui-ci s&rsquo;exécuter à une fréquence qui vous garantisse un minimum de perte de données.</p>
<p>Enfin, s&rsquo;il est clair qu&rsquo;une capture de base de données ne vaut pas une bonne stratégie de sauvegarde de base de données, on peut restaurer une base de données à partir d&rsquo;une capture de celle-ci :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">RESTORE DATABASE maBD <br />
FROM DATABASE_SNAPSHOT = maBD_Snapshot</div></td></tr></tbody></table></div>
<p>Voici un bout de code à placer dans un job pour créer des captures instantanées de toutes les bases de données sauf les bases de données système :</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 /></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/04/2009 - <br />
--------------------------------- <br />
DECLARE @SQL VARCHAR(256) <br />
&nbsp;<br />
--------------------------------------------------------------------- <br />
-- Suppression des anciennes captures instantanées de base de données &nbsp;<br />
--------------------------------------------------------------------- <br />
DECLARE curSnapshots CURSOR FOR &nbsp;<br />
&nbsp; SELECT name <br />
&nbsp; FROM sys.databases &nbsp;<br />
&nbsp; WHERE source_database_id IS NOT NULL <br />
&nbsp; AND create_date &lt; CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME) <br />
FOR READ ONLY &nbsp;<br />
&nbsp;<br />
DECLARE @nomSnapshot SYSNAME <br />
&nbsp;<br />
OPEN curSnapshots &nbsp;<br />
FETCH NEXT FROM curSnapshots INTO @nomSnapshot &nbsp;<br />
WHILE @@FETCH_STATUS = 0 &nbsp;<br />
BEGIN &nbsp;<br />
&nbsp; SET @SQL = 'DROP DATABASE ' + @nomSnapshot &nbsp;<br />
&nbsp; EXEC (@SQL) <br />
&nbsp; FETCH NEXT FROM curSnapshots INTO @nomSnapshot &nbsp;<br />
END <br />
&nbsp;<br />
DEALLOCATE curSnapshots <br />
&nbsp;<br />
-------------------------------------------- <br />
-- Captures instantanées de bases de données <br />
-------------------------------------------- <br />
DECLARE curBD CURSOR FOR <br />
&nbsp; SELECT name <br />
&nbsp; FROM sys.databases <br />
&nbsp; WHERE source_database_id IS NULL <br />
&nbsp; AND name NOT IN ('master', 'tempdb', 'model', 'msdb', 'ReportServer', 'ReportServerTempDB') <br />
&nbsp; AND state_desc = 'ONLINE' <br />
FOR READ ONLY <br />
&nbsp;<br />
DECLARE @NomBD SYSNAME, <br />
&nbsp; &nbsp; @ListeFichiers VARCHAR(255) <br />
&nbsp; &nbsp; <br />
OPEN curBD <br />
FETCH NEXT FROM curBD INTO @NomBD <br />
WHILE @@FETCH_STATUS = 0 <br />
BEGIN <br />
&nbsp; SET @ListeFichiers = NULL <br />
&nbsp;<br />
&nbsp; SELECT @ListeFichiers = ISNULL(@ListeFichiers, '') + <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '(NAME = ' + MF.name + ', FILENAME = ''C:\' + MF.name + '.snap'')' + ', ' <br />
&nbsp; FROM sys.master_files AS MF <br />
&nbsp; JOIN sys.databases AS D ON D.database_id = MF.database_id <br />
&nbsp; WHERE D.name = @NomBD <br />
&nbsp; AND MF.type = 0 -- fichiers de données <br />
&nbsp; <br />
&nbsp; SELECT @ListeFichiers = SUBSTRING(@ListeFichiers, 1, LEN(@ListeFichiers) - 1) <br />
&nbsp; <br />
&nbsp; SET @SQL = 'CREATE DATABASE ' + @NomBD + '_' + REPLACE(REPLACE(CONVERT(CHAR(10), GETDATE(), 103) + '_' + CONVERT(CHAR(8), GETDATE(), 108), '/', '_'), ':', '_') <br />
&nbsp; &nbsp; &nbsp; &nbsp; + ' ON ' + @ListeFichiers + <br />
&nbsp; &nbsp; &nbsp; &nbsp; + ' AS SNAPSHOT OF ' + @NomBD <br />
&nbsp;<br />
&nbsp; EXEC (@SQL) <br />
&nbsp; FETCH NEXT FROM curBD INTO @NomBD <br />
END <br />
&nbsp;<br />
DEALLOCATE curBD</div></td></tr></tbody></table></div>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Searchable Arguments, ou S-ARGs, ou comment optimiser la clause WHERE d&#8217;une requête</title>
		<link>https://blog.developpez.com/elsuket/p6886/moteur-de-base-de-donnees-sql-server/sql_searchable_arguments_ou_s_args</link>
		<comments>https://blog.developpez.com/elsuket/p6886/moteur-de-base-de-donnees-sql-server/sql_searchable_arguments_ou_s_args#comments</comments>
		<pubDate>Sat, 06 Dec 2008 01:00:38 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Bien que beaucoup d&#8217;optimisations peuvent être assurées lors du choix du matériel du serveur de base de données, et lors de la conception d&#8217;une base de données, il n&#8217;en reste pas moins que les requêtes, avant de nécessiter la recherche &#8230; <a href="https://blog.developpez.com/elsuket/p6886/moteur-de-base-de-donnees-sql-server/sql_searchable_arguments_ou_s_args">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Bien que beaucoup d&rsquo;optimisations peuvent être assurées lors du choix du matériel du serveur de base de données,  et lors de la conception d&rsquo;une base de données, il n&rsquo;en reste pas moins que les requêtes, avant de nécessiter la recherche d&rsquo;indexes permettant leur optimisation, peuvent être dans un premier temps mises au point au niveau de leur(s) contrainte(s).<br />
C&rsquo;est ce que montrent les S-ARGs, ou &laquo;&nbsp;Searchable Arguments&nbsp;&raquo;</p>
<p><span id="more-70"></span></p>
<p>Je vais tenter de donner une définition assez complète de ce que sont les S-ARGs.<br />
Un S-ARG est de la forme :</p>
<blockquote><p>{colonne} {opérateur} {expression}<br />
{expression} {opérateur} {colonne}</p></blockquote>
<p>Où :</p>
<p>&#8211; {colonne} correspond à un nom de colonne, et pas à une fonction, une expression ou encore un concaténation,<br />
&#8211; {opérateur} peut être l&rsquo;un des symboles mathématiques <img src="http://blog.developpez.com/media/symboles_01.PNG" width="133" height="12" alt="" /> ou encore les clauses IS NULL, BETWEEN et LIKE &lsquo;a%&rsquo;,<br />
&#8211; {expression} est soit une constante, soit une variable valuée à une valeur constante, et est du même type que la colonne dans laquelle elle est recherchée.</p>
<p>Ces clauses sont dites &laquo;&nbsp;cherchables&nbsp;&raquo; parce que l&rsquo;optimiseur de requêtes de SQL Server (et de bien d&rsquo;autres SGBD) se base sur les statistiques pour créer le meilleur plan de requête possible, c&rsquo;est à dire celui qui donnera la réponse à la requête le plus vite possible et un utilisant le moins de ressources possible.</p>
<p>Ces statistiques sont créées avec les indexes, ou encore automatiquement crées par SQL Server.<br />
Elles portent sur les données présentes dans les colonnes, et ne peuvent pas porter sur les données n&rsquo;existant pas dans les colonnes.</p>
<p>Donc, si l&rsquo;expression de la requête n&rsquo;utilise pas de S-ARGs, les indexes et statistiques ne sont pas utilisables, et le moteur de base de données décide donc d&rsquo;effectuer un scan de table, ou un scan d&rsquo;index cluster (celui de la clé primaire), qui est donc long et coûteux.</p>
<p>Dès lors, l&rsquo;utilisation de prédicats tels que OR, NOT, IS NOT NULL, NOT BETWEEN, NOT IN, NOT EXISTS, <img src="http://blog.developpez.com/media/nonsymboles_01.PNG" width="126" height="13" alt="" /> LIKE &lsquo;%a%&rsquo;, LIKE &lsquo;%a&rsquo;, NOT LIKE ne sont pas &laquo;&nbsp;cherchables&nbsp;&raquo;, et rendent la requête plus lente et plus coûteuse, alors qu&rsquo;on peut réécrire la plupart des contraintes de requête &laquo;&nbsp;non-cherchables&nbsp;&raquo; avec des contraintes &laquo;&nbsp;cherchables&nbsp;&raquo; : on peut ainsi souvent remplacer un OR par un AND, un IN par un BETWEEN, ou tout simplement &laquo;&nbsp;inverser&nbsp;&raquo; l&rsquo;expression du prédicat &laquo;&nbsp;non-cherchable&nbsp;&raquo;.</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Les différentes configurations RAID résumées dans une animation</title>
		<link>https://blog.developpez.com/elsuket/p7641/moteur-de-base-de-donnees-sql-server/les_differents_niveaux_de_raid_resumes_d</link>
		<comments>https://blog.developpez.com/elsuket/p7641/moteur-de-base-de-donnees-sql-server/les_differents_niveaux_de_raid_resumes_d#comments</comments>
		<pubDate>Sun, 24 May 2009 22:03:25 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Voici une petite animation qui résume les niveaux de RAID les plus connus. Pour aller plus loin, la page wikipedia consacrée à cette technologie. ElSuket]]></description>
				<content:encoded><![CDATA[<p>Voici une petite <a href="http://www.raidarray.com/04_01_00.html">animation</a> qui résume les niveaux de RAID les plus connus.</p>
<p>Pour aller plus loin, la page <a href="http://fr.wikipedia.org/wiki/RAID_(informatique)">wikipedia</a> consacrée à cette technologie.</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nomination MVP</title>
		<link>https://blog.developpez.com/elsuket/p8139/moteur-de-base-de-donnees-sql-server/non-documente/nomination_mvp_1</link>
		<comments>https://blog.developpez.com/elsuket/p8139/moteur-de-base-de-donnees-sql-server/non-documente/nomination_mvp_1#comments</comments>
		<pubDate>Thu, 01 Oct 2009 21:52:02 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Annonces]]></category>
		<category><![CDATA[Non documenté]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Je viens d&#8217;être nominé MVP SQL Server, et je souhaite associer à ce titre, et remercier toutes les personnes qui maintiennent ce site, et qui participent aux forums. Je tiens à remercier plus particulièrement SQLPro qui m&#8217;a parrainé pour l&#8217;obtention &#8230; <a href="https://blog.developpez.com/elsuket/p8139/moteur-de-base-de-donnees-sql-server/non-documente/nomination_mvp_1">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Je viens d&rsquo;être nominé MVP SQL Server, et je souhaite associer à ce titre, et remercier toutes les personnes qui maintiennent ce site, et qui participent aux forums.</p>
<p>Je tiens à remercier plus particulièrement <a href="http://sqlpro.developpez.com/">SQLPro</a> qui m&rsquo;a parrainé pour l&rsquo;obtention de ce titre.</p>
<p>Je continuerai à contribuer à ce forum aussi fidèlement que je le fais depuis deux ans, tout simplement parce que cela me fait plaisir, et en me concentrant plus sur la publication d&rsquo;articles complets.</p>
<p>@++ <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>3</slash:comments>
		</item>
		<item>
		<title>Connaître le pourcentage d&#8217;avancement d&#8217;une tâche sous SQL Server 2005 et 2008</title>
		<link>https://blog.developpez.com/elsuket/p8122/moteur-de-base-de-donnees-sql-server/connaitre_le_pourcentage_d_avancement_d__2008</link>
		<comments>https://blog.developpez.com/elsuket/p8122/moteur-de-base-de-donnees-sql-server/connaitre_le_pourcentage_d_avancement_d__2008#comments</comments>
		<pubDate>Tue, 29 Sep 2009 17:21:15 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Moteur de base de données SQL Server]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[S&#8217;il est impossible de connaître l&#8217;avancement d&#8217;une requête qui est en cours d&#8217;exécution dans une instance de SQL Server (cela est normal puisque l&#8217;exécution des requêtes n&#8217;est pas &#171;&#160;linéaire&#160;&#187;), il est en revanche possible de connaître l&#8217;avancement des tâches suivantes &#8230; <a href="https://blog.developpez.com/elsuket/p8122/moteur-de-base-de-donnees-sql-server/connaitre_le_pourcentage_d_avancement_d__2008">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>S&rsquo;il est impossible de connaître l&rsquo;avancement d&rsquo;une requête qui est en cours d&rsquo;exécution dans une instance de SQL Server (cela est normal puisque l&rsquo;exécution des requêtes n&rsquo;est pas &laquo;&nbsp;linéaire&nbsp;&raquo;), il est en revanche possible de connaître l&rsquo;avancement des tâches suivantes :</p>
<p><span id="more-89"></span></p>
<p>La vue de gestion dynamique sys.dm_exec_requests, introduite avec SQL Server 2005, expose une colonne percent_complete, qui reste à 0, sauf lors de l&rsquo;exécution des instructions suivantes :</p>
<p>&#8211; ALTER INDEX REORGANIZE<br />
&#8211; BACKUP DATABASE<br />
&#8211; CREATE INDEX<br />
&#8211; DBCC CHECKDB<br />
&#8211; DBCC CHECKFILEGROUP<br />
&#8211; DBCC CHECKTABLE<br />
&#8211; DBCC INDEXDEFRAG<br />
&#8211; DBCC SHRINKDATABASE<br />
&#8211; DBCC SHRINKFILE<br />
&#8211; KILL<br />
&#8211; RESTORE DATABASE<br />
&#8211; UPDATE STATISTICS</p>
<p>ElSuket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
