<?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 de SQLpro &#187; PostGreSQL</title>
	<atom:link href="https://blog.developpez.com/sqlpro/pcategory/postgresql/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/sqlpro</link>
	<description>Le SQL pour SQL Server, PostGreSQL et tous les autres SGBDR</description>
	<lastBuildDate>Thu, 15 Oct 2020 12:59:17 +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>BENCHMARK SIG : PostGreSQL vs MS SQL Server</title>
		<link>https://blog.developpez.com/sqlpro/p13148/langage-sql-norme/755</link>
		<comments>https://blog.developpez.com/sqlpro/p13148/langage-sql-norme/755#comments</comments>
		<pubDate>Mon, 01 May 2017 14:54:34 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[PostGreSQL]]></category>
		<category><![CDATA[SQL Server 2016]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=755</guid>
		<description><![CDATA[La présent article compare les performances de requêtes basiques du système d&#8217;information géographique de PostGreSQL (v 9.6.1) et de SQL Server (version 2016). Comparaison des performances de SIG PostGreSQL/PostGIS vs SQL Server Spatial]]></description>
				<content:encoded><![CDATA[<p>La présent article compare les performances de requêtes basiques du système d&rsquo;information géographique de PostGreSQL (v 9.6.1) et de SQL Server (version 2016).</p>
<p><a href="http://g-ernaelsten.developpez.com/tutoriels/comparatif-sig-et-performances/" title="BENCHMARK SIG : PostGreSQL vs MS SQL Server" target="_blank">Comparaison des performances de SIG<br />
PostGreSQL/PostGIS vs SQL Server Spatial</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Benchmark PostgreSQL vs SQL Server&#8230; comment biaiser !</title>
		<link>https://blog.developpez.com/sqlpro/p12959/langage-sql-norme/benchmark-postgresql-vs-sql-server-comment-biaiser</link>
		<comments>https://blog.developpez.com/sqlpro/p12959/langage-sql-norme/benchmark-postgresql-vs-sql-server-comment-biaiser#comments</comments>
		<pubDate>Tue, 17 Nov 2015 22:25:52 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[PostGreSQL]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[Benchmark]]></category>
		<category><![CDATA[comparaison]]></category>
		<category><![CDATA[SQL server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=626</guid>
		<description><![CDATA[La mauvaise foi règne encore chez les aficionados de PostGreSQL&#8230; L&#8217;entreprise Red Hat, que je croyais sérieuse, à effectué un benchmark entre PostGreSQL et SQL Server stupéfiant de mauvaise foi&#8230; Voici mes remarques. À noter, ce comparatif porte sur une version payante de PostGreSQL ! On trouvera le benchmark dont je parle &#171;&#160;Comparing BenchmarkSQL Performance [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>La mauvaise foi règne encore chez les aficionados de PostGreSQL&#8230; L&rsquo;entreprise Red Hat, que je croyais sérieuse, à effectué un benchmark entre PostGreSQL et SQL Server stupéfiant de mauvaise foi&#8230; Voici mes remarques. À noter, ce comparatif porte sur une version payante de PostGreSQL !<br />
<span id="more-626"></span><br />
On trouvera le benchmark dont je parle &laquo;&nbsp;Comparing BenchmarkSQL Performance on Red Hat® Enterprise Linux 5 to Windows Server Enterprise&nbsp;&raquo; à l&rsquo;URL :<br />
<a href="https://www.redhat.com/pdf/rhel/bmsql-postgres-sqlsrvr-v1.0-1.pdf" title="Comparing BenchmarkSQL Performance on Red Hat® Enterprise Linux 5 to Windows Server Enterprise" target="_blank">https://www.redhat.com/pdf/rhel/bmsql-postgres-sqlsrvr-v1.0-1.pdf</a></p>
<p>Passons sur le choix du benchmark : le TPC-C qui date de 1992 (soit 23 ans&#8230;) est constitué d&rsquo;une base de données qui comporte 9 tables et dont on peut trouver le détail à l&rsquo;URL :<br />
<a href="http://www.tpc.org/tpc_documents_current_versions/pdf/tpc-c_v5-11.pdf" title="Détail du benchmark TPC-C" target="_blank">http://www.tpc.org/tpc_documents_current_versions/pdf/tpc-c_v5-11.pdf</a>. Qui aujourd&rsquo;hui utilise en production une base composée au plus de 9 tables ? En revanche il existe un benchmark plus moderne, le TPC-E composé de 33 tables nettement plus réaliste !</p>
<p><strong>TUNING DES OS</strong></p>
<p>À la page 10 dudit benchmark on trouve le paragraphe <em>3.3.1 (Operating System)</em> qui montre comment à été optimisé Linux.</p>
<p><a href="http://blog.developpez.com/sqlpro/files/2015/11/PostGreSQL-vs-SQL-Server-OS-Tuning.jpg"><img src="http://blog.developpez.com/sqlpro/files/2015/11/PostGreSQL-vs-SQL-Server-OS-Tuning.jpg" alt="PostGreSQL vs SQL Server OS Tuning" width="829" height="621" class="alignnone size-full wp-image-630" /></a></p>
<p>On y voit clairement que <strong>seul l&rsquo;OS Linux a été optimisé</strong>. Quelles optimisations ont été faites pour Windows ? <strong>Aucune !</strong></p>
<p>Or il est bien évident qu&rsquo;une installation standard de Windows pour héberger SQL Server n&rsquo;est pas optimale sans certains réglages :<br />
&#8211; désactivation des services inutiles (ce qui a été fait pour Linux et pas pour Windows)<br />
&#8211; désactivation du système d&rsquo;économie d’énergie (qui n&rsquo;existe pas sous Linux.. pas écolo les linuxiens !)<br />
&#8211; activation de Turbo Boost<br />
&#8211; activation de l&rsquo;Instant File Initialization pour le service SQL Server<br />
&#8211; activation du Lock Page in Memory pour SQL Server<br />
&#8230;</p>
<p><strong>TUNING DES SGBDR</strong></p>
<p>À la page 11 figure le paragraphe 3.3.3 (Database) qui montre comment a été optimisé PostGreSQL.</p>
<p><a href="http://blog.developpez.com/sqlpro/files/2015/11/PostGreSQL-vs-SQL-Server-database-Tuning.jpg"><img src="http://blog.developpez.com/sqlpro/files/2015/11/PostGreSQL-vs-SQL-Server-database-Tuning.jpg" alt="PostGreSQL vs SQL Server database Tuning" width="819" height="563" class="alignnone size-full wp-image-631" /></a></p>
<p>On y voit clairement que <strong>seul PostGreSQL a été optimisé</strong>. Red Hat revendique même sa tromperie : &laquo;&nbsp;<em>&#8230;no specific SQL Server tuning was performed</em>&nbsp;&raquo; !</p>
<p>Or il est bien évident que plusieurs optimisations sont nécessaires :<br />
&#8211; la ventilation du stockage des fichiers de données de la base tempdb (objets temporaires) en autant de fichiers d&rsquo;égales longueur que de CPU (donc au moins 2);<br />
&#8211; le dimensionnement correct des fichiers de la base de données à 40 Go pour les données et 10 Go pour les transactions avec à nouveau au moins 2 fichiers pour les données<br />
&#8211; la limitation de la RAM utilisée par SQL Server à au moins 44 Go (max server memory);<br />
&#8211; la limitation du parallélisme des requêtes à 4 (du fait que le serveur présente 2 CPU Quad Core et 4 LUN par agrégats RAID) et hausse du seuil de déclenchement à 12 (cost threshold for parallelism);<br />
&#8211; le positionnement du paramètre &laquo;&nbsp;optimize for ad hoc workloads&nbsp;&raquo; à 1 sinon les plans de requête ne sont pas mis en cache !<br />
&#8211; l&rsquo;élévation du délai de report des écritures physique de données (checkpoint), paramètre &laquo;&nbsp;recovery interval&nbsp;&raquo;, à 60 minutes pour coller au paramètre &laquo;&nbsp;checkpoint_timeout &nbsp;&raquo; positionné à 1 heure dans PostGreSQL (un délai tout à fait anormal entre nous, car cela pourrait s&rsquo;avérer dangereux en production&#8230;)<br />
&#8230;</p>
<p><strong>POSTGRESQL PLUS</strong></p>
<p>Très discrètement, le document montre que la version testée de PostGreSQL n&rsquo;est pas la version gratuite Open Source, mais la version payante fabriquée par EntrepriseDB et nommée &laquo;&nbsp;PostGreSQL PLUS.<br />
Nous n&rsquo;avons pas pu obtenir le prix d&rsquo;une telle version directement sur le site d&rsquo;EntrepriseDB, mais <a href="https://assets.digitalmarketplace.service.gov.uk/documents/93566/5258173757784064-pricing-document.pdf" title="PostGreSQL PLUS prix des licences" target="_blank">sur un autre document, provenant probablement du gouvernement britannique</a> ce prix apparait être 3 265 £ par CPU (socket), soit environ 4 700 €&#8230;<br />
En comparaison, SQL Server 2008 R2 version Web, suffisante pour ce benchmark, coute 4 246,41&#8230;</p>
<p><strong>LES RÉSULTATS</strong></strong></p>
<p>Comme on s&rsquo;y attendait, avec un tel paramétrage, PostGreSQL bât haut la main SQL Server ! <em>haut la main ?</em> <strong>pas si sûr&#8230;</strong></p>
<p><a href="http://blog.developpez.com/sqlpro/files/2015/11/PostGreSQL-vs-SQL-Server-Resultats.jpg"><img src="http://blog.developpez.com/sqlpro/files/2015/11/PostGreSQL-vs-SQL-Server-Resultats.jpg" alt="PostGreSQL vs SQL Server Resultats" width="731" height="645" class="alignnone size-full wp-image-632" /></a></p>
<p>Il faut vraiment y aller à la loupe pour voir la différence. En mesurant après impression avec une règle, j&rsquo;ai constaté un écart relatif de 3 à 5 % mesuré sur les entrées 40 et 140 de l&rsquo;histogramme&#8230;</p>
<p>Bref, il est très probable qu&rsquo;avec les réglages manquants pour Windows et SQL Server, Red Hat n&rsquo;aurait jamais publié un tel benchmark tant il aurait été défavorable à PostGreSQL fût-il PLUS !</p>
<p>Ce qui me navre c&rsquo;est que je croyais naïvement que Red Hat était une entreprise sérieuse !</p>
<p>***</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL
Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Communautés PostGreSQL&#8230; entre auto satisfaction et mauvaise foi ?</title>
		<link>https://blog.developpez.com/sqlpro/p12953/postgresql/communautes-postgresql-entre-auto-satisfaction-et-mauvaise-foi</link>
		<comments>https://blog.developpez.com/sqlpro/p12953/postgresql/communautes-postgresql-entre-auto-satisfaction-et-mauvaise-foi#comments</comments>
		<pubDate>Tue, 10 Nov 2015 11:02:29 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[PostGreSQL]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=622</guid>
		<description><![CDATA[J&#8217;ai récemment posté un commentaire à un article de ce blog : expert-postgresql.fr malheureusement ma réponse a rapidement été modérée sous la forme d&#8217;un poubellisation ! Elle n&#8217;avait cependant aucune remarque diffamatoire ni désobligeante, mais rétablissait certaines vérités. Comme ce n&#8217;est pas la première fois que mes propos critiques dérangent je pense que la communautés [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>J&rsquo;ai récemment posté un commentaire à un article de ce blog :<br />
<a href="http://expert-postgresql.fr/blog/news/choisir-postgresql/">expert-postgresql.fr</a><br />
malheureusement ma réponse a rapidement été modérée sous la forme d&rsquo;un poubellisation !<br />
Elle n&rsquo;avait cependant aucune remarque diffamatoire ni désobligeante, mais rétablissait certaines vérités.<br />
Comme ce n&rsquo;est pas la première fois que mes propos critiques dérangent je pense que la communautés PosGreSQL est beaucoup moins libre qu&rsquo;on ne le pense&#8230;.<br />
Voici donc mon commentaire accompagné d&rsquo;une reprise de cet article&#8230;<br />
<span id="more-622"></span></p>
<p><strong><br />
1 &#8211; cycle de production de PostGreSQL</strong></p>
<p>&nbsp;&raquo;<br />
<em>PostgreSQL stabilise et distribue une nouvelle version majeure de sa base de données chaque année.<br />
[..]<br />
Bien sûr, très peu de projets industriels peuvent se permettre de revoir leur architecture, leurs procédures et leur intégration SQL chaque année, et même dans le milieu très dynamique des services web cela n’arrive quasiment pas.Aussi les versions de PostgreSQL sont-elles maintenues pendant au moins cinq ans, les versions courantes de PostgreSQL sont donc au nombre de 5 à 7 selon les moments de l’année.</em><br />
&nbsp;&raquo;</p>
<p><strong>Mon commentaire sur ce point :</strong></p>
<p>Vous affirmez que le rythme des versions de PostGreSQL est très élevé&#8230; Une toutes les 6 mois à vous lire&#8230;<br />
Faisons la comparaison&#8230;</p>
<p>Rythmes des versions de SQL Server</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Vers. majeure &nbsp;Vers. mineure &nbsp;Date<br />
-------------- ------------- ------------<br />
2008 RTM &nbsp; &nbsp; &nbsp; 10.00.1600 &nbsp; &nbsp;07/08/2008 &nbsp; &nbsp; &nbsp; &nbsp;<br />
2008 SP1 &nbsp; &nbsp; &nbsp; 10.00.2531 &nbsp; &nbsp;07/04/2009<br />
2008 SP2 &nbsp; &nbsp; &nbsp; 10.00.4000 &nbsp; &nbsp;29/09/2010<br />
2008 SP3 &nbsp; &nbsp; &nbsp; 10.00.5538 &nbsp; &nbsp;04/07/2015<br />
2008 SP4 &nbsp; &nbsp; &nbsp; 10.00.6000 &nbsp; &nbsp;30/09/2014<br />
<br />
2008 R2 RTM &nbsp; &nbsp;10.50.1617 &nbsp; &nbsp;14/06/2010<br />
2008 R2 SP1 &nbsp; &nbsp;10.50.2500 &nbsp; &nbsp;09/10/2012<br />
2008 R2 SP2 &nbsp; &nbsp;10.50.4000 &nbsp; &nbsp;26/06/2012<br />
2008 R2 SP3 &nbsp; &nbsp;10.50.6000 &nbsp; &nbsp;26/09/2014<br />
<br />
2012 RTM &nbsp; &nbsp; &nbsp; 11.00.2100 &nbsp; &nbsp;06/03/2012<br />
2012 SP1 &nbsp; &nbsp; &nbsp; 11.00.3000 &nbsp; &nbsp;06/11/2013<br />
2012 SP2 &nbsp; &nbsp; &nbsp; 11.00.5343 &nbsp; &nbsp;14/07/2014<br />
<br />
2014 RTM &nbsp; &nbsp; &nbsp; 12.00.2000 &nbsp; &nbsp;01/01/2014<br />
2014 SP1 &nbsp; &nbsp; &nbsp; 12.00.4100 &nbsp; &nbsp;14/05/2015</div></div>
<p>Soit 14 versions en 6 ans, plus de 2 par an dont 4 versions majeures&#8230; Rien à envier donc à PostGreSQL !<br />
PostgreSQL n&rsquo;a eu dans cette même période que :<br />
2 versions majeures : la 8 en 2005 et la 9 en 2010<br />
En tout, de 2008 à 2015 il y a eu 7 versions mineures/majeures, soit 2 fois moins que SQL Server&#8230;</p>
<p>En sus les versions de SQL Server sont maintenues par le support Microsoft de manière publique avec un décalage de 2 versions majeures (soit 6 ans) et de manière payante (support étendue) près du double&#8230;</p>
<p>Fin du support étendu des différentes versions :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SQL Server 2000 : &nbsp; &nbsp;Le 09 Avril 2013 &nbsp; soit 13 ans<br />
SQL Server 2005 : &nbsp; &nbsp;Le 12 Avril 2016 &nbsp; soit 11 ans<br />
SQL Server 2008 : &nbsp; &nbsp;Le 09 Juillet 2019 soit 11 ans<br />
SQL Server 2008 R2 : Le 09 Juillet 2019 soit 9 ans<br />
SQL Server 2012 : &nbsp; &nbsp;Le 12 Juillet 2022 soit 10 ans</div></div>
<p><strong>2) Avancées technologiques</strong></p>
<p>&nbsp;&raquo;<br />
<em>Il existe ensuite de nombreux points techniques donnant un avantage très net à PostgreSQL, soit qu’il s’agisse d’innovations technologiques issues de la recherche, telles les « Serializable snapshot isolation » (ou SSI)&#8230;</em><br />
&nbsp;&raquo;</p>
<p><strong>Mon commentaires sur ce point :</strong></p>
<p>Vous parlez du niveau d&rsquo;isolation en invoquant le &laquo;&nbsp;Serializable snapshot isolation&nbsp;&raquo;<br />
Mais PostGreSQL est toujours incapable d&rsquo;utiliser le niveau d&rsquo;isolation normatif READ UNCOMMITTED qui permet d&rsquo;éviter tout verrou.<br />
SQL Server dispose depuis la version 2005 du niveau d’isolation SNAPSHOT en 2 modes différents :<br />
SNAPSHOT et READ COMMITTED SNAPSHOT<br />
En sus dans SQL Server il est possible de changer le niveau d’isolation à tout moment, y compris au sein même d&rsquo;une transaction, ce qui n&rsquo;est pas le cas dans PostGreSQL. Ainsi, le code suivant marche sous SQL Server et provoque une erreur dans PostGreSQL :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SET TRANSACTION ISOLATION LEVEL READ COMMITTED;<br />
<br />
BEGIN TRANSACTION;<br />
<br />
UPDATE TEST_STATS<br />
SET C2 = UPPER(C2) WHERE c1 = 181092;<br />
<br />
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;<br />
<br />
UPDATE TEST_STATS<br />
SET C2 = UPPER(C2) WHERE c1 = 181099;<br />
<br />
COMMIT;</div></div>
<p><strong>3) Facilité de codage</strong></p>
<p>&nbsp;&raquo;<br />
<em>Bénéficier de PostgreSQL pour résoudre cet ensemble de problème permet de ne pas avoir à les résoudre à nouveau dans votre application (quel jour serons-nous dans trois mois ? SELECT to_char(date &lsquo;today&rsquo; + 3 * interval &lsquo;1 month&rsquo;, &lsquo;Day&rsquo;); est sûrement plus facile à utiliser que n’importe quel autre code, les développeurs lisant cela seront sûrement d’accord).</em><br />
&nbsp;&raquo;</p>
<p><strong>Et mon commentaire</strong></p>
<p>Vous pensez sincèrement que la requête suivante (SQL Server) :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT DATENAME(weekday, DATEADD(month, 3, GETDATE()))</div></div>
<p>est nettement plus compliquée que celle-ci (PostGreSQL) ?</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT to_char(date 'today' + 3 * interval '1 month', 'Day');</div></div>
<p>&#8230;pour reprendre votre exemple !</p>
<p>En sus PostGreSQL donne un résultat en anglais, même si l&rsquo;installation a été faite avec une locale française, alors que SQL Server la donne dans la langue de Victor Hugo si l&rsquo;utilisateur a été déclaré comme Français (avec la cédille sans les tables système&#8230;) !</p>
<p><strong>4) Coût des licences</strong></p>
<p>&nbsp;&raquo;<br />
<em>Bien évidemment, tout cela sans s’acquitter de coûts de licence appliqués par serveur ou qui dépendent de la capacité et du nombre d’installations dont vous avez besoin pour déployer une architecture.</em><br />
&nbsp;&raquo;</p>
<p><strong>Et mon commentaire </strong>:</p>
<p>Vous invoquez le coût inexistant des licences PostGreSQL&#8230; Vous avez bien raison. mais ça c&rsquo;est la bidouille. MS SQL Server présente aussi une version gratuite, mais qui l&rsquo;utilise de manière industrielle ?<br />
Les entreprises prennent des assurances en achetant fort cher des contrats d&rsquo;assistance auprès de boîtes comme 2ndQuadrant, Smile ou Dalibo en France&#8230; Qui ne font jamais du 24h/24 ni du 7j/7 !<br />
Et ces mêmes entreprises ont souvent besoin de recourir à des prestataires PostGreSQL pour régler certains problèmes&#8230;<br />
Alors que lorsque vous payez une licence SQL Server, vous avez droit au support 24/24 7/7&#8230;</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL
Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Une étrange limitation de PostGreSQL</title>
		<link>https://blog.developpez.com/sqlpro/p12564/postgresql/une-etrange-limitation-de-postgresql</link>
		<comments>https://blog.developpez.com/sqlpro/p12564/postgresql/une-etrange-limitation-de-postgresql#comments</comments>
		<pubDate>Mon, 07 Apr 2014 10:34:23 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[PostGreSQL]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=443</guid>
		<description><![CDATA[Voici une bien étrangère limitation que nous offre l&#8217;optimiseur de PostgreSQL. Il n&#8217;est en effet pas capable de faire une jointure externe bilatérale lorsque le prédicat de jointure n&#8217;est pas &#171;&#160;sargeable&#160;&#187;&#8230; La jointure externe est assez peu utilisée, mais elle se conçoit bien, lorsque l&#8217;on veut pas exemple faire du rapprochement de données; En voici [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Voici une bien étrangère limitation que nous offre l&rsquo;optimiseur de PostgreSQL. Il n&rsquo;est en effet pas capable de faire une jointure externe bilatérale lorsque le prédicat de jointure n&rsquo;est pas &laquo;&nbsp;sargeable&nbsp;&raquo;&#8230;<br />
<span id="more-443"></span><br />
La jointure externe est assez peu utilisée, mais elle se conçoit bien, lorsque l&rsquo;on veut pas exemple faire du rapprochement de données; En voici un exemple :<br />
Soit deux tables contenant des clients pour l&rsquo;un et des prospects pour l&rsquo;autre. On à collecté comme information le n° de SIREN et le nom d&rsquo;enseigne.<br />
Mais le nom peut être mal orthographié comme le SIREN peut être incorrect. Le but étant de joindre ces données avec le maximum de &laquo;&nbsp;chances&nbsp;&raquo;&#8230;</p>
<p><strong>Voici le modèle de la base :</strong></p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_CLIENT_CLI<br />
<span style="color: #66cc66;">&#40;</span>CLI_ID &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">,</span><br />
&nbsp;CLI_SIREN &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">CHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">9</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">UNIQUE</span><span style="color: #66cc66;">,</span><br />
&nbsp;CLI_ENSEIGNE <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">16</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_PROSPECT_PSP<br />
<span style="color: #66cc66;">&#40;</span>PSP_ID &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">,</span><br />
&nbsp;PSP_SIREN &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">CHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">9</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">UNIQUE</span><span style="color: #66cc66;">,</span><br />
&nbsp;PSP_ENSEIGNE <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">16</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Et quelques données de test :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_CLIENT_CLI <span style="color: #993333; font-weight: bold;">VALUES</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'123456789'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'IBM'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'111111111'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Microsoft'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'999555111'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'SAP'</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_PROSPECT_PSP <span style="color: #993333; font-weight: bold;">VALUES</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">101</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'123456789'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'IBM'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">102</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'555555555'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Microsoft'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">103</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'777777777'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Amazon'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">104</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'444444444'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Google'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Nous voyons que le code SIREN de Microsoft ne se recoupe pas sur les deux tables&#8230; Cepandant nous voulons toutes les données des deux tables avec jointure sur le code SIREN ou à défaut sur le nom.<br />
La requête suivante correspond à cette demande :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_CLIENT_CLI <span style="color: #993333; font-weight: bold;">AS</span> C<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">FULL</span> <span style="color: #993333; font-weight: bold;">OUTER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> T_PROSPECT_PSP <span style="color: #993333; font-weight: bold;">AS</span> P<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> C<span style="color: #66cc66;">.</span>CLI_SIREN <span style="color: #66cc66;">=</span> P<span style="color: #66cc66;">.</span>PSP_SIREN<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">OR</span> C<span style="color: #66cc66;">.</span>CLI_ENSEIGNE <span style="color: #66cc66;">=</span> P<span style="color: #66cc66;">.</span>PSP_ENSEIGNE</div></div>
<p><strong>Voici ce qu&rsquo;elle donne sous MS SQL Server :</strong></p>
<pre>
CLI_ID      CLI_SIREN CLI_ENSEIGNE     PSP_ID      PSP_SIREN PSP_ENSEIGNE
----------- --------- ---------------- ----------- --------- ----------------
1           123456789 IBM              101         123456789 IBM
2           111111111 Microsoft        102         555555555 Microsoft
3           999555111 SAP              NULL        NULL      NULL
NULL        NULL      NULL             103         777777777 Amazon
NULL        NULL      NULL             104         444444444 Google</pre>
<p><strong>Hélas, cette requête ne passe pas sous aucune version de PostGreSQL.</strong> le message est le suivant :</p>
<pre>ERREUR:  FULL JOIN est supporté seulement avec les conditions de jointures MERGE et de
jointures HASH JOIN
********** Erreur **********
État SQL :0A000</pre>
<p><strong><br />
L&rsquo;explication est la suivante :</strong><br />
PostGreSQL veut impérativement que la jointure soir <a href="http://blog.developpez.com/sqlpro/p10994/langage-sql-norme/optimisation_de_requetes_sql_sargable_c">&laquo;&nbsp;sargeable&nbsp;&raquo;</a>, c&rsquo;est à dire utiliser une technique de jointure avec algorithme MERGE (fusion d&rsquo;un tri resultant d&rsquo;index) ou algorithme HASH (donc index avec clef de hachage)&#8230; Or, avec un &laquo;&nbsp;ou&nbsp;&raquo; (OR) dans la clause On de la jointure il n&rsquo;y a pas de &laquo;&nbsp;sargeabilité&nbsp;&raquo; possible !<br />
Si vous ne prenez pas en compte la dernière ligne (OR OR C.CLI_ENSEIGNE = P.PSP_ENSEIGNE) alors la requête s&rsquo;exécute. Si vous mettez AND à la place de OR, ça passe. mais tout ceci ne donne pas le même résultat<br />
En fait, c&rsquo;est une limitation assez curieuse de l&rsquo;optimiseur de PostGreSQL qui interdit le FULL OUTER JOIN dans certains cas&#8230;</p>
<p><strong>Évidemment, cela constitue à l&rsquo;évidence un bug&#8230;</strong></p>
<p>PS : version PG testée 9.1.2 et 9.3.4</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hachage n&#8217;est pas cryptage ! De la sécurité des données chiffrées dans les SGBDR</title>
		<link>https://blog.developpez.com/sqlpro/p12496/langage-sql-norme/hachage-nest-pas-cryptage-de-la-securite-des-donnees-chiffrees-dans-les-sgbdr</link>
		<comments>https://blog.developpez.com/sqlpro/p12496/langage-sql-norme/hachage-nest-pas-cryptage-de-la-securite-des-donnees-chiffrees-dans-les-sgbdr#comments</comments>
		<pubDate>Wed, 19 Feb 2014 10:24:54 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[PostGreSQL]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[SQL Server 2012]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=403</guid>
		<description><![CDATA[De plus en plus de jeunes développeurs confondent la technique du hachage et le chiffrement des données. Voici un point sur le sujet&#8230; Qu&#8217;est-ce que le hachage ? Le hachage consiste à calculer une donnée de petite dimension à partir d&#8217;une donnée de grande dimension afin de s&#8217;en servir comme repère dans différents processus algorithmique. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>De plus en plus de jeunes développeurs confondent la technique du hachage et le chiffrement des données. Voici un point sur le sujet&#8230;<br />
<span id="more-403"></span><br />
<strong>Qu&rsquo;est-ce que le hachage ?</strong></p>
<p>Le hachage consiste à calculer une donnée de petite dimension à partir d&rsquo;une donnée de grande dimension afin de s&rsquo;en servir comme repère dans différents processus algorithmique. La valeur obtenu par hachage est un nombre ou une chaine binaire et dans ce dernier cas généralement représentée en  hexadécimal.<br />
Les algorithmes de hachage les plus connus sont : MD2, MD4, MD5 (16 octets / 128 bits en sortie), SHA (ou SHA-0), SHA-1 (20 octets / 160 bits en sortie), SHA-2 (224 à 512 bits), Whirlpoll (64 octets / 512 bits).<br />
On trouvera la description des algorithmes de calcul de ces fonctions de hachage aux URL suivantes :</p>
<li>MD2 : <a href="http://tools.ietf.org/html/rfc1319">http://tools.ietf.org/html/rfc1319</a></li>
<li>MD4 : <a href="http://tools.ietf.org/search/rfc1320">http://tools.ietf.org/search/rfc1320</a></li>
<li>MD5 : <a href="http://fr.wikipedia.org/wiki/MD5">http://fr.wikipedia.org/wiki/MD5</a></li>
<li>SHA : <a href="http://fr.wikipedia.org/wiki/SHA-0">http://fr.wikipedia.org/wiki/SHA-0</a></li>
<li>SHA1 : <a href="http://fr.wikipedia.org/wiki/SHA-1">http://fr.wikipedia.org/wiki/SHA-1</a></li>
<li>SHA2 : <a href="http://fr.wikipedia.org/wiki/SHA-2">http://fr.wikipedia.org/wiki/SHA-2</a></li>
<li>Whirlpool : <a href="http://www.seas.gwu.edu/~poorvi/Classes/CS381_2007/Whirlpool.pdf">http://www.seas.gwu.edu/~poorvi/Classes/CS381_2007/Whirlpool.pdf</a></li>
<p>La valeur en sortie est de taille fixe quel que soit la longueur de l&rsquo;information d&rsquo;entrée. Du point de vue des mathématiques il ne peut s&rsquo;agir d&rsquo;un processus de cryptage puisque le cryptage produit des données dont le volume est au moins aussi important que le volume des données en entrée, voir beaucoup plus lorsque les données d&rsquo;entrée sont de petits volumes.<br />
Certains logiciels utilisent leurs propres algorithmes pour générer des valeurs de hachage. Par exemple SQL Server implémente les fonctions CHECKSUM, BINARY_CHECKSUM et CHECKSUM_AGG pour calculer un entier 32 bits à partir d&rsquo;une valeur, d&rsquo;une expression ou d&rsquo;une liste d&rsquo;expression ou de valeurs combinées, soit pour une ligne, soit pour une colonne.<br />
On trouvera un exemple de l&rsquo;algorithme utilisé à l&rsquo;URL suivante : <a href="http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=70832">http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=70832</a></p>
<p>Le hachage entraîne fatalement des <strong>collisions</strong>, c&rsquo;est à dire que différentes informations peuvent produire une même valeur de hachage. </p>
<p>Voici un exemple de collision de hachage avec la fonction MD5&#8230;<br />
Pour PostGreSQL :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> md5<span style="color: #66cc66;">&#40;</span>E<span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\\</span>xd131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70'</span>::bytea<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">UNION</span> <span style="color: #993333; font-weight: bold;">ALL</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> md5<span style="color: #66cc66;">&#40;</span>E<span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\\</span>xd131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70'</span>::bytea<span style="color: #66cc66;">&#41;</span></div></div>
<p>Pour MS SQL Server :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> HASHBYTES<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'md5'</span><span style="color: #66cc66;">,</span> 0xd131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">UNION</span> <span style="color: #993333; font-weight: bold;">ALL</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> HASHBYTES<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'md5'</span><span style="color: #66cc66;">,</span> 0xd131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70<span style="color: #66cc66;">&#41;</span></div></div>
<p>le 20e octet est différent dans les deux chaines hexadécimales passées en argument. </p>
<p><strong>Le hachage n&rsquo;est pas non plus réversible</strong>. Il n&rsquo;existe pas de fonction permettant à coup sûr de retrouver l&rsquo;information initiale partant de la valeur hachée. La possibilité de collisions s&rsquo;oppose à la bijection impérativement nécessaire à déterminer une fonction réciproque.</p>
<p><em><strong>Le but du hachage n&rsquo;est donc pas de crypter des données mais de donner une &laquo;&nbsp;empreinte&nbsp;&raquo; à une donnée.</strong></em></p>
<p><strong>Qu&rsquo;est-ce que le cryptage ?</strong></p>
<p>Le cryptage est l&rsquo;ensemble des processus permettant à une donnée d&rsquo;être transformée en une autre incompréhensible pour qui ne connais pas la donnée originale, puis, partant de la transformation, d&rsquo;être retransformée en donnée d&rsquo;origine.<br />
Le cryptage nécessite donc l&rsquo;existence de deux traitements conjoints et bijectifs : l&rsquo;un de cryptage, l&rsquo;autre de décryptage. On parle alors de correspondance univoque entre l&rsquo;ensemble des données en clair et l&rsquo;ensemble des données cryptées.<br />
Le chiffrement est un sous ensemble du cryptage qui consiste à utiliser des fonctions mathématiques afin de crypter et de décrypter. Néanmoins il en existe d&rsquo;autres comme par exemple la stéganographie&#8230;</p>
<p>Les techniques modernes de cryptage en matière informatique sont basées sur le chiffrement à l&rsquo;aide d&rsquo;algorithmes à clefs :
<li>la même clef servant à crypter et décrypter, on parle alors de chiffrement symétrique (il faut garder sa clef secrète)</li>
<li>une clef sert à chiffrer une autre à déchiffrer, on parle alors de chiffrement asymétrique (on peut rendre publique l&rsquo;une des deux clefs)</li>
<p>L&rsquo;algorithme est connu et la clef de décryptage est confidentielle. La sécurité est basée sur la complexité d&rsquo;un possible déchiffrement par une attaque de type &laquo;&nbsp;force brute&nbsp;&raquo; (essais de décryptage par toutes une série de clef probables).<br />
La complexité du chiffrement est liée à l&rsquo;algorithme et à la longueur de la clef. Les algorithmes à clef asymétriques étant plus fiables car plus complexes, mais aussi plus couteux en temps de traitement.</p>
<p>Principaux algorithmes (et longueur de clef) :
<li>symétrique : DES (56 bits), TRIPLE_DES (128 ou 192 bits), RC2, RC4, RC4_128 (128 bits), AES (128 à 256 bits)</li>
<li>asymétrique : RSA_512 (512 bits), RSA_1024 (1024 bits), RSA_2048 (2048 bits)</li>
<p><strong>NOTA : </strong>les algorithmes de type RC sont aujourd&rsquo;hui considérés comme peu fiables et ne doivent plus être utilisés en production, car ils sont faciles à casser. RC2 fût longtemps utilisé par Lotus Notes. RC4 est encore utilisé pour protéger les informations d&rsquo;un réseau wifi avec clef WEP ou WPA.</p>
<p><strong>Emploi du hachage</strong></p>
<p>Les tous premiers emplois du hachage ont été une pseudo cryptographie à sens unique destinée à vérifier la justesse d&rsquo;une information connue. Le principe est assez simple : on calcule une valeur de hachage sur des informations confidentielle et on stocke cette valeur plutôt que les informations.<br />
Si quelqu&rsquo;un vient avec les données originales que l&rsquo;on hache avec le même algorithme, alors les deux valeurs (le hachage calculé et le hachage stocké) sont identiques; On suppose alors que les données sont les mêmes, ce qui, du fait des collisions potentielles est paradoxalement faux.<br />
Mais avant l&rsquo;an 2000, exploiter un véritable mécanisme de cryptage était considéré comme un crime et passible d&rsquo;une peine de prison. C&rsquo;est pourquoi le hachage prit de l&rsquo;ampleur avant que deux choses ne se produisent :</p>
<li>la découverte de techniques d&rsquo;attaques permettant de &laquo;&nbsp;casser&nbsp;&raquo; ou de semer le trouble concernant le hachage (par exemple la génération de collisions)</li>
<li>la liberté légale de crypter des données, introduite en droit français peu après la directive européenne 2000/31/CE du 8 juin 2000 sur le commerce électronique, suite à l&rsquo;affaire Zimmermann et son outil PGP.</li>
<p>Dès lors les algorithmes de cryptage ont remplacé la plupart des processus de hachage sauf dans les systèmes encore en vigueur dont ils constituent une part essentiel du fonctionnement.</p>
<p>Néanmoins le hachage peut rendre d&rsquo;inestimables services. Il est notablement utilisé dans les systèmes informatiques distribués ou dans la gestion du parallélisme d&rsquo;accès à des ressources d&rsquo;un système, notamment pour situer une information.<br />
Ainsi dans un système de bases de données distribuées on calculera une clef de hachage sur les éléments d&rsquo;authentification de l&rsquo;utilisateur et sur cette clef on calculera un modulo en fonction du nombre de nœuds dans le maillage du système distribué.<br />
Par exemple pour un site web comme fnac.com il existe de nombreux serveurs de bases de données, chacun ayant en table tous les produits à vendre, mais un client n&rsquo;existant que sur un seul des serveurs.<br />
Tant que l&rsquo;utilisateur navigue anonymement on route ses requêtes sur le serveur le moins chargé à l&rsquo;instant t;<br />
Dès qu&rsquo;il est authentifié ou calcule une clef de hachage sur son mail + mot de passe, puis on calcule un modulo en fonction du nombre de serveurs et on route dorénavant toutes ses requêtes sur le serveur dont l&rsquo;indice correspond au modulo, puisque c&rsquo;est seulement sur ce serveur que le client est connu.</p>
<p>Le même algorithme est appliqué dans certains moteurs de bases de données relationnelles pour gérer des traitements en parallèle ou diminuer le temps de traitement. Par exemple pour résoudre une jointure (hash join) ou un groupage (hash group)</p>
<p><strong>Emploi de la cryptographie</strong></p>
<p>La cryptographie sert à rendre confidentielles certaines informations qui ne pourrons être décryptées que par ceux qui connaisse la façon de crypter et donc de décrypter.<br />
Elle permet aussi l&rsquo;authentification, par le biais de certificat qui sont des documents liant une identité à une clef par le biais d&rsquo;une signature (tiers de confiance) et permettent d&rsquo;avoir la certitude sur l&rsquo;origine d&rsquo;une entité.</p>
<p><strong>Signature de documents et authentification</strong></p>
<p>La signature numérique (ou signature électronique) permet de garantir l&rsquo;intégrité d&rsquo;un document électronique et par là même d&rsquo;en authentifier l&rsquo;auteur.<br />
Elle fonctionne à l&rsquo;aide d&rsquo;une clef asymétrique ou d&rsquo;un certificat, et une fonction de hachage :</p>
<li>l&rsquo;auteur calcule une valeurs de hachage par le biais de la fonction de hachage considérée puis crypte cette information de hachage qui constitue la signature du document électronique. Cette signature est incorporée au document.</li>
<li>lors de la réception le destinataire calcule une valeur de hachage sur le document sans tenir compte de la signature, puis décrypte la signature à l&rsquo;aide de la clef publique. Si les deux valeurs (la signature incorporée et la signature nouvellement calculées) sont identiques, alors le document à toutes les chances d&rsquo;être authentique.</li>
<p>Il est par exemple possible de &laquo;&nbsp;signer&nbsp;&raquo; un programme informatique (exécutable ou DLL).</p>
<p><strong>Chiffrement de données</strong></p>
<p>Un exemple typique de chiffrement est la communication d&rsquo;information confidentielle par email. En effet, les données d&rsquo;un email peuvent être interceptées sur le réseau Internet, ce à quoi s&rsquo;emploient certaines organisations telles que la NSA.</p>
<p>La confidentialité des données stockées notamment dans les bases de données nécessite parfois du chiffrement. C&rsquo;est le cas des données des cartes bancaires ou des données personnelles notamment dans certains domaines sensibles comme la politique, le syndicalisme, la religion ou la santé.<br />
Dans ce dernier secteur, la Loi française impose des standards de chiffrement très élevées lorsque ces données sont accessibles sur Internet (<a href="http://www.legifrance.gouv.fr/affichCode.do;jsessionid=7A144763E4004F90B4EA25BB405A5652.tpdjo16v_3?idSectionTA=LEGISCTA000006196138&amp;cidTexte=LEGITEXT000006072665&amp;dateTexte=20101105">Décret n° 2006-6 relatif à l’hébergement de données de santé à caractère personnel</a>).</p>
<p>Certains SGBDR incorporent des services de génération et de gestion de clefs, de cryptage/décryptage et d&rsquo;authentification par certificat. C&rsquo;est par exemple le cas d&rsquo;Oracle ou de MS SQL Server qui sont leurs propres autorités de certifications et stockent les clefs dans les bases.<br />
D&rsquo;autres SGBDR propose des fonctions de cryptage/décryptage sans la gestion des clefs, ce qui pose le problème de la conservation des clefs&#8230; C&rsquo;est le cas de MySQL et de PostGreSQL qui nécessite un tiers externe de certification et obligent à véhiculer les clefs d&rsquo;une manière ou d&rsquo;une autre, souvent par le biais de fichiers sur le serveur&#8230;<br />
Le chiffrement des données dans les bases de données posent d&rsquo;ailleurs d&rsquo;autres problèmes :</p>
<li>le cassage aisé du code, si les données ne sont pas &laquo;&nbsp;salées&nbsp;&raquo;</li>
<li>la rapidité d&rsquo;accès à l&rsquo;information</li>
<li>la volumétrie de stockage des données cryptées</li>
<li>la difficulté de recherches performantes</li>
<p><strong>Le salage</strong> est abordé au paragraphe suivant et constitue une faille de sécurité importante en son absence.</p>
<p><strong>La rapidité d&rsquo;accès à l&rsquo;information</strong> est notablement diminuée par le fait de crypter et décrypter en permanence</p>
<p><strong>La volumétrie des données cryptées</strong> est plus importante en général que lorsque les données ne sont pas cryptées</p>
<p>Enfin, il est très <strong>difficile de rendre les recherches performantes</strong> dès lors que les données sont cryptées et salées par le simple fait qu&rsquo;il est impossible d&rsquo;utiliser un index et que par conséquent, il faut lire séquentiellement toutes les données et les décrypter avant d&rsquo;effectuer la comparaison.</p>
<p>Il faut aussi faire très attention dans les bases de données au <strong>recoupement des données qui permettrait</strong>, même avec un chiffrage, <strong>de trouver certaines données</strong>. En effet, toutes les informations ne sont pas chiffrées et heureusement sinon les performances seraient catastrophiques et la base inexploitable&#8230; Mais imaginons une base de données dans laquelle nous savons qu&rsquo;un des patients est un général argentin&#8230; Si ces informations figurent en clair et que, comme il est probable, il y a peu d&rsquo;argentins et peu de généraux dans les données, alors il est facile de trouver ou figure cet individu dans la base et par là même de retrouver de fil en aiguille certaines informations comme son prochain rendez-vous de chimio !</p>
<p>Pour pallier à ce dernier inconvénient, une autre solution de chiffrement dans les bases données est basée sur le cryptage du stockage et non plus des données (<a href="http://en.wikipedia.org/wiki/Transparent_Data_Encryption">TDE ou Transparent Data Encryption</a> que l&rsquo;on trouve notamment chez Oracle et MS SQL Server). Les données sont alors manipulées en clair en mémoire et de façon optimisé (utilisation des index) alors qu&rsquo;elles figurent de manière chiffrées dans les fichiers (données des tables en index et journal de transactions), le cryptage/décryptage étant assurée à la volée lors des entrées / sorties au niveau du disque.</p>
<p>Enfin, certains SGBDR (Oracle, MS SQL Server) permmettent d&rsquo;utiliser des boitiers externes de chiffrement inviolables (<a href="http://en.wikipedia.org/wiki/Hardware_Security_Module">HSM ou Hardware Security Module</a>) que l&rsquo;on place sur le réseau et qui sont utilisés par le serveur SQL. En cas de tentative d&rsquo;accès au boitier, les clefs sont automatiquement détruites.<br />
Un exemple d&rsquo;utilisation d&rsquo;un HMS en pratique est celui qui protège les données personnelles confidentielles de santé des agents territoriaux de France (environ 2 millions d&rsquo;individus) par le biais d&rsquo;un HSM et d&rsquo;un serveur de bases de données Microsoft SQL Server, </p>
<p><strong>Salage</strong></p>
<p>Le salage, est une méthode permettant de renforcer la sécurité des informations cryptées en y ajoutant une donnée supplémentaire afin d&rsquo;empêcher que deux informations identiques conduisent aux mêmes données chiffrées. Le but du salage est de lutter contre une attaque par analyse fréquentielle.<br />
Le cas est classique dans les bases de données. En effet, lorsque le système concentre beaucoup de données, il est fréquent de trouver des informations identiques (redondances) comme c&rsquo;est par exemple le cas des noms de famille (<a href="http://www.genealogie.com/nom-de-famille-1/">MARTIN, DURAND, LEFEBVRE&#8230;</a>)<br />
Dès lors une analyse basées sur la fréquence d&rsquo;apparition des redondances permettrait assez rapidement de casser le code.<br />
Pour pallier à cet inconvénient, certains SGBDR comme Oracle ou SQL Server intègrent automatiquement un salage pour que deux données identiques donnent deux codes chiffrés différents. </p>
<p><strong>NOTA :</strong> les serveurs de bases de données comme MySQL ou PostGreSQL ne permettent pas d&rsquo;utiliser un salage automatique des données lors de l&rsquo;utilisation des fonctions de cryptage. </p>
<p><strong>Bases de données et chiffrement</strong></p>
<p>À la lecture des paragraphes précédent, il apparait clair que les solutions de chiffrement actuelles dans les bases de données &laquo;&nbsp;libres&nbsp;&raquo; comme PostGreSQL ou MySQL sont incapable de procurer une sécurité suffisante :</p>
<li>les clefs sont généralement stockées en fichiers sur le serveur et non dans la base et sont par conséquent lisible par tout utilisateur ayant accès au serveur;</li>
<li>le chiffrement n&rsquo;est pas &laquo;&nbsp;salé&nbsp;&raquo; et par conséquent une attaque du code par analyse fréquentielle est possible;</li>
<li>ces serveurs ne permettent pas d&rsquo;utiliser des boitiers de type HSM, qui s&rsquo;avèrent particulièrement intéressant pour les données bancaires (code des cartes de paiement) ou de santé (données personnelles);</li>
<li>un service de chiffrement du stockage de type TDE n&rsquo;est pas intégré dans de tels serveur ce qui fait par exemple qu&rsquo;un fichier de données ou une sauvegarde volée donne tout le temps au voleur de déchiffrer par recoupement.</li>
<li>comme la clef ne figure pas dans la base, elle doit être transmise en clair dans les requêtes. Elle figure donc dans les routines (fonctions PG/PLSQL de PostGreSQL par exemple) comme dans les requêtes des appliciations clientes.</li>
<li>le code généré est généralement assez court et permet plus aisément une attaque</li>
<p><strong>Exemple de chiffrement de données dans les bases de données</strong> </p>
<p>Avec PostGreSQL, extension pgcrypto avec algorithme AES :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> EXTENSION pgcrypto;<br />
<br />
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_NOM<br />
<span style="color: #66cc66;">&#40;</span>NOM &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;NOM_CRYPTE &nbsp;bytea<span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_NOM <span style="color: #66cc66;">&#40;</span>NOM<span style="color: #66cc66;">&#41;</span> <br />
<span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'MARTIN'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'DUPONT'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'MARTIN'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'DURAND'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Cryptage :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">UPDATE</span> T_NOM<br />
<span style="color: #993333; font-weight: bold;">SET</span> &nbsp; &nbsp;NOM_CRYPTE <span style="color: #66cc66;">=</span> encrypt<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span>NOM <span style="color: #993333; font-weight: bold;">AS</span> bytea<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Le petit chat est mort.'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'aes'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> T_NOM;<br />
<br />
NOM &nbsp; &nbsp; &nbsp; &nbsp;NOM_CRYPTE<br />
<span style="color: #808080; font-style: italic;">---------- ---------------------------------------------------------------</span><br />
MARTIN &nbsp; &nbsp; \<span style="color: #cc66cc;">212</span>\<span style="color: #cc66cc;">306</span>\<span style="color: #cc66cc;">335</span>\<span style="color: #cc66cc;">270</span>\<span style="color: #cc66cc;">27615</span>\<span style="color: #cc66cc;">334</span>\33021o\<span style="color: #cc66cc;">212</span>\<span style="color: #cc66cc;">271</span>\252a\<span style="color: #cc66cc;">277</span>\<span style="color: #cc66cc;">302</span><br />
DUPONT &nbsp; &nbsp; \<span style="color: #cc66cc;">343</span>\<span style="color: #cc66cc;">331</span>\<span style="color: #cc66cc;">307</span><span style="color: #66cc66;">-</span>\<span style="color: #cc66cc;">202</span>\<span style="color: #cc66cc;">203</span>\<span style="color: #cc66cc;">301</span><span style="color: #66cc66;">|</span><span style="color: #66cc66;">&#40;</span>\247M32<span style="color: #66cc66;">+</span>\<span style="color: #cc66cc;">177</span>\<span style="color: #cc66cc;">301</span>\<span style="color: #cc66cc;">265</span><br />
MARTIN &nbsp; &nbsp; \<span style="color: #cc66cc;">212</span>\<span style="color: #cc66cc;">306</span>\<span style="color: #cc66cc;">335</span>\<span style="color: #cc66cc;">270</span>\<span style="color: #cc66cc;">27615</span>\<span style="color: #cc66cc;">334</span>\33021o\<span style="color: #cc66cc;">212</span>\<span style="color: #cc66cc;">271</span>\252a\<span style="color: #cc66cc;">277</span>\<span style="color: #cc66cc;">302</span><br />
DURAND &nbsp; &nbsp; <span style="color: #cc66cc;">3513</span>\<span style="color: #cc66cc;">252</span>\<span style="color: #cc66cc;">23627</span>^M21<span style="color: #66cc66;">,</span><span style="color: #cc66cc;">3002</span><span style="color: #66cc66;">&#93;</span>w\<span style="color: #cc66cc;">326</span>\<span style="color: #cc66cc;">227</span></div></div>
<p>Décryptage :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> NOM<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span>decrypt<span style="color: #66cc66;">&#40;</span>NOM_CRYPTE<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Le petit chat est mort.'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'aes'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> NOM_CLAIR<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_NOM;<br />
<br />
NOM &nbsp; &nbsp; &nbsp; &nbsp;NOM_CLAIR<br />
<span style="color: #808080; font-style: italic;">---------- ---------------------------------------------------------------</span><br />
MARTIN &nbsp; &nbsp; MARTIN<br />
DUPONT &nbsp; &nbsp; DUPONT<br />
MARTIN &nbsp; &nbsp; MARTIN<br />
DURAND &nbsp; &nbsp; DURAND</div></div>
<p>Comme on le voit, le mot de passe de la clef de cryptage est passée en clair lors de l&rsquo;utilisation des fonctions de cryptage et décryptage.<br />
Le chiffrement de MARTIN a donné deux fois le même code, la longueur du code est d&rsquo;une quinzaine d&rsquo;octets&#8230;</p>
<p>Avec SQL Server (chiffrement intégré dans toutes les versions) algorithme AES :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- création d'une clef de cryptage de niveau base de données </span><br />
<span style="color: #808080; font-style: italic;">-- permettant la génération de clefs de cryptage interne</span><br />
<span style="color: #993333; font-weight: bold;">CREATE</span> MASTER <span style="color: #993333; font-weight: bold;">KEY</span> ENCRYPTION <span style="color: #993333; font-weight: bold;">BY</span> PASSWORD <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Le petit chat est mort.'</span>;<br />
<span style="color: #993333; font-weight: bold;">GO</span><br />
<br />
<span style="color: #808080; font-style: italic;">-- création d'une clef de cryptage avec algorithme ASE clef à 256 bits</span><br />
<span style="color: #993333; font-weight: bold;">CREATE</span> SYMMETRIC <span style="color: #993333; font-weight: bold;">KEY</span> MA_CLEF<br />
<span style="color: #993333; font-weight: bold;">WITH</span> ALGORITHM <span style="color: #66cc66;">=</span> AES_256 <br />
&nbsp; &nbsp; ENCRYPTION <span style="color: #993333; font-weight: bold;">BY</span> PASSWORD <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'P@ssw0rd !'</span>;<br />
<span style="color: #993333; font-weight: bold;">GO</span> &nbsp; &nbsp;<br />
<br />
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_NOM<br />
<span style="color: #66cc66;">&#40;</span>NOM &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;NOM_CRYPTE &nbsp;VARBINARY<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">256</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_NOM <span style="color: #66cc66;">&#40;</span>NOM<span style="color: #66cc66;">&#41;</span> <br />
<span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'MARTIN'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'DUPONT'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'MARTIN'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'DURAND'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Cryptage :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- ouverture de la clef pour la session</span><br />
<span style="color: #808080; font-style: italic;">-- peut être fait côté serveur dans un déclencheur FOR LOGON et dans ce cas</span><br />
<span style="color: #808080; font-style: italic;">-- le mot de passe ne sera pas codé dans les applis ni transmis dans le réseau</span><br />
<span style="color: #993333; font-weight: bold;">OPEN</span> SYMMETRIC <span style="color: #993333; font-weight: bold;">KEY</span> MA_CLEF<br />
DECRYPTION <span style="color: #993333; font-weight: bold;">BY</span> PASSWORD <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'P@ssw0rd !'</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<br />
<span style="color: #808080; font-style: italic;">-- la fonction KEY_GUID permet de retrouver la clef primaire informatique </span><br />
<span style="color: #808080; font-style: italic;">-- (de type GUID) de la clef de cryptage pour pouvoir l'utiliser</span><br />
<span style="color: #993333; font-weight: bold;">UPDATE</span> T_NOM<br />
<span style="color: #993333; font-weight: bold;">SET</span> &nbsp; &nbsp;NOM_CRYPTE <span style="color: #66cc66;">=</span> ENCRYPTBYKEY<span style="color: #66cc66;">&#40;</span>KEY_GUID<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'MA_CLEF'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> NOM<span style="color: #66cc66;">&#41;</span>;</div></div>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> T_NOM;<br />
<br />
NOM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NOM_CRYPTE<br />
<span style="color: #808080; font-style: italic;">------------ ------------------------------------------------------------------------------------------------------------</span><br />
MARTIN &nbsp; &nbsp; &nbsp; 0x00AC31E101131E408D190F626A5F757801000000519DC1A3C61A63A66EA857F7E9BBE649E09989B0E718CDFE861BE27CFAEA68B8<br />
DUPONT &nbsp; &nbsp; &nbsp; 0x00AC31E101131E408D190F626A5F7578010000000BECCA5469AFF7771675C1D9FB7103A1807FE2430FBF1922C56A990CBC3BA6FF<br />
MARTIN &nbsp; &nbsp; &nbsp; 0x00AC31E101131E408D190F626A5F757801000000B496C2D5DC5D92D4303B05B86457042767CC4382F852B29BFA1B0A66BB566388<br />
DURAND &nbsp; &nbsp; &nbsp; 0x00AC31E101131E408D190F626A5F757801000000121A2325A435CD72E830B255089C25CA24CF0A7FD2C693F66819FE5493FDD0F0</div></div>
<p>Décryptage :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- la clef étant ouverte, on a pas besoin du mot de passe pour décryptage</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> NOM<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span>DECRYPTBYKEY<span style="color: #66cc66;">&#40;</span>NOM_CRYPTE<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> NOM_CLAIR<br />
<span style="color: #993333; font-weight: bold;">FROM</span> T_NOM;<br />
<br />
NOM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NOM_CLAIR<br />
<span style="color: #808080; font-style: italic;">------------ --------------</span><br />
MARTIN &nbsp; &nbsp; &nbsp; MARTIN<br />
DUPONT &nbsp; &nbsp; &nbsp; DUPONT<br />
MARTIN &nbsp; &nbsp; &nbsp; MARTIN<br />
DURAND &nbsp; &nbsp; &nbsp; DURAND &nbsp; &nbsp;<br />
<br />
CLOSE SYMMETRIC <span style="color: #993333; font-weight: bold;">KEY</span> MA_CLEF;</div></div>
<p>Le mot de passe de la clef n&rsquo;est pas passé pour crypter et décrypter. L&rsquo;ouverture de la clef peut être automatisée côté serveur par un déclencheur FOR LOGON.<br />
Le chiffrement de MARTIN a donné deux codes différents et la longueur du code est de 52 octets&#8230;<br />
On peut aussi utiliser un certificat à la place du mot de passe.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Calculs SQL avec des dates : age exact révolu et anniversaires&#8230;</title>
		<link>https://blog.developpez.com/sqlpro/p12468/langage-sql-norme/calculs-sql-avec-des-dates-age-exact-revolu-et-anniversaires</link>
		<comments>https://blog.developpez.com/sqlpro/p12468/langage-sql-norme/calculs-sql-avec-des-dates-age-exact-revolu-et-anniversaires#comments</comments>
		<pubDate>Wed, 05 Feb 2014 23:27:07 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[PostGreSQL]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=392</guid>
		<description><![CDATA[Parmi les requêtes les plus difficile à établir en SQL se trouve généralement les calculs temporels. Voici deux problématiques résolues, celle du calcul de l&#8217;âge révolu et celle de la recherche de personnes sont l&#8217;anniversaire est à souhaiter&#8230; pas si simple ! Tout d&#8217;abord, voici les données de nos exemples&#8230; D&#8217;abord la table : CREATE [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Parmi les requêtes les plus difficile à établir en SQL se trouve généralement les calculs temporels. Voici deux problématiques résolues, celle du calcul de l&rsquo;âge révolu et celle de la recherche de personnes sont l&rsquo;anniversaire est à souhaiter&#8230; pas si simple !<br />
<span id="more-392"></span></p>
<p><strong>Tout d&rsquo;abord, voici les données de nos exemples&#8230; </strong></p>
<p>D&rsquo;abord la table :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_PERSONNE_PRS<br />
<span style="color: #66cc66;">&#40;</span>PRS_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">IDENTITY</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">,</span><br />
&nbsp;PRS_DATE_NAISSANCE &nbsp;<span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">GO</span></div></div>
<p>Ensuite son alimentation, d&rsquo;abord avec plus de 40 000 lignes de personnes ayant des dates de naissances continues du 1/1/1900 à nos jours&#8230;</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">DECLARE</span> @D <span style="color: #993333; font-weight: bold;">DATE</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'1900-01-01'</span>;<br />
WHILE @D <span style="color: #66cc66;">&lt;=</span> <span style="color: #993333; font-weight: bold;">CURRENT_TIMESTAMP</span><br />
<span style="color: #993333; font-weight: bold;">BEGIN</span><br />
&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_PERSONNE_PRS <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span>@D<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SET</span> @D <span style="color: #66cc66;">=</span> DATEADD<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> @D<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #993333; font-weight: bold;">END</span>;</div></div>
<p>Enfin, on y ajoutant des doublons pour la charge afin d&#039;effectuer des tests de performances :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">WITH</span> TN <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AS</span> N<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">UNION</span> <span style="color: #993333; font-weight: bold;">ALL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> N <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; TN<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;N <span style="color: #66cc66;">&lt;</span> <span style="color: #cc66cc;">24</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_PERSONNE_PRS<br />
<span style="color: #993333; font-weight: bold;">SELECT</span> PRS_DATE_NAISSANCE<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; TN<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">CROSS</span> <span style="color: #993333; font-weight: bold;">JOIN</span> T_PERSONNE_PRS <span style="color: #993333; font-weight: bold;">AS</span> TP;</div></div>
<p>Ce qui remplit notre table avec plus d&#039;un million de lignes.</p>
<p><strong>Le calcul de l&rsquo;âge révolu</strong></p>
<p>Il fut calculer l&rsquo;âge en tenant compte du jour près par rapport à la date courante.<br />
Voici quelques approches malheureuses (fonctions SQL Server) :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- ceci est inexact... car imprécis jusqu'à 11 mois et 30 jours près !</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*,</span> DATEDIFF<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">YEAR</span><span style="color: #66cc66;">,</span> PRS_DATE_NAISSANCE<span style="color: #66cc66;">,</span> GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> AGE<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS;<br />
<br />
<span style="color: #808080; font-style: italic;">-- ceci est inexact... car imprécis jusqu'à 30 jours près ! </span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*,</span> DATEDIFF<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">,</span> PRS_DATE_NAISSANCE<span style="color: #66cc66;">,</span> GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">/</span> <span style="color: #cc66cc;">12</span> <span style="color: #993333; font-weight: bold;">AS</span> AGE<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS;<br />
<br />
<span style="color: #808080; font-style: italic;">-- ceci est inexact... car imprécis à 1 jours près ! </span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*,</span> <span style="color: #993333; font-weight: bold;">FLOOR</span><span style="color: #66cc66;">&#40;</span>DATEDIFF<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">,</span> PRS_DATE_NAISSANCE<span style="color: #66cc66;">,</span> GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">/</span> <span style="color: #cc66cc;">365.25</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> AGE<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS;</div></div>
<p>Voici maintenant une formulation qui donne les réponses exactes :</p>
<p><em>Requête 1 :</em></p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> % <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2013-11-20'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2013-11-20'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; % <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2013-12-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2013-12-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">371</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; % <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Les métriques de performances relevées (4 UC), sont les suivantes :<br />
&#8212; 1) Temps UC = 748 ms, temps écoulé = 8031 ms.<br />
&#8212; 2) Temps UC = 515 ms, temps écoulé = 7994 ms.<br />
&#8212; 3) Temps UC = 717 ms, temps écoulé = 7948 ms.<br />
&#8212; 4) Temps UC = 624 ms, temps écoulé = 7932 ms.</p>
<p><strong>La recherche des anniversaires</strong></p>
<p>Voici tout d&rsquo;abord quelques requêtes simples pour des cas triviaux :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- les personnes qui ont leur date d'anniversaire aujourd'hui</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;<span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; <br />
<span style="color: #808080; font-style: italic;">-- les personnes qui ont leur date de naissance dans 15 jours</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>DATEADD<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15</span><span style="color: #66cc66;">,</span> GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;<span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>DATEADD<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15</span><span style="color: #66cc66;">,</span> GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; &nbsp;<br />
&nbsp; <br />
<span style="color: #808080; font-style: italic;">-- les personnes qui ont leur date d'anniversaire dans le mois courant</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">-- les personnes qui ont leur date d'anniversaire dans le mois suivant le mois courant</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> % <span style="color: #cc66cc;">13</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">/</span> <span style="color: #cc66cc;">12</span>;<br />
<span style="color: #808080; font-style: italic;">-- notez le + 1 pour rechercher le mois suivant</span><br />
<br />
<span style="color: #808080; font-style: italic;">-- les personnes qui ont leur date d'anniversaire dans le 6e mois suivant le mois courant</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">6</span><span style="color: #66cc66;">&#41;</span> % <span style="color: #cc66cc;">13</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">/</span> <span style="color: #cc66cc;">12</span>;<br />
<span style="color: #808080; font-style: italic;">-- notez le + 6...</span></div></div>
<p>Nous allons maintenant rechercher les personnes qui ont leur date d&rsquo;anniversaire entre deux dates&#8230; </p>
<p>Voici tout d&rsquo;abord quelques cas triviaux :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- exemple 1 : 20 février / 10 mars</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&gt;=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-02-20'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-02-20'</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&lt;=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-03-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-03-10'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- exemple 2 : 20 décembre / 10 janvier (an + 1)</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&gt;=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-12-20'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-12-20'</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">OR</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&lt;=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2015-01-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2015-01-10'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #808080; font-style: italic;">-- notez la présence du OR à la place du AND, car nous avons changé d'année (l'intervalle s'est &quot;retourné&quot;) !</span></div></div>
<p>Et maintenant la solution générique :</p>
<p><em>Requête 2</em></p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- avec dates du 20 décembre au 10 janvier (an + 1)</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> % <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-12-20'</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-12-20'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp;% <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2015-01-10'</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2015-01-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">372</span><span style="color: #66cc66;">&#41;</span> &nbsp;% <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">-- &nbsp;avec dates du 20 février au 10 mars</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> % <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-02-20'</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-02-20'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp;% <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-03-10'</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-03-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">372</span><span style="color: #66cc66;">&#41;</span> &nbsp;% <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Les métriques de performances relevées (4 UC), sont les suivantes :<br />
&#8211;&gt; 1) Temps UC = 951 ms, temps écoulé = 677 ms.<br />
&#8211;&gt; 2) Temps UC = 967 ms, temps écoulé = 641 ms.<br />
&#8211;&gt; 3) Temps UC = 890 ms, temps écoulé = 638 ms.<br />
&#8211;&gt; 4) Temps UC = 905 ms, temps écoulé = 663 ms.</p>
<p>La question est maintenant&#8230; Y a t-il des formulations plus performantes ?</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tri combiné dans un arbre intervallaire</title>
		<link>https://blog.developpez.com/sqlpro/p11925/langage-sql-norme/tri-combine-dans-un-arbre-intervallaire</link>
		<comments>https://blog.developpez.com/sqlpro/p11925/langage-sql-norme/tri-combine-dans-un-arbre-intervallaire#comments</comments>
		<pubDate>Thu, 18 Apr 2013 07:42:23 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[PostGreSQL]]></category>
		<category><![CDATA[arborescence]]></category>
		<category><![CDATA[chemin]]></category>
		<category><![CDATA[fratrie]]></category>
		<category><![CDATA[intervale]]></category>
		<category><![CDATA[intervallaire]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[sibling]]></category>
		<category><![CDATA[tri]]></category>
		<category><![CDATA[tri mixte]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=286</guid>
		<description><![CDATA[Trier des données dans le sens de l&#8217;arborescence et quand elle sont aux même niveau (frères) par ordre alphabétique (tri mixte arbre et alfa) est difficile à réaliser dans un arbre modélisé par intervalle. Mais le principe est assez simple. Il suffit de composer une nouvelle colonne constitué d&#8217;une alternance de nœud et d&#8217;ordre alphabétique [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Trier des données dans le sens de l&rsquo;arborescence et quand elle sont aux même niveau (frères) par ordre alphabétique (tri mixte arbre et alfa) est difficile à réaliser dans un arbre modélisé par intervalle. Mais le principe est assez simple. Il suffit de composer une nouvelle colonne constitué d&rsquo;une alternance de nœud et d&rsquo;ordre alphabétique relatif dans la fratrie, et de trier dessus. Voici comment faire. Cette technique s’appelle en anglais &laquo;&nbsp;sibling ordering&nbsp;&raquo;.<br />
<span id="more-286"></span> </p>
<p><strong>1 &#8211;  LE PROBLÈME</strong></p>
<p><strong>Voici notre jeu de test :</strong></p>
<p>Tout d&rsquo;abord la table</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE TABLE T_VEHICULE_VHC<br />
(VHC_ID &nbsp; &nbsp; &nbsp; &nbsp; INTEGER NOT NULL PRIMARY KEY,<br />
&nbsp;VHC_BG &nbsp; &nbsp; &nbsp; &nbsp; INTEGER,<br />
&nbsp;VHC_BD &nbsp; &nbsp; &nbsp; &nbsp; INTEGER,<br />
&nbsp;VHC_NIVEAU &nbsp; &nbsp; SMALLINT,<br />
&nbsp;VHC_NOM &nbsp; &nbsp; &nbsp; &nbsp;VARCHAR(16));</div></div>
<p>Et ses données :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INSERT INTO T_VEHICULE_VHC VALUES ( 1, &nbsp;1, 26, 0, 'ALL');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 2, &nbsp;2, &nbsp;7, 1, 'SEA');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 3, &nbsp;8, 19, 1, 'EARTH');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 4, 20, 25, 1, 'AIR');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 5, &nbsp;3, &nbsp;4, 2, 'SUBMARINE');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 6, &nbsp;5, &nbsp;6, 2, 'BOAT');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 7, &nbsp;9, 10, 2, 'CAR');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 8, 11, 16, 2, 'TWO WHEELS');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 9, 17, 18, 2, 'TRUCK');<br />
INSERT INTO T_VEHICULE_VHC VALUES (10, 21, 22, 2, 'ROCKET');<br />
INSERT INTO T_VEHICULE_VHC VALUES (11, 23, 24, 2, 'PLANE');<br />
INSERT INTO T_VEHICULE_VHC VALUES (12, 12, 13, 3, 'MOTORCYCLE');<br />
INSERT INTO T_VEHICULE_VHC VALUES (13, 14, 15, 3, 'BICYCLE');</div></div>
<p><strong>Premier essai :</strong></p>
<p>Une simple requête telle que celle-ci :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT CAST(SPACE(VHC_NIVEAU) + VHC_NOM AS VARCHAR(32)) AS NOM_IDENTE, <br />
&nbsp; &nbsp; &nbsp; &nbsp;VHC_ID, VHC_BG, VHC_BD, VHC_NIVEAU<br />
FROM &nbsp; T_VEHICULE_VHC &nbsp;<br />
ORDER &nbsp;BY VHC_BG;</div></div>
<p>Donne un résultat insatisfaisant :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">NOM_IDENTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; VHC_ID &nbsp; &nbsp; &nbsp;VHC_BG &nbsp; &nbsp; &nbsp;VHC_BD &nbsp; &nbsp; &nbsp;VHC_NIVEAU<br />
-------------------------------- ----------- ----------- ----------- ----------<br />
ALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 26 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0<br />
&nbsp;SEA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; SUBMARINE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp; BOAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp;EARTH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 19 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; CAR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; TWO WHEELS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;16 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; &nbsp;MOTORCYCLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3<br />
&nbsp; &nbsp;BICYCLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;14 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;15 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3<br />
&nbsp; TRUCK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 17 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;18 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp;AIR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 20 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;25 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; ROCKET &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;21 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;22 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; PLANE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;23 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;24 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2</div></div>
<p>Au niveau 1, &laquo;&nbsp;SEA&nbsp;&raquo; est avant &laquo;&nbsp;EARTH&nbsp;&raquo; qui lui même est avant &laquo;&nbsp;AIR&nbsp;&raquo;. Dans les deux roues (&laquo;&nbsp;TWO WHEELS&nbsp;&raquo;), &laquo;&nbsp;MOTORCYCLE&nbsp;&raquo; précède &laquo;&nbsp;BICYCLE&nbsp;&raquo;. Enfin, &laquo;&nbsp;CAR&nbsp;&raquo;, &laquo;&nbsp;TWO WHEELS&nbsp;&raquo; et &laquo;&nbsp;TRUCK&nbsp;&raquo; sont mélangés.<br />
Il n&rsquo;est pas possible d&rsquo;obtenir un meilleur ordonnancement directement basé sur les valeurs des colonnes actuelles de la table.</p>
<p>Mais la technique de l&rsquo;arbre intervallaire permet d&rsquo;ordonner les frères entre eux. Il suffit donc de bouger les bornes droites et gauches pour que cela corresponde à l&rsquo;ordre demandé. </p>
<p><strong>2 &#8211; PREMIÈRE SOLUTION</strong></p>
<p>Elle consiste donc à réordonner les bornes gauche et droite.</p>
<p>La nouvelle table pour ce faire :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE TABLE T_VEHICULE2_VHC<br />
(VHC_ID &nbsp; &nbsp; &nbsp; &nbsp; INTEGER NOT NULL PRIMARY KEY,<br />
&nbsp;VHC_BG &nbsp; &nbsp; &nbsp; &nbsp; INTEGER,<br />
&nbsp;VHC_BD &nbsp; &nbsp; &nbsp; &nbsp; INTEGER,<br />
&nbsp;VHC_NIVEAU &nbsp; &nbsp; SMALLINT,<br />
&nbsp;VHC_NOM &nbsp; &nbsp; &nbsp; &nbsp;VARCHAR(16));</div></div>
<p>Les données réarrangées :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INSERT INTO T_VEHICULE2_VHC VALUES ( 1, &nbsp;1, 26, 0, 'ALL');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 2, 20, 25, 1, 'SEA');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 3, &nbsp;8, 19, 1, 'EARTH');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 4, &nbsp;2, &nbsp;7, 1, 'AIR');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 5, 23, 24, 2, 'SUBMARINE');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 6, 21, 22, 2, 'BOAT');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 7, &nbsp;9, 10, 2, 'CAR');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 8, 13, 18, 2, 'TWO WHEELS');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 9, 11, 12, 2, 'TRUCK');<br />
INSERT INTO T_VEHICULE2_VHC VALUES (10, &nbsp;5, &nbsp;6, 2, 'ROCKET');<br />
INSERT INTO T_VEHICULE2_VHC VALUES (11, &nbsp;3, &nbsp;4, 2, 'PLANE');<br />
INSERT INTO T_VEHICULE2_VHC VALUES (12, 16, 17, 3, 'MOTORCYCLE');<br />
INSERT INTO T_VEHICULE2_VHC VALUES (13, 14, 15, 3, 'BICYCLE');</div></div>
<p>La requête :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT CAST(SPACE(VHC_NIVEAU) + VHC_NOM AS VARCHAR(32)) AS NOM_IDENTE, <br />
&nbsp; &nbsp; &nbsp; &nbsp;VHC_ID, VHC_BG, VHC_BD, VHC_NIVEAU<br />
FROM &nbsp; T_VEHICULE2_VHC &nbsp;<br />
ORDER &nbsp;BY VHC_BG;</div></div>
<p>Le résultat :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">NOM_IDENTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; VHC_ID &nbsp; &nbsp; &nbsp;VHC_BG &nbsp; &nbsp; &nbsp;VHC_BD &nbsp; &nbsp; &nbsp;VHC_NIVEAU<br />
-------------------------------- ----------- ----------- ----------- ----------<br />
ALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 26 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0<br />
&nbsp;AIR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; PLANE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp; ROCKET &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp;EARTH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 19 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; CAR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; TRUCK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; TWO WHEELS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;18 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; &nbsp;BICYCLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;14 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;15 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3<br />
&nbsp; &nbsp;MOTORCYCLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;16 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;17 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3<br />
&nbsp;SEA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 20 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;25 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; BOAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 21 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;22 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; SUBMARINE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 23 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;24 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2</div></div>
<p><strong>Critique de la première solution</strong></p>
<p>La requête finale est simple. En revanche le coût est reporté lors des mises à jours (généralement peu nombreuses dans les arborescences) mais cela oblige souvent à réordonner tout l&rsquo;arbre (ce qui peut se minimiser en modélisant l&rsquo;arbre intervallaire à côté de la table contenant les données).<br />
De plus, elle n&rsquo;est pas satisfaisante si d&rsquo;autres colonnes complique la structure de la table et qu&rsquo;il faut en tenir compte dans la solution (par exemple de multiples arborescences).</p>
<p><strong>3 &#8211; UNE SOLUTION GÉNÉRIQUE</strong></p>
<p>Il existe une façon de faire globale, mais elle nécessite hélas une requête récursive en sus d&rsquo;être gourmande en données. Cette solution consiste à rajouter un &laquo;&nbsp;chemin&nbsp;&raquo; composé d&rsquo;une mixité de données comprenant les ancêtres alternés avec la position ordinale des frères entre eux. Pour la faire fonctionner correctement il est nécessaire d&rsquo;utiliser une fonction de remplissage que j&rsquo;ai intitulé PADMASK :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--===========================================================================--<br />
-- Masque de caractères avec fusion alignée<br />
--===========================================================================--<br />
CREATE FUNCTION &nbsp;[F_PADMASK](@DATA NVARCHAR(1024), <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@MASK NVARCHAR(1024),<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@ALIGN CHAR(6))<br />
RETURNS NVARCHAR(1024)<br />
AS<br />
/****************************************************************************** <br />
* Fonction de masque pour une donées polymorphe retournée en chaine de car. &nbsp; *<br />
******************************************************************************* <br />
* Fred. Brouard - http://sqlpro.developpez.com - www.sqlspot.com - 2012-07-12 * <br />
*******************************************************************************<br />
* Fusionne une donnée chaine avec un masque aligné à droite ou à gauche &nbsp; &nbsp; &nbsp; * <br />
* Exemples : &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; &nbsp;*<br />
* SELECT dbo.F_PADMASK('ABC', '*****', 'LEFT' ) &nbsp; --&amp;gt; 'ABC**' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *<br />
* SELECT dbo.F_PADMASK(123, '00000', 'RIGHT') &nbsp; &nbsp; --&amp;gt; '00123' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *<br />
* SELECT dbo.F_PADMASK('ABCDEFG', '***', 'LEFT') &nbsp;--&amp;gt; 'EFG' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *<br />
* SELECT dbo.F_PADMASK('ABCDEFG', '***', 'RIGHT') --&amp;gt; 'ABC' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *<br />
******************************************************************************/ <br />
BEGIN<br />
&nbsp; &nbsp;IF @MASK IS NULL RETURN '';<br />
&nbsp; &nbsp;IF @DATA IS NULL RETURN @MASK;<br />
&nbsp; &nbsp;IF UPPER(@ALIGN) IN ('RIGHT', 'DROIT', 'DROITE')<br />
&nbsp; &nbsp; &nbsp; SET @ALIGN = 'RIGHT'<br />
&nbsp; &nbsp;ELSE<br />
&nbsp; &nbsp; &nbsp; SET @ALIGN = 'LEFT'; &nbsp; &nbsp;<br />
-- masque avec alignement à gauche (alpha) &nbsp; <br />
&nbsp; &nbsp;IF @ALIGN = 'LEFT'<br />
&nbsp; &nbsp;BEGIN<br />
&nbsp; &nbsp; &nbsp; IF LEN(@MASK) &amp;gt; LEN(@DATA)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SET @DATA = @DATA + SUBSTRING(@MASK, LEN(@DATA) + 1, LEN(@MASK) - LEN(@DATA));<br />
&nbsp; &nbsp; &nbsp; IF LEN(@MASK) &nbsp;LEN(@DATA)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SET @DATA = SUBSTRING(@MASK, 1, LEN(@MASK) - LEN(@DATA)) + @DATA;<br />
&nbsp; &nbsp; &nbsp; IF LEN(@MASK) &amp;lt; LEN(@DATA)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SET @DATA = SUBSTRING(@DATA, LEN(@DATA) - LEN(@MASK) + 1, LEN(@MASK));<br />
&nbsp; &nbsp;END;<br />
&nbsp; &nbsp;RETURN @DATA; &nbsp; <br />
END<br />
GO</div></div>
<p><strong>NOTA</strong> : la fonction F_PADMASK a été écrite pour MS SQL Server, et peut aisément être traduite en PGPL/SQL pour PostGreSQL.</p>
<p>Voici maintenant la requête :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">WITH <br />
TA AS -- crée un indice numérique global d'ordonnancement alphabétique des libellés et le transforme en chaine complété avec des zéros<br />
(SELECT VHC_ID, VHC_BG, VHC_BD, VHC_NIVEAU, VHC_NOM, <br />
&nbsp; &nbsp; &nbsp; &nbsp; dbo.F_PADMASK(CAST(ROW_NUMBER() OVER(ORDER BY VHC_NOM) AS VARCHAR(10)), '00000000000', 'RIGHT') &nbsp;AS ORDRE<br />
&nbsp;FROM &nbsp; T_VEHICULE_VHC),<br />
T0 AS -- concatène un mixte de chemin et d'indice alphabétique dans une colonne intitulée PATH_MIXTE<br />
(SELECT VHC_ID, VHC_BG, VHC_BD, VHC_NIVEAU, VHC_NOM, ORDRE, <br />
&nbsp; &nbsp; &nbsp; &nbsp; CAST(dbo.F_PADMASK(VHC_NOM, '****************', 'LEFT') + ORDRE AS NVARCHAR(max)) AS PATH_MIXTE<br />
&nbsp;FROM &nbsp; TA<br />
&nbsp;WHERE &nbsp;VHC_NIVEAU = 0<br />
&nbsp;UNION ALL<br />
&nbsp;SELECT T1.VHC_ID, T1.VHC_BG, T1.VHC_BD, T1.VHC_NIVEAU, T1.VHC_NOM, T1.ORDRE, <br />
&nbsp; &nbsp; &nbsp; &nbsp; T0.PATH_MIXTE + dbo.F_PADMASK(T1.VHC_NOM, '****************', 'LEFT') + T1.ORDRE<br />
&nbsp;FROM &nbsp; TA AS T1<br />
&nbsp; &nbsp; &nbsp; &nbsp; INNER JOIN T0 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ON T1.VHC_NIVEAU = T0.VHC_NIVEAU + 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND T1.VHC_BG &amp;gt; T0.VHC_BG<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND T1.VHC_BD &amp;lt; T0.VHC_BD)<br />
SELECT CAST(SPACE(VHC_NIVEAU) + VHC_NOM AS VARCHAR(32)) AS NOM_IDENTE, <br />
&nbsp; &nbsp; &nbsp; &nbsp;VHC_ID, VHC_BG, VHC_BD, VHC_NIVEAU, PATH_MIXTE<br />
FROM &nbsp; T0 &nbsp;<br />
ORDER &nbsp;BY PATH_MIXTE;</div></div>
<p>Comme indiqué, la colonne surnuméraire de tri, PATH_MIXTE, va contenir le chemin jusqu&rsquo;au nœud en cours avec entre chaque nom d&rsquo;élément sa position relative dans la fratrie. Le nécessité d&rsquo;utiliser la fonction de remplissage est lié au fait que notre colonne de tri contient une alternance de données numérique et alphabétique qu&rsquo;il faut ordonner ensemble. or les nombres sont alignés à droite et les mots à gauche. la fonction F_PADMASK permet de coordonner ces alignements. On comprend mieux la chose en voyant ce quelle contient :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">NOM_IDENTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;VHC_ID &nbsp; &nbsp; &nbsp;VHC_BG &nbsp; &nbsp; &nbsp;VHC_BD &nbsp; &nbsp; &nbsp;VHC_NIVEAU PATH_MIXTE &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; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
------------------- ----------- ----------- ----------- ---------- ------------------------------------------------------------------------------------------------------------<br />
ALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 26 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002<br />
&nbsp;AIR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 20 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;25 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002AIR*************00000000001<br />
&nbsp; PLANE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;23 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;24 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002AIR*************00000000001PLANE***********00000000008<br />
&nbsp; ROCKET &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;21 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;22 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002AIR*************00000000001ROCKET**********00000000009<br />
&nbsp;EARTH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 19 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006<br />
&nbsp; CAR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006CAR*************00000000005<br />
&nbsp; TRUCK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 17 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;18 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006TRUCK***********00000000012<br />
&nbsp; TWO WHEELS &nbsp; &nbsp; &nbsp; &nbsp;8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;16 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006TWO WHEELS******00000000013<br />
&nbsp; &nbsp;BICYCLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;14 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;15 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006TWO WHEELS******00000000013BICYCLE*********00000000003<br />
&nbsp; &nbsp;MOTORCYCLE &nbsp; &nbsp; &nbsp; 12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006TWO WHEELS******00000000013MOTORCYCLE******00000000007<br />
&nbsp;SEA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002SEA*************00000000010<br />
&nbsp; BOAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002SEA*************00000000010BOAT************00000000004<br />
&nbsp; SUBMARINE &nbsp; &nbsp; &nbsp; &nbsp; 5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002SEA*************00000000010SUBMARINE*******00000000011</div></div>
<p><strong>NOTA</strong> : le nombre de caractères de remplissage pour la partie alphabétique (ici colonne VHC_NOM) dépend de la longueur de la colonne (ici 16) définit à la construction de la table.</p>
<p><strong>ATTENTION</strong> : Certaines formulations, comme celle données ici sur Internet &laquo;&nbsp;<a href="http://stackoverflow.com/questions/2834156/ordering-recursive-result-set-in-sql-server" title="Ordering recursive result set in SQL Server">Ordering recursive result set in SQL Server</a>&nbsp;&raquo; sont fausses. Je vous laisse deviner pourquoi !</p>
<p><strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a><br />
<img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>

</pre>
<p>L&rsquo;ntreprise <a href="http://www.sqlspot.com">SQL Spot</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ajout du niveau dans un arbre intervallaire</title>
		<link>https://blog.developpez.com/sqlpro/p11924/langage-sql-norme/ajout-du-niveau-dans-un-arbre-intervallaire</link>
		<comments>https://blog.developpez.com/sqlpro/p11924/langage-sql-norme/ajout-du-niveau-dans-un-arbre-intervallaire#comments</comments>
		<pubDate>Wed, 17 Apr 2013 16:36:53 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[PostGreSQL]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[arborescence]]></category>
		<category><![CDATA[arbre]]></category>
		<category><![CDATA[intervallaire]]></category>
		<category><![CDATA[intervalle]]></category>
		<category><![CDATA[niveau]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=281</guid>
		<description><![CDATA[Voici comment ajouter le niveau des éléments dans un arbre modélisé par intervalles. Pour notre test, la table est la suivante : CREATE TABLE T_VEHICULE_VHC (VHC_ID &#160; &#160; &#160; &#160; INTEGER NOT NULL PRIMARY KEY, &#160;VHC_BG &#160; &#160; &#160; &#160; INTEGER, &#160;VHC_BD &#160; &#160; &#160; &#160; INTEGER, &#160;VHC_NOM &#160; &#160; &#160; &#160;VARCHAR(16)); Les données que [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Voici comment ajouter le niveau des éléments dans un arbre modélisé par intervalles.<br />
<span id="more-281"></span><br />
Pour notre test, la table est la suivante :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE TABLE T_VEHICULE_VHC<br />
(VHC_ID &nbsp; &nbsp; &nbsp; &nbsp; INTEGER NOT NULL PRIMARY KEY,<br />
&nbsp;VHC_BG &nbsp; &nbsp; &nbsp; &nbsp; INTEGER,<br />
&nbsp;VHC_BD &nbsp; &nbsp; &nbsp; &nbsp; INTEGER,<br />
&nbsp;VHC_NOM &nbsp; &nbsp; &nbsp; &nbsp;VARCHAR(16));</div></div>
<p>Les données que l&rsquo;on y insère sont les suivantes :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INSERT INTO T_VEHICULE_VHC VALUES (1, 1, 26, 'ALL');<br />
INSERT INTO T_VEHICULE_VHC VALUES (2, 2, 7, 'SEA');<br />
INSERT INTO T_VEHICULE_VHC VALUES (3, 8, 19, 'EARTH');<br />
INSERT INTO T_VEHICULE_VHC VALUES (4, 20, 25, 'AIR');<br />
INSERT INTO T_VEHICULE_VHC VALUES (5, 3, 4, 'SUBMARINE');<br />
INSERT INTO T_VEHICULE_VHC VALUES (6, 5, 6, 'BOAT');<br />
INSERT INTO T_VEHICULE_VHC VALUES (7, 9, 10, 'CAR');<br />
INSERT INTO T_VEHICULE_VHC VALUES (8, 11, 16, 'TWO WHEELS');<br />
INSERT INTO T_VEHICULE_VHC VALUES (9, 17, 18, 'TRUCK');<br />
INSERT INTO T_VEHICULE_VHC VALUES (10, 21, 22, 'ROCKET');<br />
INSERT INTO T_VEHICULE_VHC VALUES (11, 23, 24, 'PLANE');<br />
INSERT INTO T_VEHICULE_VHC VALUES (12, 12, 13, 'MOTORCYCLE');<br />
INSERT INTO T_VEHICULE_VHC VALUES (13, 14, 15, 'BICYCLE');;</div></div>
<p>Que l&rsquo;on peut présenter ainsi :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">VHC_NOM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;VHC_ID &nbsp; &nbsp; &nbsp;VHC_NIVEAU &nbsp;VHC_PATH<br />
------------------ ----------- ----------- --------------------------------<br />
ALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp;AIR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AIR<br />
&nbsp; PLANE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AIR, PLANE<br />
&nbsp; ROCKET &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AIR, ROCKET<br />
&nbsp;EARTH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EARTH<br />
&nbsp; CAR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EARTH, CAR<br />
&nbsp; TRUCK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EARTH, TRUCK<br />
&nbsp; TWO WHEELS &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EARTH, TWO WHEELS<br />
&nbsp; &nbsp;BICYCLE &nbsp; &nbsp; &nbsp; &nbsp; 13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EARTH, TWO WHEELS, BICYCLE<br />
&nbsp; &nbsp;MOTORCYCLE &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; EARTH, TWO WHEELS, MOTORCYCLE<br />
&nbsp;SEA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SEA<br />
&nbsp; BOAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SEA, BOAT<br />
&nbsp; SUBMARINE &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SEA, SUBMARINE</div></div>
<p>Le calcul du niveau peut se faire par la requête :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT VHC_ID, <br />
&nbsp; &nbsp; &nbsp; &nbsp;(SELECT COUNT(*) <br />
&nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; T_VEHICULE_VHC <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;VHC_BG &nbsp;REF.VHC_BD) AS VHC_NIVEAU,<br />
&nbsp; &nbsp; &nbsp; &nbsp;VHC_NOM <br />
FROM &nbsp; T_VEHICULE_VHC AS REF;</div></div>
<p>En fait il s&rsquo;agit de compter le nombre de parents d&rsquo;un nœud.</p>
<p>Pour rajouter le calcul du niveau en dur dans la table, on peut faire comme ceci :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ALTER TABLE T_VEHICULE_VHC ADD VHC_NIVEAU SMALLINT;</div></div>
<p>Ce qui rajoute la colonne niveau dans la table.</p>
<p>Il faut maintenant la mettre à jour :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">UPDATE REF<br />
SET &nbsp; &nbsp;VHC_NIVEAU = (SELECT COUNT(*) <br />
&nbsp; &nbsp; &nbsp; &nbsp; FROM &nbsp; T_VEHICULE_VHC <br />
&nbsp; &nbsp; &nbsp; &nbsp; WHERE &nbsp;VHC_BG &nbsp;REF.VHC_BD)<br />
FROM &nbsp; T_VEHICULE_VHC AS REF;</div></div>
<p><strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a><br />
<img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>

</pre>
<p>L&rsquo;ntreprise <a href="http://www.sqlspot.com">SQL Spot</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Comparatif des fonctionnalités PostGreSQL 9.2 SQL Server 2012</title>
		<link>https://blog.developpez.com/sqlpro/p11859/langage-sql-norme/comparatif-des-fonctionnalites-postgresql-9-2-sql-server-2012</link>
		<comments>https://blog.developpez.com/sqlpro/p11859/langage-sql-norme/comparatif-des-fonctionnalites-postgresql-9-2-sql-server-2012#comments</comments>
		<pubDate>Tue, 26 Mar 2013 09:24:49 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[PostGreSQL]]></category>
		<category><![CDATA[comparaison]]></category>
		<category><![CDATA[comparatif]]></category>
		<category><![CDATA[fonctionnalité]]></category>
		<category><![CDATA[SQL Sever]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=268</guid>
		<description><![CDATA[Voici une étude comparant les fonctionnalités de Microsoft SQL Server version 2012 et de PostGreSQL version 9.2. Dans ce comparatif des fonctionnalités de nombreuses sources et explication sont fournies. Comparaison PostGreSQL 9.2 Microsoft SQL Server 2012 fonctionnalités Le site web sur le SQL et les SGBDR Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES Expert &#160;S.G.B.D [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Voici une étude comparant les fonctionnalités de Microsoft SQL Server version 2012 et de PostGreSQL version 9.2.<br />
Dans ce comparatif des fonctionnalités de nombreuses sources et explication sont fournies.<br />
<a href="http://blog.developpez.com/sqlpro/files/2013/03/Comparaison-PostGreSQL-9.2-Microsoft-SQL-Server-2012-fonctionnalités.pdf">Comparaison PostGreSQL 9.2 Microsoft SQL Server 2012 fonctionnalités</a></p>
<p><strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a><br />
<img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>

</pre>
<p>L&rsquo;ntreprise <a href="http://www.sqlspot.com">SQL Spot</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Où et comment sont stockées mes données avec PostGreSQL ?</title>
		<link>https://blog.developpez.com/sqlpro/p11821/bases-de-donnees/ou-et-comment-sont-stockees-mes-donnees-avec-postgresql</link>
		<comments>https://blog.developpez.com/sqlpro/p11821/bases-de-donnees/ou-et-comment-sont-stockees-mes-donnees-avec-postgresql#comments</comments>
		<pubDate>Thu, 07 Mar 2013 10:46:25 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[PostGreSQL]]></category>
		<category><![CDATA[fichier]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[stockage]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=261</guid>
		<description><![CDATA[Comme tous les SGBD relationnel, PostGreSQL stocke les données des tables et des index dans des fichiers organisés sous forme de pages. Que les données soient dans le cache (donc en mémoire vive), ou bien sur le disque, ces pages sont structurées d’une manière bien particulière afin d’exploiter au mieux les lectures et écritures physiques [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Comme tous les SGBD relationnel, PostGreSQL stocke les données des tables et des index dans des fichiers organisés sous forme de pages. Que les données soient dans le cache (donc en mémoire vive), ou bien sur le disque, ces pages sont structurées d’une manière bien particulière afin d’exploiter au mieux les lectures et écritures physiques et logiques ainsi que la gestion des versions de ligne.<br />
L&rsquo;ensemble des pages figurent dans des fichiers.<br />
Cet article a pour but de vous présenter comment et où PostGreSQL stocke les données et compare sa façon de faire aux autres SGBDR que sont Oracle et MS SQL Server.<br />
Mais contrairement à ses grands frères, PostGreSQL ne dispose pas d&rsquo;une gestion des espaces de stockage&#8230; Voyons ce que cela induit notamment sur le plan des performances et de la volumétrie.<br />
<span id="more-261"></span><br />
L&rsquo;étude est disponible sous format PDF à l&rsquo;URL suivante : <a href="http://blog.developpez.com/sqlpro/files/2013/03/Ou-sont-stockées-mes-données-avec-PostGreSQL.pdf">Ou sont stockées mes données avec PostGreSQL</a></p>
<p><strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>

</pre>
<p>L&rsquo;ntreprise <a href="http://www.sqlspot.com">SQL Spot</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
