<?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>SQL &#38; SQL Server sans tabou &#187; Bon à savoir</title>
	<atom:link href="https://blog.developpez.com/mssql-sans-tabou/pcategory/bon-a-savoir/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/mssql-sans-tabou</link>
	<description></description>
	<lastBuildDate>Tue, 26 Jun 2012 15:46:35 +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>Quelques choses à savoir sur les espaces en fin de chaîne</title>
		<link>https://blog.developpez.com/mssql-sans-tabou/p11117/bon-a-savoir/quelques_choses_a_savoir_sur_les_espaces</link>
		<comments>https://blog.developpez.com/mssql-sans-tabou/p11117/bon-a-savoir/quelques_choses_a_savoir_sur_les_espaces#comments</comments>
		<pubDate>Tue, 26 Jun 2012 15:42:58 +0000</pubDate>
		<dc:creator><![CDATA[Sergejack]]></dc:creator>
				<category><![CDATA[Bon à savoir]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Lorsque l&#8217;on manipule des chaîne de caractères se terminant par un ou une séries d&#8217;espace, il est bon d&#8217;avoir un certain nombre de considérations à l&#8217;esprit. &#8216;abc&#8217; = &#8216;abc &#8216; se vérifie Lorsque vous comparez deux chaînes de caractère de longueurs différentes via l&#8217;opérateur de comparaison &#171;&#160;=&#160;&#187;, SQL Server va &#171;&#160;au préalable&#160;&#187; (et selon la norme ANSI SQL92) forcer les chaînes a avoir des tailles identiques en rallonger la plus courte par des espaces terminaux [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>
Lorsque l&rsquo;on manipule des chaîne de caractères se terminant par un ou une séries d&rsquo;espace, il est bon d&rsquo;avoir un certain nombre de considérations à l&rsquo;esprit.
</p>
<p><span id="more-6"></span></p>
<h2>&lsquo;abc&rsquo; = &lsquo;abc &lsquo; se vérifie</h2>
<p>
Lorsque vous comparez deux chaînes de caractère de longueurs différentes via l&rsquo;opérateur de comparaison &laquo;&nbsp;=&nbsp;&raquo;, SQL Server va &laquo;&nbsp;au préalable&nbsp;&raquo; (et selon la norme ANSI SQL92) forcer les chaînes a avoir des tailles identiques en rallonger la plus courte par des espaces terminaux (PADDING)
</p>
<p>
Le résultat en est par exemple que &lsquo;abc&rsquo; = &lsquo;abc &lsquo; se vérifie.<br />
<br />
<a href="http://support.microsoft.com/kb/316626/en-us">infos complémentaires</a>
</p>
<h2>&lsquo;abc&rsquo; LIKE &lsquo;abc &lsquo; ne se vérifie pas</h2>
<p>
Comme la nature du LIKE ne se limite pas au test d&rsquo;égalité, celui n&rsquo;est pas, comme l&rsquo;opérateur &laquo;&nbsp;=&nbsp;&raquo;, soumis à la norme évoquée plus haut.
</p>
<p>
Le résultat en est par exemple que &lsquo;abc&rsquo; LIKE &lsquo;abc &lsquo; ne se vérifie pas.
</p>
<h2><a href="http://msdn.microsoft.com/en-us/library/ms190329.aspx">LEN</a>(&lsquo;abc &lsquo;) renvoi 3 et non 4</h2>
<p>
Par définition la fonction LEN qui renvoi la taille d&rsquo;une chaîne de caractère passée en paramètre ne tient pas compte des espaces en fin de cette chaîne
</p>
<p>
Par conséquent, LEN(&lsquo;abc &lsquo;) renvoi 3 et non 4.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Le triangle parfait entre FROM, OUTPUT et MERGE</title>
		<link>https://blog.developpez.com/mssql-sans-tabou/p11041/bon-a-savoir/merge_output</link>
		<comments>https://blog.developpez.com/mssql-sans-tabou/p11041/bon-a-savoir/merge_output#comments</comments>
		<pubDate>Tue, 22 May 2012 15:42:48 +0000</pubDate>
		<dc:creator><![CDATA[Sergejack]]></dc:creator>
				<category><![CDATA[Bon à savoir]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le triangle parfait entre FROM, OUTPUT et MERGE Le but de ce sujet est de vous montrer un intérêt résidant en MERGE et qui est d&#8217;offrir une possibilité cruellement absente avant son apparition en SQL Server : à l&#8217;insertion, récupérer dans la clause OUTPUT des valeurs provenant de la clause FROM (plutôt que provenant seulement des tables deleted et inserted). Note : MERGE est présent en SQL Server depuis la version 2008. Clause FROM, j&#8217;aime [&#8230;]]]></description>
				<content:encoded><![CDATA[<h1>Le triangle parfait entre FROM, OUTPUT et MERGE</h1>
<p><span id="more-4"></span></p>
<p> Le but de ce sujet est de vous montrer un intérêt résidant  en MERGE et qui est d&rsquo;offrir une possibilité cruellement absente avant son apparition  en SQL Server : à l&rsquo;insertion, récupérer dans la clause OUTPUT des valeurs  provenant de la clause FROM (plutôt que provenant seulement des tables deleted  et inserted).</p>
<p>
  Note :<br />
  MERGE est présent en SQL Server depuis la version 2008.</p>
<h2> Clause FROM, j&rsquo;aime :</h2>
<p> S&rsquo;il y a certaines raisons à l&rsquo;appréciation que je porte à  SQL Server (que je connais depuis sa version 2005), l&rsquo;existence de la clause  FROM pour UPDATE (entre autres) est une des plus significatives.<br />
  Il n&rsquo;y a aucun sarcasme tandis que je vous dis que Microsoft a fait, avec cette  clause, le choix de s&rsquo;écarter de la norme SQL avec une perspicacité exemplaire  (mais ceci n&rsquo;est pas le sujet traité). Cette clause qui est aussi présente pour  les DELETE est malheureusement absente des opérations INSERT.<br />
  À priori, cette absence ne semble pas porter à grande  conséquence puisqu&rsquo;il reste néanmoins possible de faire des insertions sur base  de résultats obtenus par select. (insert into … select … from …). Mais cela  serait oublier un peu vite la clause OUTPUT qui, si elle n&rsquo;en continue pas  moins d&rsquo;exister pour les opérations d&rsquo;insertion, n&rsquo;a alors pas accès à autre  chose qu&rsquo;aux table inserted et deleted.
</p>
<h2>
  INSERT FROM, y a OUTPUT qui te cherche :</h2>
<p> Ainsi donc, il n&rsquo;existe pas de clause FROM à l&rsquo;opération INSERT.<br />
  Alors imaginons un scénario où cela va nous manquer :<br />
  Nous avons deux tables temporaires, l&rsquo;une faisant référence à l&rsquo;autre (il y a  donc emploie de clés) et nous souhaitons copier le contenu de ces deux tables  temporaires vers des tables de même structures mais dont les identifiants  devront être adaptés (parce qu&rsquo;il s&rsquo;agit d&rsquo;identifiant numériques auto  incrémentés par exemple).<br />
  Nous allons donc devoir commencer par faire la copie des données de la table « parente/influente »  (celle qui est référée par l&rsquo;autre), récupérer les identifiants des lignes insérées  dans la table de destination et ensuite faire la copie des données de la table « fille/dépendante »  en exploitant les identifiants précédemment récupérés.
  </p>
<p>Facile à dire et bien que faisable, le faire est une belle  paire de manche (et autant vous dire, qu&rsquo;en tout cas de figure, il y aura des performances  tristement gâchées).</p>
<p align="center"> <em><img src="http://blog.developpez.com/media/InsertFrom.png" width="605" height="276" alt="Insert from" /><br />
  Recréer les relations n&rsquo;est pas une mince affaire.</em></p>
<h2>
  MERGE à la rescousse :</h2>
<p> MERGE qui a une syntaxe particulière offre non seulement une  approche compacte à la fusion de données (insérer ce qui n&rsquo;existe pas et mettre  à jour ce qui existe) mais offre surtout un remède aux problèmes qui ont été  mentionnés plus haut. En effet, MERGE permet dans sa clause OUTPUT de récupérer  des données provenant tant des tables inserted et deleted que de la table  source (table au sens large, un ensemble de résultats).<br />
  Ainsi, si l&lsquo;on reprend le scénario qui nous inquiétait en considérant une  approche avec INSERT, il devient facile pendant l&rsquo;insertion (avec MERGE) de  ligne provenant de la table temporaire « parente/influente » d&rsquo;en  récupérer simultanément l&rsquo;identifiant d&rsquo;origine et l&rsquo;identifiant obtenu après  insertion. Cela peut donc permettre d&rsquo;établir rapidement la correspondance d&rsquo;un  identifiant vers l&rsquo;autre, ce qui permettra donc une « traduction »  des identifiants lors de l&rsquo;insertion des lignes de la seconde table « fille/dépendante ».</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">DECLARE @Mapping TABLE ( <br />
&nbsp; externalID INT <br />
&nbsp; , internalID INT <br />
&nbsp; <br />
&nbsp; /* Ci dessous, une</div></div>

<a href="http://blog.developpez.com/mssql-sans-tabou/p11042/bon-a-savoir/vartable-index/">astuce</a> pour avoir un index sur externalID */ 
  , ID INT IDENTITY 
  , UNIQUE (externalID, ID) 
) 
 
MERGE INTO dbo.Vert AS Dst 
USING ( 
  SELECT 
    ID 
    , colonne1 
    , colonne2 
  FROM #tmpVert    
) AS Src 
ON ( 
  1 = 2 -- 100% nouvelles lignes 
) 
WHEN NOT MATCHED THEN 
  INSERT (colonne1, colonne2) 
  VALUES (Src.colonne1, Src.colonne2) 
OUTPUT Src.ID, inserted.ID INTO @Mapping(externalID, internalID) 
; -- Le point virgule fait partie de la syntaxe 
 
INSERT INTO dbo.Jaune ( 
  vertID 
  , colonne1 
) 
SELECT 
  M.internalID 
  , Src.colonne1 
FROM #tmpJaune AS Src 
INNER JOIN @Mapping AS M ON ( 
  M.externalID = Src.vertID 
) 
</pre>
<h2>
  Conclusion :</h2>
<p> Le simple fait d&rsquo;offrir une clause OUTPUT dans laquelle  les données de la table source peuvent être  récupérées, dote l&rsquo;opération MERGE d&rsquo;un avantage pouvant s&rsquo;avérer essentielle  face à l&rsquo;opération INSERT.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Des indexes dans vos variables tables</title>
		<link>https://blog.developpez.com/mssql-sans-tabou/p11042/bon-a-savoir/vartable_index</link>
		<comments>https://blog.developpez.com/mssql-sans-tabou/p11042/bon-a-savoir/vartable_index#comments</comments>
		<pubDate>Wed, 23 May 2012 09:01:45 +0000</pubDate>
		<dc:creator><![CDATA[Sergejack]]></dc:creator>
				<category><![CDATA[Bon à savoir]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Des indexes dans vos variables tables Contrairement à ce que l&#8217;on peut encore trop fréquemment lire, il est tout à fait possible, avec un peu d&#8217;astuce de définir des indexes sur les variables tables. Comment ? L&#8217;astuce en question est de tirer profit de la possibilité de définir pour un ou plusieurs ensembles de colonnes une contrainte d&#8217;unicité. La contrainte d&#8217;unicité que ce soit pour des variables tables, des tables temporaires ou des tables normales [&#8230;]]]></description>
				<content:encoded><![CDATA[<h1>Des indexes dans vos variables tables</h1>
<p> Contrairement à ce que l&rsquo;on peut encore trop fréquemment lire,  il est tout à fait possible, avec un peu d&rsquo;astuce de définir des indexes sur  les variables tables.</p>
<p><span id="more-5"></span></p>
<h2>  Comment ?</h2>
<p> L&rsquo;astuce en question est de tirer profit de la possibilité de  définir pour un ou plusieurs ensembles de colonnes une contrainte d&rsquo;unicité. La  contrainte d&rsquo;unicité que ce soit pour des variables tables, des tables  temporaires ou des tables normales provoque la construction d&rsquo;un index dont les  colonnes sont ordonnées dans le même ordre que celui présent dans la définition  de la contrainte (ceci est important).<br />
Illustrons cela par un exemple :</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">DECLARE @Mapping TABLE ( <br />
&nbsp; special BIT <br />
&nbsp; , data1 VARCHAR(MAX) <br />
&nbsp; , data2 VARCHAR(MAX) <br />
&nbsp; <br />
&nbsp; , ID INT IDENTITY <br />
&nbsp; , UNIQUE (special, ID) <br />
)</div></div>

</pre>
<p> Dans cet exemple, la  contrainte d&rsquo;unicité va causer la création d&rsquo;un indexe [special, ID] (et en  aucun cas [ID, special] qui serait pourtant forcément tout aussi unique). L&rsquo;indexe  ainsi crée, permettra de facilement faire des queries sur cette variable table  en en filtrant le résultat selon la valeure du champ « special ».</p>
<h2> L&rsquo;unicité :</h2>
<p> Bien sûr avant de définir une  contrainte d&rsquo;unicité il faut être certain de pouvoir la respecter, aussi dans  vos tables temporaires, il n&rsquo;existe pas toujours un combinaison de colonnes (comprenant  celles pour lesquelles vous souhaitez construire un indexe) qui puissent  respecter l&rsquo;unicité. Sauf que rien ne vous empêche de rajouter un colonne supplémentaire  qui fera apparaître une telle combinaison. Et cela est d&rsquo;une simplicité  enfantine puisque, comme vous l&rsquo;aviez peut-être déjà constaté dans l&rsquo;exemple,  il suffit de rajouter une colonne (numérique) autoincrémenté à votre variable  table dont la présence dans n&rsquo;importe quelle combinaison de colonnes, garantira  que cette combinaison respectera l&rsquo;unicité (puisque cette colonne a elle seule la  garanti déjà).</p>
<h2> Conclusion :</h2>
<p> Pour créer un indexe sur une  table variable, vous devez définir que les ensembles ordonnées des colonnes qui  composent ces indexes ont des valeurs uniques et pour permettre cela, vous  pouvez rajouter une colonne autoincrémentée qui terminera la définition de  chacune de vos contrainte d&rsquo;unicité.</p>
<pre><code class="codecolorer text default"><span class="text">UNIQUE ([colonne 1], [colonne &nbsp;2], …, [colonne n], [Auto ID])</span></code></pre>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
