<?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; SQL Server 2012</title>
	<atom:link href="https://blog.developpez.com/elsuket/pcategory/sql-server-2012/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>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>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>Les posters des permissions pour SQL Server 2008 R2, 2012 et Azure</title>
		<link>https://blog.developpez.com/elsuket/p11954/securite/les-posters-des-permissions-pour-sql-server-2008-r2-2012-et-azure</link>
		<comments>https://blog.developpez.com/elsuket/p11954/securite/les-posters-des-permissions-pour-sql-server-2008-r2-2012-et-azure#comments</comments>
		<pubDate>Tue, 07 May 2013 05:44:33 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Sécurité]]></category>
		<category><![CDATA[SQL Server 2012]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/elsuket/?p=362</guid>
		<description><![CDATA[Si l&#8217;on est un peu perdu dans les privilèges que l&#8217;on peut octroyer à des utilisateurs ou des connexions (logins), ou que l&#8217;on souhaite tout simplement explorer les possibilités offertes par les entités de sécurité, on peut télécharger des posters &#8230; <a href="https://blog.developpez.com/elsuket/p11954/securite/les-posters-des-permissions-pour-sql-server-2008-r2-2012-et-azure">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Si l&rsquo;on est un peu perdu dans les privilèges que l&rsquo;on peut octroyer à des utilisateurs ou des connexions (logins), ou que l&rsquo;on souhaite tout simplement explorer les possibilités offertes par les entités de sécurité, on peut <a href="http://social.technet.microsoft.com/wiki/contents/articles/11842.sql-server-database-engine-permission-posters.aspx">télécharger</a> des posters qui les présentent sous forme de groupes : serveur, base de données, ou pour chaque fonctionnalité du moteur de base de données.</p>
<p>Bon octroi de privilèges !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Le guide technique détaillé de mise à niveau vers SQL Server 2012 &#8230;</title>
		<link>https://blog.developpez.com/elsuket/p11073/sql-server-2012/guide_upgrade_sql_2012</link>
		<comments>https://blog.developpez.com/elsuket/p11073/sql-server-2012/guide_upgrade_sql_2012#comments</comments>
		<pubDate>Wed, 06 Jun 2012 00:11:20 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[&#8230; est maintenant disponible ici Bonne Lecture ! ElSüket]]></description>
				<content:encoded><![CDATA[<p>&#8230; est maintenant disponible <a href="http://blogs.technet.com/b/sqlman/archive/2012/05/21/detailed-sql-server-2012-upgrade-technical-guide-now-available.aspx">ici</a></p>
<p>Bonne Lecture !</p>
<p>ElSüket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tout savoir sur SEQUENCE avec SQL Server 2012</title>
		<link>https://blog.developpez.com/elsuket/p11008/t-sql/sql_server_2012_sequence</link>
		<comments>https://blog.developpez.com/elsuket/p11008/t-sql/sql_server_2012_sequence#comments</comments>
		<pubDate>Sun, 03 Jun 2012 11:03:40 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Implémentation de SQL dans SQL Server longtemps attendue, voici enfin SEQUENCE, qui permet d&#8217;obtenir un nombre augmenté d&#8217;un certain incrément à chaque appel, que l&#8217;on peut partager entre les tables et les utilisateurs d&#8217;une base de données, et bien d&#8217;autre &#8230; <a href="https://blog.developpez.com/elsuket/p11008/t-sql/sql_server_2012_sequence">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Implémentation de SQL dans SQL Server longtemps attendue, voici enfin SEQUENCE, qui permet d&rsquo;obtenir un nombre augmenté d&rsquo;un certain incrément à chaque appel, que l&rsquo;on peut partager entre les tables et les utilisateurs d&rsquo;une base de données, et bien d&rsquo;autre possibilités encore &#8230;<br />
<span id="more-168"></span><br />
<strong>Attention : cet article comporte 6 pages <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></strong></p>
<p>On notera tout d&rsquo;abord qu&rsquo;un objet de type SEQUENCE n&rsquo;est utilisable qu&rsquo;avec des types numériques précis : tinyint, smallint, int, bigint, decimal et numéric, les deux derniers avec une échelle à zéro.</p>
<p>Commençons donc par créer une SEQUENCE de la façon la plus simple qui soit :</p>
<p><code class="codecolorer text default"><span class="text">CREATE SEQUENCE dbo.maSequence</span></code></p>
<p><img src="http://blog.developpez.com/media/sequence_01.PNG" width="289" height="157" alt="" /></p>
<p>C&rsquo;est aussi simple que cela, mais nous allons voir par la suite qu&rsquo;on peut aller un peu plus loin.</p>
<p>Maintenant, comment obtenir la &laquo;&nbsp;première&nbsp;&raquo; valeur de la SEQUENCE dbo.maSequence ?<br />
Là encore, c&rsquo;est relativement simple :</p>
<p><code class="codecolorer text default"><span class="text">SELECT NEXT VALUE FOR dbo.maSequence</span></code></p>
<p><img src="http://blog.developpez.com/media/sequence_02.PNG" width="340" height="204" alt="" /></p>
<p>Donc si l&rsquo;on crée un objet SEQUENCE sans aucune option, le type par défaut est <em>bigint</em>, et la valeur initiale attribuée à cette SEQUENCE est la plus petite valeur que peut stocker le type de données <em>bigint</em>.</p>
<p>Est-ce le cas avec les autres types de données ?</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;">CREATE</span> <span style="color: #0000FF;">SEQUENCE</span> dbo.<span style="color: #202020;">ma_sequence_smallint</span><br />
<span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">smallint</span><br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">VALUE</span> <span style="color: #0000FF;">FOR</span> dbo.<span style="color: #202020;">ma_sequence_smallint</span> <span style="color: #0000FF;">AS</span> next_value_ma_sequence_smallint<br />
GO<br />
<br />
<span style="color: #0000FF;">CREATE</span> <span style="color: #0000FF;">SEQUENCE</span> dbo.<span style="color: #202020;">ma_sequence_tinyint</span><br />
<span style="color: #0000FF;">AS</span> <span style="color: #0000FF;">tinyint</span><br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">VALUE</span> <span style="color: #0000FF;">FOR</span> dbo.<span style="color: #202020;">ma_sequence_tinyint</span> <span style="color: #0000FF;">AS</span> next_value_ma_sequence_tinyint<br />
GO</div></td></tr></tbody></table></div>
<p>
<img src="http://blog.developpez.com/media/sequence_03.PNG" width="657" height="422" alt="" /></p>
<p>Rien de surprenant par rapport au comportement par défaut.<br />
En revanche le fait que la SEQUENCE ne commence pas à 1 comme avec les colonnes de type entier auxquelles on confère la propriété d&rsquo;auto-incrémentation à l&rsquo;aide de la clause IDENTITY est appréciable.</p>
<p>Avant de continuer à nous éclairer sur SEQUENCE, voyons comment connaître les propriétés d&rsquo;un tel objet : la vue système <em>sys.sequences</em> est là pour cela :</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; &nbsp; &nbsp; &nbsp; &nbsp; S.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> sequence_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , T.<span style="color: #202020;">name</span> <span style="color: #0000FF;">AS</span> sequence_data_type_name<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , S.<span style="color: #202020;">start_value</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , S.<span style="color: #202020;">increment</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , S.<span style="color: #202020;">minimum_value</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , S.<span style="color: #202020;">maximum_value</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , S.<span style="color: #202020;">is_cycling</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , S.<span style="color: #202020;">cache_size</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , S.<span style="color: #202020;">current_value</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; , S.<span style="color: #202020;">is_exhausted</span><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> S<br />
<span style="color: #0000FF;">INNER</span> <span style="color: #808080;">JOIN</span>&nbsp; &nbsp; &nbsp; sys.<span style="color: #202020;">types</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;">system_type_id</span> <span style="color: #808080;">=</span> T.<span style="color: #202020;">system_type_id</span></div></td></tr></tbody></table></div>
<p>Ce qui retourne :</p>
<p><img src="http://blog.developpez.com/media/sequence_04.PNG" width="1126" height="376" alt="" /></p>
<p>Je passerai sur la description des colonnes jusqu&rsquo;à <em>maximum_value</em>, et sur <em>current_value</em> puisque leur nom est suffisamment explicite.</p>
<p>La colonne <em>is_cycling</em> nous montre qu&rsquo;il est possible de faire boucler la SEQUENCE, c&rsquo;est à dire de la faire revenir à sa valeur de départ.<br />
La colonne <em>cache_size</em> indique le nombre de valeurs qui est mise en cache. Nous verrons la notion de cache de SEQUENCE par la suite.<br />
Enfin la colonne <em>is_exhausted</em> indique s&rsquo;il est encore possible de générer de nouveaux nombres à partir de celle-ci.</p>
<p>On retrouve les objets SEQUENCE dans l&rsquo;Explorateur d&rsquo;Objets, avec les fonctionnalités accessibles par clic-droit que l&rsquo;on connaît :</p>
<p><img src="http://blog.developpez.com/media/sequence_05.PNG" width="336" height="520" alt="" /></p>
<p>Après un clic sur <em>Propriétés</em> :</p>
<p><img src="http://blog.developpez.com/media/sequence_06.png" width="457" height="759" alt="" /></p>
<p>On obtient la fenêtre suivante :</p>
<p><img src="http://blog.developpez.com/media/sequence_07.png" width="756" height="681" alt="" /></p>
<p>On peut aussi créer une SEQUENCE décrémentielle, simplement en spécifiant un incrément négatif :</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;">CREATE</span> <span style="color: #0000FF;">SEQUENCE</span> uneSequenceDecrementielle<br />
<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: #000;">0</span><br />
<span style="color: #808080;">IN</span>CREMENT <span style="color: #0000FF;">BY</span> <span style="color: #808080;">-</span><span style="color: #000;">5</span><br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">VALUE</span> <span style="color: #0000FF;">FOR</span> uneSequenceDecrementielle<br />
<span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">VALUE</span> <span style="color: #0000FF;">FOR</span> uneSequenceDecrementielle<br />
<span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">VALUE</span> <span style="color: #0000FF;">FOR</span> uneSequenceDecrementielle<br />
<span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">VALUE</span> <span style="color: #0000FF;">FOR</span> uneSequenceDecrementielle<br />
<span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">VALUE</span> <span style="color: #0000FF;">FOR</span> uneSequenceDecrementielle</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/sequence_08.png" /></p>
<p>On peut également changer l&rsquo;incrément en cours de route à l&rsquo;aide d&rsquo;une instruction ALTER SEQUENCE :</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;">ALTER</span> <span style="color: #0000FF;">SEQUENCE</span> dbo.<span style="color: #202020;">uneSequenceDecrementielle</span><br />
<span style="color: #808080;">IN</span>CREMENT <span style="color: #0000FF;">BY</span> <span style="color: #808080;">-</span><span style="color: #000;">2</span><br />
GO<br />
<br />
<span style="color: #0000FF;">SELECT</span> <span style="color: #0000FF;">NEXT</span> <span style="color: #0000FF;">VALUE</span> <span style="color: #0000FF;">FOR</span> uneSequenceDecrementielle</div></td></tr></tbody></table></div>
<p>
<img src="http://blog.developpez.com/media/sequence_09.png" /></p>
<p>Il est également possible, comme le suggère la colonne <em>maximum_value</em> de la vue <em>sys.sequences</em>, mettre une valeur maximale à cette séquence.<br />
Il faut bien sûr dans ce cas que la valeur maximale de la séquence prenne en compte la valeur de départ, sinon celle-ci ne serait pas générable :</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;">SEQUENCE</span> dbo.<span style="color: #202020;">uneSequenceDecrementielle</span><br />
MAXVALUE <span style="color: #808080;">-</span><span style="color: #000;">30</span><br />
GO</div></td></tr></tbody></table></div>
<p>
<img src="http://blog.developpez.com/media/sequence_10.png" /></p>
<p>Ici comme la séquence est décrémentielle, SQL Server rejette l&rsquo;instruction ALTER SEQUENCE puisque nous avions spécifié que la SEQUENCE démarre à zéro.</p>
<p>Si nous changeons par MINVALUE :</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;">SEQUENCE</span> dbo.<span style="color: #202020;">uneSequenceDecrementielle</span><br />
MAXVALUE <span style="color: #808080;">-</span><span style="color: #000;">30</span><br />
GO</div></td></tr></tbody></table></div>
<p>
<img src="http://blog.developpez.com/media/sequence_11.png" /></p>
<p>Voici un message d&rsquo;avertissement intéressant : nous n&rsquo;avons pas spécifié de valeur pour la taille du cache de la SEQUENCE, mais SQL Server en a mis une par défaut &#8230;<br />
J&rsquo;ai tenté de savoir quelle est la taille du cache par défaut, et comment SQL Server stocke celle-ci en utilisant une connexion d&rsquo;administrateur dédiée (DAC), mais il semble que SQL Server réalise cela dans des tables internes.<br />
Si quelqu&rsquo;un découvre cela, merci de le poster en commentaire <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>17</slash:comments>
		</item>
		<item>
		<title>Les nouvelles fonctions T-SQL de SQL Server 2012 &#8211; Episode 2/8 &#8211; FORMAT()</title>
		<link>https://blog.developpez.com/elsuket/p10976/sql-server-2012/sql_server_2012nouvelles_fonctions_forma</link>
		<comments>https://blog.developpez.com/elsuket/p10976/sql-server-2012/sql_server_2012nouvelles_fonctions_forma#comments</comments>
		<pubDate>Tue, 01 May 2012 04:42:11 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Nouvelles fonctions T-SQL]]></category>
		<category><![CDATA[SQL Server 2012]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[A l&#8217;épisode précédent, nous avions abordé les possibilités offertes par la nouvelle fonction PARSE(). Poursuivons avec FORMAT(), qui est une extension de CONVERT(), puisqu&#8217;elle est plus ouverte aux différentes cultures &#8230; et beaucoup plus ! Tout d&#8217;abord, la syntaxe : &#8230; <a href="https://blog.developpez.com/elsuket/p10976/sql-server-2012/sql_server_2012nouvelles_fonctions_forma">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>A l&rsquo;<a href="http://blog.developpez.com/elsuket/c3210/sql-server-2012/nouvelles-fonctions-t-sql/">épisode</a> précédent, nous avions abordé les possibilités offertes par la nouvelle fonction <a href="http://blog.developpez.com/elsuket/p10950/sql-server-2012/sql-server-2012-nouvelles-fonctions-pars/">PARSE()</a>.</p>
<p>Poursuivons avec FORMAT(), qui est une extension de CONVERT(), puisqu&rsquo;elle est plus ouverte aux différentes cultures &#8230; et beaucoup plus !<br />
<span id="more-167"></span><br />
Tout d&rsquo;abord, la syntaxe :</p>
<p><code class="codecolorer text default"><span class="text">FORMAT (valeur, format [, culture ])</span></code></p>
<p>Comme avec PARSE() :</p>
<p>&#8211; la nouveauté c&rsquo;est qu&rsquo;on peut formater une valeur suivant une culture (33 cultures disponibles !)<br />
&#8211; les types supportés par cette fonction : bigint, int, smallint, tinyint, decimal, numeric, float, real, smallmoney, money, date, time, datetime, smalldatetime, datetime2 et datetimeoffset.<br />
&#8211; on ne peut pas utiliser PARSE() pour exécuter une requête sur un serveur distant, car celle-ci dépend du .NET Framework 3.5 SP1 , et que rien ne garantit qu&rsquo;il est présent sur la machine distante.</p>
<p>On remarquera que les types de données de chaînes de caractère, comme pour PARSE(), ne sont pas supportés.<br />
Dès lors, on ne peut pas s&rsquo;attendre à pouvoir passer une date au format ISO dans une chaîne de caractères, et que cela fonctionne :</p>
<p><img src="http://blog.developpez.com/media/format_01.PNG" width="551" height="166" alt="" /></p>
<p>=> <strong>Formatage des dates</strong></p>
<p>Commençons avec quelques exemples sur les dates, qui sont généralement assez recherchés.<br />
Voyons sans la culture d&rsquo;abord :</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">DECLARE @dt date = '20120102' <br />
&nbsp;<br />
SELECT &nbsp;FORMAT(@dt, N'dddd, MMM dd, yyyy') AS anglo_saxon_date_format_0 <br />
&nbsp; , FORMAT(@dt, N'dddd dd MMMM yyyy') AS anglo_saxon_date_format_1 <br />
&nbsp; , FORMAT(@dt, N'dd-MM-yyyy') AS French_numeric_format <br />
&nbsp; , FORMAT(@dt, N'yyyyMMdd') AS ISO_format <br />
&nbsp; , FORMAT(@dt, N'yyyyMMdd HH:mm:ss.000') AS ISO_format_with_time</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/format_02.PNG" width="699" height="241" alt="" /></p>
<p>Et avec la culture :</p>
<p><img src="http://blog.developpez.com/media/format_03.PNG" width="617" height="243" alt="" /></p>
<p>On peut maintenant apprendre les bases d&rsquo;une langue tout en codant <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley" /></p>
<p>En revanche le formatage composite n&rsquo;est pas directement supporté :</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">DECLARE @dt date = '20120102' <br />
&nbsp;<br />
SELECT &nbsp;FORMAT(@dt, N'Nous sommes le dddd dd MMMM yyyy', 'fr-FR')</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/format_04.PNG" width="552" height="187" alt="" /></p>
<p>Attention donc, car les lettres qui correspondent à des parties de date sont automatiquement remplacées, sans qu&rsquo;une erreur ne soit levée.</p>
<p>Essayons d&rsquo;éviter ces lettres :</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">DECLARE @dt date = '20120102' <br />
&nbsp;<br />
SELECT &nbsp;FORMAT(@dt, N'Now : dddd dd MMMM yyyy', 'en-US')</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/format_05.PNG" width="504" height="179" alt="" /></p>
<p>Mais il s&rsquo;agit là d&rsquo;un jeu dangereux.<br />
Voyons si on peut les échapper. Est-ce que le classique anti-slash va fonctionner ?</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">DECLARE @dt date = '20120102' <br />
&nbsp;<br />
SELECT &nbsp;FORMAT(@dt, N'Nou\s \so\m\me\s le dddd dd MMMM yyyy', 'fr-FR')</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/format_07.PNG" width="580" height="195" alt="" /></p>
<p>Il faut reconnaître que c&rsquo;est assez tortueux pour ne pas dire <em><a href="http://fr.wikipedia.org/wiki/Programmation_spaghetti">spaghetti</a></em>.<br />
Par extension, on pourra créer une fonction en T-SQL qui effectue automatiquement l’échappement de ces caractères &#8230;</p>
<p>=> <strong>Examinons maintenant les formats raccourcis</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">DECLARE @dt date = '20120102' <br />
&nbsp;<br />
SELECT &nbsp;FORMAT(@dt, 'D', 'fr-FR') AS weekday_litteral_FR <br />
&nbsp; , FORMAT(@dt, 'D', 'en-US') AS weekday_litteral_US <br />
&nbsp; , FORMAT(@dt, 'd', 'fr-FR') AS decimal_date_FR <br />
&nbsp; , FORMAT(@dt, 'd', 'en-US') AS decimal_date_US <br />
&nbsp; , FORMAT(@dt, 'm', 'fr-FR') AS month_date_litteral_FR <br />
&nbsp; , FORMAT(@dt, 'm', 'en-US') AS month_date_litteral_US <br />
&nbsp; , FORMAT(@dt, 'M', 'fr-FR') AS month_date_litteral_FR_case <br />
&nbsp; , FORMAT(@dt, 'M', 'en-US') AS month_date_litteral_US_case</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/format_08.PNG" width="1100" height="293" alt="" /></p>
<p>Attention donc à la casse dans les formats !<br />
On notera que le zéro non-significatif disparaît au format Français, mais demeure au format Anglo-saxon.</p>
<p>J&rsquo;ai trouvé ceux-ci à tâtons. Voyons les dans leur ensemble :</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">DECLARE @now datetime = GETDATE() <br />
&nbsp; , @amount decimal(6,2) = 1234.56 <br />
&nbsp; , @integer int = 123456 <br />
&nbsp; , @percent decimal(3,2) = 0.76 <br />
&nbsp; , @fr char(5) = 'fr-FR' <br />
&nbsp; , @us char(5) = 'en-US' <br />
&nbsp;<br />
SELECT &nbsp; &nbsp;'Currency 1' AS label, @fr AS culture, 'FORMAT(@amount, ''c'', @fr)' AS sql, FORMAT(@amount, 'c', @fr) AS exemple <br />
UNION ALL &nbsp;SELECT 'Currency 2' AS label, @us AS culture, 'FORMAT(@amount, ''c'', @us)', FORMAT(@amount, 'c', @us) AS exemple <br />
-- <br />
UNION ALL &nbsp;SELECT 'Currency 3', @fr, 'FORMAT(@amount, ''C'', @fr)', FORMAT(@amount, 'C', @fr) <br />
UNION ALL &nbsp;SELECT 'Currency 4', @us, 'FORMAT(@amount, ''C'', @us)', FORMAT(@amount, 'C', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Decimal 1', @fr, 'FORMAT(@integer, ''d'', @fr)', FORMAT(@integer, 'd', @fr) <br />
UNION ALL &nbsp;SELECT 'Decimal 2', @us, 'FORMAT(@integer, ''d'', @us)', FORMAT(@integer, 'd', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Decimal 3', @fr, 'FORMAT(@integer, ''D'', @fr)', FORMAT(@integer, 'D', @fr) <br />
UNION ALL &nbsp;SELECT 'Decimal 4', @us, 'FORMAT(@integer, ''D'', @us)', FORMAT(@integer, 'D', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Decimal 5', @fr, 'FORMAT(@integer, ''D8'', @fr)', FORMAT(@integer, 'D8', @fr) <br />
UNION ALL &nbsp;SELECT 'Decimal 6', @us, 'FORMAT(@integer, ''D8'', @us)', FORMAT(@integer, 'D8', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Full date time, short time 1', @fr, 'FORMAT(@now, ''f'', @fr)', FORMAT(@now, 'f', @fr) <br />
UNION ALL &nbsp;SELECT 'Full date time, short time 2', @us, 'FORMAT(@now, ''f'', @us)', FORMAT(@now, 'f', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Full date time, long time 1', @fr, 'FORMAT(@now, ''F'', @fr)', FORMAT(@now, 'F', @fr) <br />
UNION ALL &nbsp;SELECT 'Full date time, long time 2', @us, 'FORMAT(@now, ''F'', @us)', FORMAT(@now, 'F', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'General date time, short time 1', @fr, 'FORMAT(@now, ''g'', @fr)', FORMAT(@now, 'g', @fr) <br />
UNION ALL &nbsp;SELECT 'General date time, short time 2', @us, 'FORMAT(@now, ''g'', @us)', FORMAT(@now, 'g', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'General date time, long time 1', @fr, 'FORMAT(@now, ''G'', @fr)', FORMAT(@now, 'G', @fr) <br />
UNION ALL &nbsp;SELECT 'General date time, long time 2', @us, 'FORMAT(@now, ''G'', @us)', FORMAT(@now, 'G', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Short time 1', @fr, 'FORMAT(@now, ''t'', @fr)', FORMAT(@now, 't', @fr) <br />
UNION ALL &nbsp;SELECT 'Short time 2', @us, 'FORMAT(@now, ''t'', @us)', FORMAT(@now, 't', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Long time 1', @fr, 'FORMAT(@now, ''T'', @fr)', FORMAT(@now, 'T', @fr) <br />
UNION ALL &nbsp;SELECT 'Long time 2', @us, 'FORMAT(@now, ''T'', @us)', FORMAT(@now, 'T', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Numeric 1', @fr, 'FORMAT(@amount, ''n'', @fr)', FORMAT(@amount, 'n', @fr) <br />
UNION ALL &nbsp;SELECT 'Numeric 2', @us, 'FORMAT(@amount, ''n'', @us)', FORMAT(@amount, 'n', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Numeric 3', @fr, 'FORMAT(@amount, ''N'', @fr)', FORMAT(@amount, 'N', @fr) <br />
UNION ALL &nbsp;SELECT 'Numeric 4', @us, 'FORMAT(@amount, ''N'', @us)', FORMAT(@amount, 'N', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Numeric 5', @fr, 'FORMAT(@amount, ''N0'', @fr)', FORMAT(@amount, 'N0', @fr) <br />
UNION ALL &nbsp;SELECT 'Numeric 6', @us, 'FORMAT(@amount, ''N0'', @us)', FORMAT(@amount, 'N0', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Numeric 7', @fr, 'FORMAT(@amount, ''N1'', @fr)', FORMAT(@amount, 'N1', @fr) <br />
UNION ALL &nbsp;SELECT 'Numeric 8', @us, 'FORMAT(@amount, ''N1'', @us)', FORMAT(@amount, 'N1', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Percentage 1', @fr, 'FORMAT(@percent, ''p'', @fr)', FORMAT(@percent, 'p', @fr) <br />
UNION ALL &nbsp;SELECT 'Percentage 2', @us, 'FORMAT(@percent, ''p'', @us)', FORMAT(@percent, 'p', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Percentage 3', @fr, 'FORMAT(@percent, ''P0'', @fr)', FORMAT(@percent, 'P0', @fr) <br />
UNION ALL &nbsp;SELECT 'Percentage 4', @us, 'FORMAT(@percent, ''P0'', @us)', FORMAT(@percent, 'P0', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Percentage 5', @fr, 'FORMAT(@percent, ''P1'', @fr)', FORMAT(@percent, 'P1', @fr) <br />
UNION ALL &nbsp;SELECT 'Percentage 6', @us, 'FORMAT(@percent, ''P1'', @us)', FORMAT(@percent, 'P1', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Hexadecimal 1', @fr, 'FORMAT(@integer, ''x'', @fr)', FORMAT(@integer, 'x', @fr) <br />
UNION ALL &nbsp;SELECT 'Hexadecimal 2', @us, 'FORMAT(@integer, ''x'', @us)', FORMAT(@integer, 'x', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Hexadecimal 3', @fr, 'FORMAT(@integer, ''X'', @fr)', FORMAT(@integer, 'X', @fr) <br />
UNION ALL &nbsp;SELECT 'Hexadecimal 4', @us, 'FORMAT(@integer, ''X'', @us)', FORMAT(@integer, 'X', @us) <br />
-- <br />
UNION ALL &nbsp;SELECT 'Hexadecimal 5', @fr, 'FORMAT(@integer, ''X10'', @fr)', FORMAT(@integer, 'X10', @fr) <br />
UNION ALL &nbsp;SELECT 'Hexadecimal 6', @us, 'FORMAT(@integer, ''X10'', @us)', FORMAT(@integer, 'X10', @us)</div></td></tr></tbody></table></div>
<p><img src="http://img17.imageshack.us/img17/5430/format12.png" alt="" title="" /></p>
<p>On voit donc que pour le formatage de données :</p>
<p>&#8211; numériques, la casse du format court n&rsquo;a pas d&rsquo;importance<br />
&#8211; numériques, on peut ajouter un chiffre au format court qui indique soit le nombre de décimales, soit la largeur de la mantisse<br />
&#8211; numériques de devise, la culture change bien évidemment le résultat<br />
&#8211; de date, la casse est importante, de même que la culture</p>
<p>=> <strong>Étudions les devises plus en détails</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 /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT &nbsp;FORMAT(1234.56, 'C', 'en-US') AS US_format <br />
&nbsp; , FORMAT(1234.56, 'C', 'fr-FR') AS French_format <br />
&nbsp; , FORMAT(1234.56, 'C', 'de-DE') AS German_format <br />
&nbsp; , FORMAT(1234.56, 'C', 'en-GB') AS UK_format <br />
&nbsp; , FORMAT(1234.56, 'C', 'sv-SE') AS Swedish_format <br />
&nbsp; , FORMAT(1234.56, 'C', 'th-TH') AS Thai_format <br />
&nbsp; , FORMAT(1234.56, 'C', 'ar-SA') AS Arabic_format</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/format_13.PNG" width="615" height="246" alt="" /></p>
<p>On voit que les formats de devises sont rigoureusement respectés, notamment en ce qui concerne les points et les virgules : les anglo-saxons utilisent la virgule comme séparateur des puissances de 10 multiples de 3, alors que les Latins utilisent le point; et inversement pour les parties décimales.<br />
De même la prise en compte des pays membres de la Zone Euro ont tous leur devise préfixée ou suffixée par le symbole €, alors que le Royaume-Uni et la Suède, qui n&rsquo;en sont pas membres, ont bien évidemment conservé respectivement les symboles de la Livre Sterling et de la Couronne Suédoise.</p>
<p>Une petite remarque : en Arabe, la notation retournée par SQL Server n&rsquo;est strictement identique à ce que l&rsquo;on observe rien qu&rsquo;en collant cette valeur de fenêtre de résultats dans la fenêtre de requêtes de <em>SQL Server Management Studio</em> :</p>
<p><img src="http://blog.developpez.com/media/format_09.PNG" width="452" height="54" alt="" /></p>
<p>J&rsquo;ai essayé de faire traduire automatiquement par <em>Google Translate</em>, mais le résultat retourné est <em>R.. Q. 1,234.56</em>.<br />
Si vous pouvez expliquer ce qui s&rsquo;est passé, n&rsquo;hésitez pas à poster un commentaire !</p>
<p>=> <strong>Les masques pour les valeurs numériques</strong></p>
<p>Les masques permettent de spécifier le nombre de décimales pour une valeur numérique, et si l&rsquo;on en a besoin, d&rsquo;ajouter des symboles dans la valeur formatée à l&rsquo;aide de la position :</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">DECLARE @uneValeur decimal(6,2) = 1234.56 <br />
&nbsp;<br />
SELECT &nbsp;FORMAT(@uneValeur, '##,##0.00') AS exemple_1 <br />
&nbsp; , FORMAT(@uneValeur, '#,##0.00') AS exemple_2 <br />
&nbsp; , FORMAT(@uneValeur, '#,#0.00') AS exemple_3 <br />
&nbsp; , FORMAT(@uneValeur, '#,#0.0') AS exemple_4 <br />
&nbsp; , FORMAT(@uneValeur, '#,#0') AS exemple_5 <br />
&nbsp; , FORMAT(@uneValeur, '#0') AS exemple_6 <br />
&nbsp; , FORMAT(@uneValeur, '#0.0') AS exemple_7 <br />
&nbsp; , FORMAT(@uneValeur, '#0.00') AS exemple_8 <br />
&nbsp; , FORMAT(@uneValeur, '#0.000') AS exemple_9 <br />
&nbsp; , FORMAT(@uneValeur, '#|#0.000') AS exemple_10 <br />
&nbsp; , FORMAT(@uneValeur, '#\#0.000') AS exemple_11</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/format_14.PNG" width="817" height="341" alt="" /></p>
<p>Dans les colonnes exemple_2 et exemple_10, on a respectivement placé :</p>
<p>&#8211; une virgule avant les trois derniers chiffres de la partie entière de la valeur décimale<br />
&#8211; un pipe avant les deux derniers chiffres de la partie entière de la valeur décimale</p>
<p>Dans la colonne exemple_11, l&rsquo;antislash étant un caractère d&rsquo;échappement, il y a donc un symbole <em>dièse</em> qui sera intercalé entre le dernier et l&rsquo;avant-dernier chiffre de la partie entière de la valeur décimale.</p>
<p>De la même façon que ce que nous avons vu avec les formats courts, on peut aussi préciser le nombre de chiffres significatifs de la partie décimale d&rsquo;une telle valeur.<br />
Si le nombre de chiffres significatifs de la partie décimale :</p>
<p>&#8211; est plus petit que celui de la valeur passée en paramètre, alors la valeur formatée est arrondie<br />
&#8211; est plus grand que celui de la valeur passée en paramètre, alors la valeur formatée est suivie d&rsquo;autant de zéros que la différence entre le nombre de chiffres significatifs de la partie décimale et le nombre de chiffres de la partie décimale du masque de formatage.</p>
<p>Bon FORMATage de données à tous !</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installer l&#8217;aide de SQL Server 2012 localement</title>
		<link>https://blog.developpez.com/elsuket/p10966/sql-server-2012/installer_aid_sql_server_2012_local</link>
		<comments>https://blog.developpez.com/elsuket/p10966/sql-server-2012/installer_aid_sql_server_2012_local#comments</comments>
		<pubDate>Sat, 21 Apr 2012 18:12:00 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[SQL Server 2012]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Jusqu&#8217;à SQL Server 2008, l&#8217;aide de SQL Server, aussi connue sous le nom de SQL Server Books OnLine ou BOL, était installable localement en même temps qu&#8217;une instance SQL Server. Cela a changé avec SQL Server 2012, qui démarre automatiquement &#8230; <a href="https://blog.developpez.com/elsuket/p10966/sql-server-2012/installer_aid_sql_server_2012_local">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Jusqu&rsquo;à SQL Server 2008, l&rsquo;aide de SQL Server, aussi connue sous le nom de <em>SQL Server Books OnLine</em> ou <em>BOL</em>, était installable localement en même temps qu&rsquo;une instance SQL Server.<br />
Cela a changé avec SQL Server 2012, qui démarre automatiquement <em>Internet Explorer</em> et ouvre la page qui correspond à ce que l&rsquo;on a surligné avant de presser F1.</p>
<p>Si c&rsquo;est efficace et que l&rsquo;on peut comprendre pourquoi Microsoft a décidé de ne plus inclure les fichiers d&rsquo;aide dans le package d&rsquo;installation de SQL Server (poids plus léger, simplicité de maintenance de l&rsquo;aide, et tous les développeurs et DBAs en en général accès à Internet), que se passe-t-il si l&rsquo;on a besoin de consulter la documentation de SQL Server sur un serveur de production, qui n&rsquo;a généralement pas d&rsquo;accès à Internet pour des raisons de sécurité ? C&rsquo;est aussi pratique pour les favoris, qui permettent de consulter la syntaxe d&rsquo;une commande fréquemment utilisée mais dont on ne retient pas forcément toutes les options et subtilités.</p>
<p>On peut toujours installer celle-ci localement. Voyons comment procéder &#8230;<br />
<span id="more-166"></span><br />
Il faut d&rsquo;abord paramétrer SQL Server Management Studio 2012 pour indiquer que l&rsquo;on préfère consulter l&rsquo;aide localement.<br />
Pour ce faire, il suffit de cliquer sur <em>Help</em> puis <em>Manage Help Settings</em> :</p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale01.png" width="801" height="247" alt="" /></p>
<p>Puis de choisir entre l&rsquo;aide locale et l&rsquo;aide en ligne :</p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale03.png" width="574" height="390" alt="" /></p>
<p>Ce qui sera fait très simplement après avoir changé le bouton radio sur :</p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale05_01.png" width="571" height="388" alt="" /></p>
<p>Il faut ensuite procéder au téléchargement des fichiers :</p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale06.png" width="572" height="389" alt="" /></p>
<p>La recherche de fichiers d&rsquo;aide s&rsquo;effectue en quelques secondes :</p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale07.png" width="571" height="388" alt="" /></p>
<p>et l&rsquo;on obtient la liste de nombreuses aides de produits <em>Microsoft</em> :</p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale08.png" width="571" height="389" alt="" /></p>
<p>Il suffit de faire défiler jusqu&rsquo;à trouver celle de SQL Server, et de cliquer sur <em>Add</em> :</p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale09.png" width="570" height="388" alt="" /></p>
<p>S&rsquo;ensuit le téléchargement qui dure quelques secondes :</p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale10.png" width="572" height="391" alt="" /></p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale11.png" width="571" height="390" alt="" /></p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale12.jpg" width="565" height="383" alt="" /></p>
<p>Après un clic sur le bouton Finish, on peut quitter :</p>
<p><img src="http://img834.imageshack.us/img834/7645/sqlserver2012installaid.png" alt="" title="" /></p>
<p>Voyons maintenant comment tout cela se présente : essayons de consulter l&rsquo;aide de <code class="codecolorer text default"><span class="text">CREATE TABLE</span></code> :</p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale14.png" width="773" height="300" alt="" /></p>
<p>Après avoir surligné l&rsquo;instruction et pressé F1, l&rsquo;application <em>Help Viewer</em> démarre (c&rsquo;est très rapide).<br />
L&rsquo;application demeure accessible à partir de zone de notification (regardez bien en bas à droite de la capture ci-dessous) :</p>
<p><img src="http://img835.imageshack.us/img835/7645/sqlserver2012installaid.png" alt="" title="" /></p>
<p>L&rsquo;application s&rsquo;ouvre directement sur la documentation de l&rsquo;instruction <code class="codecolorer text default"><span class="text">CREATE TABLE</span></code> :</p>
<p><img src="http://img705.imageshack.us/img705/7645/sqlserver2012installaid.png" alt="" title="" /></p>
<p>Et on retrouve le bouton d&rsquo;ajout aux favoris :</p>
<p><img src="http://blog.developpez.com/media/sql_server_2012_install_aide_locale17.png" width="659" height="426" alt="" /></p>
<p>La recherche de la documentation d&rsquo;autres instructions se fait tout aussi aisément et rapidement : voyons <code class="codecolorer text default"><span class="text">CREATE INDEX</span></code> :</p>
<p><img src="http://img845.imageshack.us/img845/7645/sqlserver2012installaid.png" alt="" title="" /></p>
<p>Toutes les instructions contenant les deux mots apparaissent dans le panneau de navigation, à gauche, avec un extrait du début de la documentation de chacune des instructions trouvées :</p>
<p><img src="http://img812.imageshack.us/img812/7645/sqlserver2012installaid.png" alt="" title="" /></p>
<p>Cliquons sur la première, puisque c&rsquo;est celle qui nous intéresse :</p>
<p><img src="http://img853.imageshack.us/img853/7645/sqlserver2012installaid.png" alt="" title="" /></p>
<p>Documentez-vous bien, car les ajouts de fonctionnalités et <a href="http://blog.developpez.com/elsuket/c3210/sql-server-2012/nouvelles-fonctions-t-sql/">nouvelles fonctions T-SQL</a> dans <a href="http://blog.developpez.com/elsuket/c3209/sql-server-2012/">SQL Server 2012</a> sont nombreux !</p>
<p>ElSüket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Les nouvelles fonctions T-SQL de SQL Server 2012 &#8211; Episode 1/8 &#8211; PARSE() &#8211;</title>
		<link>https://blog.developpez.com/elsuket/p10950/t-sql/sql_server_2012_nouvelles_fonctions_pars</link>
		<comments>https://blog.developpez.com/elsuket/p10950/t-sql/sql_server_2012_nouvelles_fonctions_pars#comments</comments>
		<pubDate>Mon, 16 Apr 2012 12:18:57 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Nouvelles fonctions T-SQL]]></category>
		<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Je vous propose de découvrir les 14 nouvelles fonctions que SQL Server 2012 introduit, en dédiant un billet soit à chacune d&#8217;entre-elles, ou bien à un groupe d&#8217;entre-elles. Commençons avec la fonction PARSE() &#8230; La syntaxe d&#8217;utilisation de cette fonction &#8230; <a href="https://blog.developpez.com/elsuket/p10950/t-sql/sql_server_2012_nouvelles_fonctions_pars">Lire la suite <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Je vous propose de découvrir les 14 nouvelles fonctions que SQL Server 2012 introduit, en dédiant un billet soit à chacune d&rsquo;entre-elles, ou bien à un groupe d&rsquo;entre-elles.</p>
<p>Commençons avec la fonction PARSE() &#8230;<br />
<span id="more-165"></span><br />
La syntaxe d&rsquo;utilisation de cette fonction est la suivante :</p>
<p><code class="codecolorer text default"><span class="text">PARSE('&lt;uneValeur&gt;' AS &lt;data_type&gt; [USING '&lt;culture&gt;'])</span></code></p>
<p>La nouveauté c&rsquo;est la possibilité de formater une valeur suivant une culture, et ce n&rsquo;est pas moins de 33 cultures qui sont disponibles !<br />
De façon générale, cette fonction est une extension de ce que l&rsquo;on peut faire avec CONVERT().<br />
Rappelons dans les deux cas qu&rsquo;il s&rsquo;agit de fonctions de formatage de données.</p>
<p>On notera que :</p>
<p>&#8211; <em>data_type</em> est limité aux types suivants : bigint, int, smallint, tinyint, decimal, numeric, float, real, smallmoney, money, date, time, datetime, smalldatetime, datetime2 et datetimeoffset.</p>
<p>&#8211; On ne peut pas utiliser PARSE() pour exécuter une requête sur un serveur distant, car celle-ci dépend du .NET Framework 3.5 SP1 , et que rien ne garantit qu&rsquo;il est présent sur la machine distante.</p>
<p>Faisons quelques essais !</p>
<p><code class="codecolorer text default"><span class="text">SELECT PARSE ('100.000' AS int)</span></code></p>
<p><img src="http://blog.developpez.com/media/parse_01.PNG" width="469" height="153" alt="" /></p>
<p>Alors qu&rsquo;un <code class="codecolorer text default"><span class="text">SELECT CONVERT(int, '100.000')</span></code> :</p>
<p><img src="http://blog.developpez.com/media/parse_02.png" width="625" height="167" alt="" /></p>
<p>Essayons un <code class="codecolorer text default"><span class="text">SELECT PARSE('Lundi 16 Avril 2012' AS datetime USING 'fr-FR')</span></code></p>
<p><img src="http://blog.developpez.com/media/parse_03.PNG" width="528" height="154" alt="" /></p>
<p>Voyons au format Anglo-Saxon : <code class="codecolorer text default"><span class="text">SELECT PARSE('Monday 16 April 2012' AS datetime USING 'en-US')</span></code></p>
<p><img src="http://blog.developpez.com/media/parse_04.PNG" width="527" height="168" alt="" /></p>
<p>Quid du format que l&rsquo;on nous a donné à l&rsquo;école ? <code class="codecolorer text default"><span class="text">SELECT PARSE('Monday, April 16 2012' AS datetime USING 'en-US')</span></code></p>
<p><img src="http://blog.developpez.com/media/parse_05.png" width="529" height="162" alt="" /></p>
<p>En revanche <code class="codecolorer text default"><span class="text">SELECT PARSE('Monday, April 16th 2012' AS datetime USING 'en-US')</span></code></p>
<p><img src="http://blog.developpez.com/media/parse_06.PNG" width="751" height="155" alt="" /></p>
<p>Essayons <code class="codecolorer text default"><span class="text">SELECT PARSE('April, 16 2012' AS datetime USING 'en-US')</span></code></p>
<p><img src="http://blog.developpez.com/media/parse_07.png" width="517" height="164" alt="" /></p>
<p>Voyons avec une date du calendrier Grégo-Thaï : en effet, le calendrier Grégo-Thaï à 543 ans d&rsquo;avance sur le calendrier Grégorien :<br />
<code class="codecolorer text default"><span class="text">SELECT PARSE(N'16 &amp;#3648;&amp;#3617;&amp;#3625;&amp;#3634;&amp;#3618;&amp;#3609; 2555' AS datetime USING 'Th-TH')</span></code></p>
<p><img src="http://blog.developpez.com/media/parse_08.PNG" width="516" height="158" alt="" /></p>
<p>Et avec des variables ?</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">DECLARE @date_string char(20) = 'Lundi 16 Avril 2012' <br />
&nbsp; , @culture char(5) = 'fr-FR' <br />
&nbsp;<br />
SELECT PARSE(@date_string AS datetime USING @culture)</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/parse_09.PNG" width="524" height="216" alt="" /></p>
<p>Et dans une table :</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">CREATE TABLE test_PARSE <br />
( <br />
&nbsp; date_string nvarchar(20) <br />
&nbsp; , culture char(5) <br />
&nbsp; , formatted_date AS (PARSE(date_string AS datetime USING culture)) <br />
) <br />
GO <br />
&nbsp;<br />
INSERT &nbsp;INTO dbo.test_PARSE <br />
VALUES &nbsp;(N'Lundi 16 Avril 2012', 'fr-FR'), (N'16 &amp;#3648;&amp;#3617;&amp;#3625;&amp;#3634;&amp;#3618;&amp;#3609; 2555', 'th-TH') <br />
GO <br />
&nbsp;<br />
SELECT &nbsp;* <br />
FROM &nbsp;dbo.test_PARSE</div></td></tr></tbody></table></div>
<p><img src="http://blog.developpez.com/media/parse_10.PNG" width="597" height="376" alt="" /></p>
<p>Vous vous demandez s&rsquo;il sera possible de retourner une valeur décimale avec le symbole de la devise suivant une culture ? la réponse est oui : avec la fonction FORMAT(), que nous verrons au prochain épisode <img src="https://blog.developpez.com/elsuket/wp-includes/images/smilies/icon_wink.gif" alt=";)" class="wp-smiley" /></p>
<p>Bon formatage de données !</p>
<p>ElSüket</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Le petit lien qui fait du bien dans l&#8217;historique des jobs de l&#8217;Agent SQL Server 2012</title>
		<link>https://blog.developpez.com/elsuket/p10965/agent-sql-server/ssms_2012_job_historique_lien_definition</link>
		<comments>https://blog.developpez.com/elsuket/p10965/agent-sql-server/ssms_2012_job_historique_lien_definition#comments</comments>
		<pubDate>Thu, 19 Apr 2012 17:52:22 +0000</pubDate>
		<dc:creator><![CDATA[elsuket]]></dc:creator>
				<category><![CDATA[Agent SQL Server]]></category>
		<category><![CDATA[SQL Server 2012]]></category>

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