<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Italian Premier Center for SQL Server</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:31:12 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>SQL 2012 - discontinuità nella generazione dei valori associati alla proprietà IDENTITY</title>
      <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/sql-2012-discontinuit-nella-generazione-dei-valori-associati-alla-propriet-identity</link>
      <pubDate>Tue, 29 Jul 2014 02:42:28 GMT</pubDate>
      <dc:creator><![CDATA[Italian Premier Center for SQL Server]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/italian_premier_center_for_sql_server/2014/07/29/sql-2012-discontinuit-nella-generazione-dei-valori-associati-alla-propriet-identity/</guid>
      <description><![CDATA[Recentemente mi &egrave; capitato di lavorare presso due differenti clienti che avevano un problema...]]></description>
      <content:encoded><![CDATA[<p>Recentemente mi &egrave; capitato di lavorare presso due differenti clienti che avevano un problema simile. Tale problema consisteva nel fatto che in alcune situazioni, i valori generati tramite l&rsquo;attributo IDENTITY presentavano delle discontinuit&agrave;. Questo fenomeno &egrave; dovuto ad una differente modalit&agrave; di generazione dei valori da SQL Server 2012 in poi.<br />Nelle versioni precedenti, ad ogni nuovo valore di IDENTITY corrispondeva una scrittura sul transaction log. Dalla versione 2012 il valori IDENTITY vengono generati attraverso un batch, per cui, sul transaction log viene scritto soltanto il valore massimo dell&rsquo;intervallo generato, il resto dei valori sono contenuti in una in-memory cache. Questa differente gestione permette di ridurre il numero e la frequenza di scritture sul transaction log, migliorando la scalabilit&agrave; delle operazioni di inserimento.<br />I gap si possono generare in una delle seguenti situazioni:</p>
<ol>
<li>Il servizio SQL Server viene &ldquo;stoppato&rdquo; con il comando: NET STOP</li>
<li>Il servizio SQL Server viene &ldquo;stoppato&rdquo; tramite SSMS</li>
<li>Il servizio SQL Server &egrave; clustered e si verifica un failover automatico o manuale</li>
<li>In tutte le condizioni in cui il servizio SQL Server viene &ldquo;stoppato&rdquo; senza che prima venga effettuata un operazione di CHECKPOINT</li>
</ol>
<p>Tale comportamento &egrave; documentato nei books online:<br /><a href="https://msdn.microsoft.com/library/ms186775(v=sql.110).aspx">https://msdn.microsoft.com/library/ms186775(v=sql.110).aspx</a><br /><em>&ldquo;The identity property on a column does not guarantee the following:</em></p>
<ul>
<li><em><strong>Uniqueness of the value</strong> &ndash; Uniqueness must be enforced by using a <strong>PRIMARY KEY</strong> or <strong>UNIQUE</strong> constraint or <strong>UNIQUE</strong> index. </em></li>
<li><em><strong>Consecutive values within a transaction</strong> &ndash; A transaction inserting multiple rows is not guaranteed to get consecutive values for the rows because other concurrent inserts might occur on the table. If values must be consecutive then the transaction should use an exclusive lock on the table or use the <strong>SERIALIZABLE</strong> isolation level.</em></li>
<li><span style="background-color:#ffff00;"><em><strong>Consecutive values after server restart or other failures</strong> &ndash;SQL Server might cache identity values for performance reasons and some of the assigned values can be lost during a database failure or server restart. This can result in gaps in the identity value upon insert. If gaps are not acceptable then the application should use a sequence generator with the NOCACHE option or use their own mechanism to generate key values.</em></span></li>
<li><em><strong>Reuse of values</strong> &ndash; For a given identity property with specific seed/increment, the identity values are not reused by the engine. If a particular insert statement fails or if the insert statement is rolled back then the consumed identity values are lost and will not be generated again. This can result in gaps when the subsequent identity values are generated.</em></li>
</ul>
<p><em>These restrictions are part of the design in order to improve performance, and because they are acceptable in many common situations. If you cannot use identity values because of these restrictions, create a separate table holding a current value and manage access to the table and number assignment with your application.&rdquo;</em></p>
<p>Il seguente script riproduce la problematica:</p>
<p><span style="color:#000000;"><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">CREATE TABLE</span> [TestTable] ([C1] <span style="color:#993300;">INT IDENTITY</span>, [C2] <span style="color:#993300;">CHAR</span> (100));</span></strong></span></p>
<p><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;">GO</span></strong></span></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 1&#39;);</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 2&#39;);</span></strong></p>
<p>aprire un command prompt con privilegi elevati (run as administrator)<br /><strong><span style="font-family:&#39;courier new&#39;, courier;">net stop MSSQLSERVER</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;">net start MSSQLSERVER</span></strong></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 3&#39;);</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 4&#39;);</span></strong></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">SELECT</span> * <span style="color:#993300;">FROM</span> [TestTable]</span></strong></p>
<p>Il risultato che si ottiene &egrave; il seguente:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/1.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/1.jpg"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/1.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/1.jpg" border="0" alt=" " /></a></p>
<p>Generalmente la discontinuit&agrave; nei valori dei campi IDENTITY non crea problemi applicativi, a patto che tali campi vengano utilizzati come chiavi surrogate, cio&egrave; i valori non devono avere un significato di bussiness:<br /><a href="https://en.wikipedia.org/wiki/Surrogate_key">https://en.wikipedia.org/wiki/Surrogate_key</a><br />al contrario di quello che succede per le chiavi naturali: <br /><a href="https://en.wikipedia.org/wiki/Natural_key">https://en.wikipedia.org/wiki/Natural_key</a> un tipico esempio di una chiave naturale in letteratura &egrave; il SSN simile al, molto pi&ugrave; nostrano, Codice Fiscale.</p>
<p>Ad essere sinceri anche a me, sull&rsquo;istanza del mio portatile, si sono verificati numerosi gap sugli IDENTITY, probabilmente in corrispondenza di alcuni shutdown non proprio da manuale, che ogni tanto mi capita di fare. Nella figura che segue un esempio:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/2.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/2.jpg"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/2.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/2.jpg" border="0" alt=" " /></a></p>
<p>Nel mio caso la discontinuit&agrave; dei valori non mi ha creato nessun problema perch&eacute; ho usato il campo IDENTITY come chiave surrogata, non mi ero accorto del gap se non dopo parecchio tempo, quando sono andato a modificare dei record direttamente sul DB, perch&eacute; non ho avuto ancora il tempo di implementare la modifica di un determinato valore dalla mia applicazione.</p>
<p>Se al contrario si &egrave; scelto di dare un significato di bussiness, ai valori generati tramite attributo IDENTITY, e un eventuale gap crea un problema, si pu&ograve; utilizzare uno dei seguenti workaround.</p>
<p><strong><span style="font-size:large;">Workaround 1 (retrocompatibilit&agrave;)</span></strong></p>
<p>Utilizzare il trace flag 272 tra gli startup parameters dell&rsquo;istanza. Da notare che la stringa da aggiungere &egrave; &ndash;T272 (la &ldquo;T&rdquo; deve essere uppercase).<br />Questo trace flag forza il SQL Engine a generare gli IDENTITY emulando le versioni pre 2012, cio&egrave; verr&agrave; effettuata una scrittura sul transaction log per ogni valore. <br />L&rsquo;attivazione di questo trace flag potrebbe creare un impatto sulle performances.<br />Il trace flag &egrave; deprecato e nelle prossime versioni potrebbe essere rimosso.<br />Per verificare questo workaround possiamo modificare lo script presentato prima come segue:</p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;background-color:#ffff00;"><span style="color:#993300;">DBCC</span> TRACEON(272, -1)</span></strong><br /><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;background-color:#ffff00;">GO</span></strong></span><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">CREATE TABLE</span> [TestTable] ([C1] <span style="color:#993300;">INT IDENTITY</span>, [C2] <span style="color:#993300;">CHAR</span> (100));</span></strong><br /><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;">GO</span></strong></span></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 1&#39;);</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 2&#39;);</span></strong></p>
<p>aprire un command prompt con privilegi elevati (run as administrator)<br /><strong><span style="font-family:&#39;courier new&#39;, courier;">net stop MSSQLSERVER</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;">net start MSSQLSERVER</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 3&#39;);</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 4&#39;);</span></strong></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">SELECT</span> * <span style="color:#993300;">FROM</span> [TestTable]</span></strong></p>
<p>Il risultato che si ottiene &egrave; il seguente:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3.jpg"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3.jpg" border="0" alt=" " /></a></p>
<p><span style="font-size:large;"><strong>Workaround 2</strong>&nbsp;</span></p>
<p>Effettuare manualmente il commando CHECKPOINT prima di riavviare l&rsquo;istanza o di effettuare un failover. <br />Tale soluzione &egrave; praticabile solo durante le operazioni programmate.<br />Per verificare questo workaround possiamo modificare lo script presentato prima come segue:</p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">CREATE TABLE</span> [TestTable] ([C1] <span style="color:#993300;">INT IDENTITY</span>, [C2] <span style="color:#993300;">CHAR</span> (100));</span></strong><br /><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;">GO</span></strong></span></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 1&#39;);</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 2&#39;);</span></strong></p>
<p><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;background-color:#ffff00;">CHECKPOINT</span></strong></span></p>
<p>apriere un command prompt con privileggi elevati (run as administrator)<br /><strong><span style="font-family:&#39;courier new&#39;, courier;">net stop MSSQLSERVER</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;">net start MSSQLSERVER</span></strong></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 3&#39;);</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] <span style="color:#993300;">VALUES</span> (&#39;Transaction 4&#39;);</span></strong></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">SELECT</span> * <span style="color:#993300;">FROM</span> [TestTable]</span></strong></p>
<p>Il risultato che si ottiene &egrave; il seguente:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3173.3.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3173.3.jpg"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3173.3.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3173.3.jpg" border="0" alt=" " /></a></p>
<p><strong><span style="font-size:large;">Workaround 3 (Sequence)</span></strong></p>
<p>Sostituire l&rsquo;uso dell&rsquo;IDENTITY con una SEQUENCE con l&rsquo;argomento NO CACHE, come descritto nei books online https://msdn.microsoft.com/en-us/library/ff878091.aspx:</p>
<p><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;">CREATE SEQUENCE s1 AS INT </span></strong></span><br /><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;">START WITH 1 </span></strong></span><br /><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;">NO CACHE;</span></strong></span></p>
<p>l&rsquo;uso del NO CACHE avr&agrave; l&rsquo;effetto, come nel caso dell&rsquo;IDENTITY nelle versioni antecedenti a 2012, di produrre una scrittura di un record sul transaction log per ogni valore generato. <span style="background-color:#ffff00;">Questo chiaramente annulla l&rsquo;incremento di performance guadagnato con la generazione &ldquo;a batch&rdquo; delle sequenze di valori.</span><br />A seguire due esempi di utilizzo della SEQUANECE che emulare l&rsquo;IDENTITY:</p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">CREATE TABLE</span> t </span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;">(</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"> Id <span style="color:#993300;">INT PRIMARY KEY DEFAULT NEXT VALUE FOR</span> s1, </span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"> val <span style="color:#993300;">INT NOT NULL </span></span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;">);</span></strong></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> t (val) <span style="color:#993300;">VALUES</span> (2)</span></strong></p>
<p>oppure:</p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">CREATE TABLE</span> t</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;">(</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"> Id <span style="color:#993300;">INT PRIMARY KEY</span>, </span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"> val <span style="color:#993300;">INT NOT NULL</span></span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;">);</span></strong></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> t (id, val) <span style="color:#993300;">VALUES</span> (<span style="color:#993300;">NEXT VALUE FOR</span> s1, 2)</span></strong></p>
<p>Per testare anche questo workaround possiamo modificare il solito script per utilizzare la SEQUENCE:<br /><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;">CREATE SEQUENCE s1 AS INT </span></strong></span><br /><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;">START WITH 1 </span></strong></span><br /><span style="color:#993300;"><strong><span style="font-family:&#39;courier new&#39;, courier;">NO CACHE;</span></strong></span></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">CREATE TABLE</span> [TestTable] ([C1] <span style="color:#993300;">INT</span>, [C2] <span style="color:#993300;">CHAR</span> (100));</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;">GO</span></strong></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] ([C1], [C2]) <span style="color:#993300;">VALUES</span> (<span style="color:#993300;">NEXT VALUE FOR</span> s1, &#39;Transaction 1&#39;)</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] ([C1], [C2]) <span style="color:#993300;">VALUES</span> (<span style="color:#993300;">NEXT VALUE FOR</span> s1, &#39;Transaction 2&#39;)</span></strong></p>
<p>apriere un command prompt con privileggi elevati (run as administrator)<br /><strong><span style="font-family:&#39;courier new&#39;, courier;">net stop MSSQLSERVER</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;">net start MSSQLSERVER</span></strong></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] ([C1], [C2]) <span style="color:#993300;">VALUES</span> (<span style="color:#993300;">NEXT VALUE FOR</span> s1, &#39;Transaction 3&#39;)</span></strong><br /><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">INSERT INTO</span> [TestTable] ([C1], [C2]) <span style="color:#993300;">VALUES</span> (<span style="color:#993300;">NEXT VALUE FOR</span> s1, &#39;Transaction 4&#39;)</span></strong></p>
<p><strong><span style="font-family:&#39;courier new&#39;, courier;"><span style="color:#993300;">SELECT</span> * <span style="color:#993300;">FROM</span> [TestTable]</span></strong></p>
<p>Il risultato ottenuto &egrave; quello corretto:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/7674.3.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/7674.3.jpg" style="font-size:large;"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/7674.3.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/7674.3.jpg" border="0" alt=" " /></a></p>
<p>Come controprova, se per caso, avessimo dimenticato il NO CACHE, avremmo ottenuto un gap (provate a eseguire nuovamente lo script commentando il NO CACHE):</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4.jpg"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4.jpg" border="0" alt=" " /></a></p>
<p><strong>Nota</strong>: nel caso degli IDENTITY e della SEQUENCE otteniamo dei gap di valori differenti, ci&ograve; &egrave; dovuto alle diverse dimensioni del buffer che contengono i valori generati in modalit&agrave; batch.</p>
<p><strong><span style="font-size:large;">Conclusione</span></strong></p>
<p>A causa della struttura degli indici di SQL Server:<br /><a href="https://technet.microsoft.com/en-us/library/ms177443(v=sql.105).aspx">https://technet.microsoft.com/en-us/library/ms177443(v=sql.105).aspx</a><br /><a href="https://technet.microsoft.com/en-us/library/ms177484(v=sql.105).aspx">https://technet.microsoft.com/en-us/library/ms177484(v=sql.105).aspx</a><br />le SEQUENCE o di campi con attributo IDENTITY, sono ottimi candidati per essere usati come primary key clustered questo perch&eacute; permetteranno di avere:</p>
<ul>
<li>row locator sugli indici nonclustered compatti</li>
<li>datatype performanti per le operazioni di join tra tabelle (la join tra tabelle con clausola di ON su campi int o &egrave; molto pi&ugrave; performante della stessa operazione su campi ad esempio varchar(255)).</li>
</ul>
<p>Si suggerisce quindi di progettare le basi dati in modo tale che i valori delle primary key, prodotti con SEQUENCE o tramite l&rsquo;attributo IDENTITY, siano delle chiavi surrogate.<br />Se non fosse possibile cambiare la logica implementata all&rsquo;interno del database si consiglia di utilizzare il workaround 3.<br />Se non fosse possibile nemmeno modificare il codice &egrave; possibile usare il workaround 1.</p>
<p>Marco Giordani</p>
<p><span style="font-size:large;">&nbsp;</span></p>]]></content:encoded>
    </item>
    <item>
      <title>How to set up an Hyper-v Linux (CentOS) server with Microsoft® SQL Server® ODBC Driver</title>
      <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/how-to-set-up-an-hyper-v-linux-centos-server-with-microsoft-sql-server-odbc-driver</link>
      <pubDate>Mon, 30 Jun 2014 08:18:45 GMT</pubDate>
      <dc:creator><![CDATA[Italian Premier Center for SQL Server]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/italian_premier_center_for_sql_server/2014/06/30/how-to-set-up-an-hyper-v-linux-centos-server-with-microsoft-sql-server-odbc-driver/</guid>
      <description><![CDATA[Have you ever tried to query a SQL Server instance from linux? It might be scary for a&nbsp;senior...]]></description>
      <content:encoded><![CDATA[<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Have you ever tried to query a SQL Server instance from linux? It might be scary for a&nbsp;senior Microsoft DBA. Even if you just want to play with it a bit the&nbsp;you might&nbsp;lose&nbsp;yourself&nbsp;in the Linux inner workings. For this reason I&#39;ve put together a simple how-to guide that should ease the pain of the initial&nbsp;configuration&nbsp;of SQL Server ODBC Driver for Linux. At the end of this guide you will have a working CentOS installation capable of querying SQL Server via ODBC: this means <em>any</em> ODBC client will work (yes, including the all-powerful&nbsp;sqlcmd!). Note this guide is not meant to represent a production installation procedure: it&#39;s meant to be simple (an, thus, insecure!) to give DBAs a Linux&nbsp;playground :). If you want to dig deeper (and you should!) please refer to:</span></p>
<ul>
<li style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">[TechNet] Welcome to the Microsoft ODBC Driver 11 for SQL Server on Linux&nbsp;(<a href="https://technet.microsoft.com/en-us/library/hh568451(v=sql.110).aspx">https://technet.microsoft.com/en-us/library/hh568451(v=sql.110).aspx</a>).</span></li>
</ul>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;"><br /></span><span style="font-family:Calibri;font-size:medium;">While we can use a standard Microsoft Azure image for this I opted for a full blown on premise hyper-v based installation. </span></p>
<p><em><span style="color:#000080;font-family:verdana,geneva;font-size:large;">First step: acquire a linux distribution</span></em></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">For this tutorial we&rsquo;ll use CentOS. You can get the install image from here: </span><a href="https://www.centos.org/"><span style="color:#0563c1;font-family:Calibri;font-size:medium;">https://www.centos.org/</span></a><span style="font-family:Calibri;font-size:medium;"> . </span></p>
<p><span style="color:#000080;"><em><span style="font-family:verdana,geneva;font-size:large;">Second step: install CentOS</span></em></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">I will not go into the details here, just make your Hyper-V settings include a network adapter bound to an external network or a NATed internal network. In this lab I assume the hypervisor hosts the SQL Server instance so we need connectivity between CentOS (virtual) and the hypervisor. Please&nbsp;make sure your firewall-ipsec configuration allows that.&nbsp;I will also assume internet access for the virtualized OS (for upgrades and so on).</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/0434.00.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/0434.00.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/0434.00.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/0434.00.png" border="0" /></a><br /></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">To keep things simple we can pick the CentOS wizard suggestions:</span></p>
<p><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4885.01.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4885.01.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4885.01.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4885.01.png" border="0" /></a></span></p>
<p><span style="font-family:Calibri;font-size:medium;">Pick an hostname:</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/0447.02.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/0447.02.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/0447.02.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/0447.02.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Allow the installer to use all the virtual hard disk space:</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/0068.03.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/0068.03.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/0068.03.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/0068.03.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Installation type &ldquo;minimal&rdquo; would suffice (we don&rsquo;t need a GUI after all) and we can add what&#39;s needed afterwards anyway:</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/8311.04.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/8311.04.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/8311.04.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/8311.04.png" border="0" /></a><br /></span><span style="font-family:Calibri;font-size:medium;">After the installation and the following reboot you need to login as root with your chosen password. </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Note: you should create another user to avoid abusing root. <span style="text-decoration:underline;">This is not shown here</span> for the sake of simplicity. If you&rsquo;re interested take a look at useradd, passwd and visudo. </span></p>
<p><em><span style="color:#000080;font-family:verdana,geneva;font-size:large;">Third step (optional): install Linux Integration Services Version for Hyper-V</span></em></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Get them from here: </span><a href="https://www.microsoft.com/en-us/download/details.aspx?id=34603"><span style="color:#0563c1;font-family:Calibri;font-size:medium;">https://www.microsoft.com/en-us/download/details.aspx?id=34603</span></a><span style="font-family:Calibri;font-size:medium;"> . Since it&rsquo;s an ISO we just need to load it using the <span style="font-family:courier new,courier;">Media-&gt;DVD Drive-&gt;Insert disk&hellip;</span> hyper-v menu:</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3362.05.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3362.05.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3362.05.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3362.05.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">To mount the DVD in CentOS just issue there two commands:</span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">sudo mkdir /mnt/dvd</span></p>
<p><span style="font-family:Calibri;font-size:medium;">and</span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">sudo mount /dev/dvd /mnt/dvd</span></p>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/5556.06.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/5556.06.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/5556.06.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/5556.06.png" border="0" /></a></span></p>
<p><span style="font-family:Calibri;font-size:medium;">(note: if you are root you don&rsquo;t need the sudo command).</span></p>
<p><span style="font-family:Calibri;font-size:medium;">Now you should be able to <span style="font-family:courier new,courier;">cd</span> into <span style="font-family:courier new,courier;">/mnt/dvd </span></span><span style="font-family:Calibri;font-size:medium;">and pick the right version (in my case <span style="font-family:courier new,courier;">RHEL63</span>):</span></p>
<p><span style="font-family:Calibri;font-size:medium;"><span style="font-family:courier new,courier;background-color:#c0c0c0;">cd /mnt/dvd/RHEL63</span><br /></span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/5001.07.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/5001.07.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/5001.07.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/5001.07.png" border="0" /></a><span style="font-family:Calibri;font-size:medium;">Now issue the <span style="font-family:courier new,courier;">install.sh</span> script with </span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">sudo ./install.sh</span></p>
<p><span style="font-family:Calibri;font-size:medium;">And wait. </span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/5415.08.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/5415.08.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/5415.08.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/5415.08.png" border="0" /></a><span style="font-family:Calibri;font-size:medium;">When the installation is over, you have to reboot your CentoOS server:</span><span style="font-family:Calibri;font-size:medium;"><br /></span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">sudo reboot</span></p>
<p><span style="font-size:medium;"><span style="font-family:Calibri;">That&rsquo;s it.&nbsp;Now your CentOS installation should be a better hyper-v guest&nbsp;:)</span><span style="font-family:Calibri;">.</span></span></p>
<p><em><span style="color:#000080;font-family:verdana,geneva;font-size:large;">Fourth step: enable the network connection and get an IP</span></em></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">To enable the internet connection at boot and get a DHCP leased address we need to edit the <span style="font-family:courier new,courier;">/etc/sysconfig/network-scripts/ifcfg-eth0</span> file. To do this we issue a</span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Just edit the file and set <span style="font-family:courier new,courier;background-color:#c0c0c0;">ONBOOT=yes</span> instead of <span style="font-family:courier new,courier;background-color:#c0c0c0;">ONBOOT=no</span>. Make sure that <span style="font-family:courier new,courier;background-color:#c0c0c0;">BOOTPROTO</span> is <span style="font-family:courier new,courier;background-color:#c0c0c0;">dhcp</span> so we&rsquo;ll get an address from the DHCP server.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Note: vi can be awkward if you are used to the&nbsp;easy-yet-powerful Microsoft editors. If you have problems please let me know.<br /></span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6378.09.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6378.09.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6378.09.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6378.09.png" border="0" /></a></p>
<p><span style="font-family:Calibri;font-size:medium;">Now at reboot we should have a valid IP. </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">To test it perform a full system update:</span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">sudo yum update</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/7635.10.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/7635.10.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/7635.10.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/7635.10.png" border="0" /></a></p>
<p><span style="font-family:Calibri;font-size:medium;">While we are at it, install some useful commands:</span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">sudo yum install wget nano tar gcc</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/2727.11.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/2727.11.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/2727.11.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/2727.11.png" border="0" /></a></p>
<p><span style="font-family:Calibri;font-size:medium;">And reboot again.</span></p>
<p><em><span style="color:#000080;font-family:verdana,geneva;font-size:large;">Fifth step: Download and install Microsoft&reg; SQL Server&reg; ODBC Driver 1.0 for Linux</span></em></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Go here and download the package: </span><a href="https://www.microsoft.com/en-us/download/details.aspx?id=28160"><span style="color:#0563c1;font-family:Calibri;font-size:medium;">https://www.microsoft.com/en-us/download/details.aspx?id=28160</span></a><span style="font-family:Calibri;font-size:medium;">.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">For this purpose I&rsquo;ve created a folder in my home directory called <span style="font-family:courier new,courier;">dev</span> an downloaded the package there. You might want to download it using Windows and then upload it using SFTP protocol or just wget it:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/8272.12.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/8272.12.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/8272.12.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/8272.12.png" border="0" /></a><span style="font-family:Calibri;font-size:medium;">Extract it:</span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">tar xvf sqlncli-11.0.1790.0.tar.gz</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6177.13.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6177.13.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6177.13.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6177.13.png" border="0" /></a></p>
<p><span style="font-family:Calibri;font-size:medium;">Now just issue the <span style="font-family:courier new,courier;">./build_dm</span> command:</span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">./build_dm</span></p>
<p style="text-align:justify;"><span style="font-family:courier new,courier;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6710.14.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6710.14.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6710.14.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6710.14.png" border="0" /></a><br /></span><span style="font-family:Calibri;font-size:medium;">And follow the on-screen instructions.</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4747.15.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4747.15.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4747.15.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4747.15.png" border="0" /></a><span style="font-family:Calibri;font-size:medium;"></span></p>
<p style="text-align:left;"><span style="font-family:Calibri;font-size:medium;">As you can see we still need to install the driver with:</span></p>
<p><span style="font-family:Calibri;font-size:medium;"><span style="font-family:courier new,courier;background-color:#c0c0c0;">cd /tmp/unixODBC.24884.23543.20110/unixODBC-2.3.0</span> (your path <span style="text-decoration:underline;"><strong>will be</strong></span> different!)</span></p>
<p><span style="font-family:Calibri;font-size:medium;">and then<br /></span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">sudo make install</span></p>
<p><span style="font-family:courier new,courier;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/8345.16.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/8345.16.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/8345.16.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/8345.16.png" border="0" /></a><br /></span><span style="font-family:Calibri;font-size:medium;">As last thing to do we should go back to our <span style="font-family:courier new,courier;">dev</span> folder:</span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">cd ~/dev/sqlncli-11.0.1790.0</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/8562.17.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/8562.17.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/8562.17.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/8562.17.png" border="0" /></a></p>
<p><span style="font-family:Calibri;font-size:medium;">And issue a <span style="font-family:courier new,courier;">sudo ./install.sh install</span> command:</span></p>
<p><span style="font-family:Calibri;font-size:medium;"><span style="font-family:courier new,courier;background-color:#c0c0c0;">sudo ./install.sh install</span><br /></span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6431.18.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6431.18.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6431.18.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6431.18.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">And we are done!</span></p>
<p><em><span style="color:#000080;font-family:verdana,geneva;font-size:large;">Sixth step: connect to SQL!</span></em></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Now we can use the well known sqlcmd utility to query our database. In this lab I&rsquo;ll use SQL authentication but know that Kerberos authentication is supported too. </span></p>
<p><span style="font-family:Calibri;font-size:medium;">To connect to my SQL instance (default with port 1433) all I need is:</span></p>
<p><span style="font-family:courier new,courier;font-size:medium;background-color:#c0c0c0;">sqlcmd &ndash;s myserver &ndash;U username &ndash;P password</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4113.19.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4113.19.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4113.19.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4113.19.png" border="0" /></a></p>
<p><span style="font-family:Calibri;font-size:medium;">Now I can issue a very common TSQL statement and check it:</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">SELECT</span> name <span style="color:#800000;font-weight:bold;">FROM</span> <span style="color:#bb7977;font-weight:bold;">sys</span><span style="color:#808030;">.</span>databases
</pre>
</div>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/7651.20.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/7651.20.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/7651.20.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/7651.20.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">We succeeded querying a SQL Server database from a brand new hyper-v hosted CentOS virtual server!</span></p>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;</span></p>
<p><strong><span style="font-family:Calibri;font-size:medium;">Happy coding,</span></strong></p>
<p><strong><span style="font-family:Calibri;font-size:medium;"><a title="Francesco Cogno" href="mailto:Francesco.Cogno@microsoft.com">Francesco Cogno</a></span></strong></p>
<p></p>]]></content:encoded>
    </item>
    <item>
      <title>Time normalization: a SQL CLR approach to address unevenly-spaced data samples</title>
      <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/time-normalization-a-sql-clr-approach-to-address-unevenly-spaced-data-samples</link>
      <pubDate>Thu, 05 Jun 2014 07:43:00 GMT</pubDate>
      <dc:creator><![CDATA[Italian Premier Center for SQL Server]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/italian_premier_center_for_sql_server/2014/06/05/time-normalization-a-sql-clr-approach-to-address-unevenly-spaced-data-samples/</guid>
      <description><![CDATA[One very common challenge in the IT department is to represent time driven data. Think about...]]></description>
      <content:encoded><![CDATA[<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">One very common challenge in the IT department is to represent time driven data. Think about performance counter values, weather data or, more simply, your own weight tracking. This kind of data is taken in samples: each sample is defined by the collection time. When we try to visualize the data, we often need to make sure the time scale is linear and homogeneous. In other terms we want each sample to be equidistant from the previous and the following one. This is what we expect (although there are different scales we will talk about linear here) most of the time. While the representation is expected to be linear in time, the samples may be not: this causes problems when we want to represent the data visually.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Let&rsquo;s talk about a simple example: the wind speed measurement. Suppose we have a telemetry telling us the actual speed of the wind. The data will be roughly like this:</span></p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/00.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/00.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/00.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/00.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Notice that we have 11 equidistantiated samples (one each second). This will translate very well in a graph:</span></p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/01.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/01.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/01.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/01.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Looking at the graph, you can clearly see that there was a spike lasting two seconds. Otherwise the value is more or less constant.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Now we suppose we lose the connection for 2 minutes with the telemetry and we lose data. When the connection is restored we receive another 8 samples:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/02.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/02.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/02.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/02.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">The graph becomes this one:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/03.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/03.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/03.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/03.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">&nbsp;</span><span style="font-family:Calibri;font-size:medium;">You see the problem here? Even though the legend shows the correct time, just looking at the graph we might not be aware of the data loss. Even worse, we might think that between the two spikes there were only few seconds. This is <span style="text-decoration:underline;">not</span> good:</span></p>
<p style="text-align:justify;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/04.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/04.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/04.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/04.png" border="0" /></a><span style="font-family:Calibri;font-size:medium;">What should we do? There is no right answer; generally I tend to keep the last value until a new one is available. This creates a flat line: it&rsquo;s clear that something went wrong. It is also clear that minutes passed between a spike and the other:</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/05.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/05.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/05.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/05.png" border="0" /></a></p>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Now let&rsquo;s go back to the original dataset:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/06.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/06.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/06.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/06.png" border="0" /></a><span style="font-family:Calibri;font-size:medium;">This time we receive a flood of data (more than one each second):</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/07.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/07.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/07.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/07.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">&nbsp;</span><span style="font-family:Calibri;font-size:medium;">This leads to this misleading graph:</span></p>
<p style="text-align:center;"><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/08.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/08.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/08.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/08.png" border="0" /></a><br /></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">We seem to have a huge spike lasting very long! The problem here is &ndash; again &ndash; that the time scale is not linear:</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/09.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/09.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/09.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/09.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">What can we do in this case? I tend to suggest using the weighted average: this is mathematically correct even though this may cause loss of information. The graph with the linear time will be:</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/10.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/10.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/10.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/10.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Aside of having a lower spike, it&rsquo;s also evident that the spike lasted just a few seconds. </span></p>
<p><span style="font-family:Calibri;font-size:medium;">A more formal definition of what I&rsquo;ve done here is kindly given by a contributor who wished to remain anonymous:</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/11.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/11.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/11.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/11.png" border="0" /></a><br /></span><span style="font-family:Calibri;font-size:medium;">Just to explain a little, consider this simplified example. Given a linear time axis:</span></p>
<p style="text-align:center;"><span style="font-family:Calibri;font-size:medium;">&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/12.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/12.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/12.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/12.png" border="0" /></a></span></p>
<p align="center" style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">We add two samples at&nbsp;<em>Cp(0)</em></span>&nbsp;<span style="font-size:medium;"><span style="font-family:Calibri;">&nbsp;and at <em>Cp(1)</em></span></span><span style="font-family:Calibri;font-size:medium;">. The values are&nbsp;<em>f(Cp(0))</em><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/15.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/15.png"></a> </span><span style="font-size:medium;"><span style="font-family:Calibri;">and&nbsp;<em>f(Cp(1))</em></span></span><span style="font-family:Calibri;font-size:medium;">. The goal here is to get the value at each <em>x(i)</em>.</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/17.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/17.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/17.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/17.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">The first sample is exactly at the <em>x(0)</em></span> <span style="font-family:Calibri;font-size:medium;">. </span><span style="font-family:Calibri;font-size:medium;">This means that </span></p>
<p><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/18.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/18.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/18.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/18.png" border="0" /></a></span> <span style="font-family:Calibri;font-size:medium;">. </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">That&rsquo;s easy. </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Now since we don&rsquo;t have samples between <em>x(0)</em> and <em>x(1)</em> we choose <i>maintain</i> the same value. </span></p>
<p><span style="font-family:Calibri;font-size:medium;">This means that</span></p>
<p style="text-align:justify;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/19.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/19.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/19.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/19.png" border="0" /></a><span style="font-family:Calibri;font-size:medium;">.&nbsp; </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">In other words we are weighting the value for relative weight in the interval:</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/20.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/20.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/20.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/20.png" border="0" /></a></span><span style="font-family:Calibri;font-size:medium;">. </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Of course since&nbsp; <em>x(1)-x(0)</em> is our <em>deltaT</em>, </span><span style="font-family:Calibri;font-size:medium;">we have:</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/21.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/21.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/21.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/21.png" border="0" /></a>.<br /></span></p>
<p style="text-align:center;"><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/22.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/22.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/22.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/22.png" border="0" /></a><br /></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">&nbsp;</span><span style="font-family:Calibri;font-size:medium;">Now, we add another sample <em>Cp(2)</em>. This sample is after <em>x(2)</em> but before <em>x(3)</em>.</span></p>
<p style="text-align:center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/23.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/23.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/23.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/23.png" border="0" /></a></p>
<p><span style="font-family:Calibri;font-size:medium;">What will be the value of <em>f(x(2))</em>?</span></p>
<p><span style="font-family:Calibri;font-size:medium;">It will be the value of <em>f(x(1))</em> until a new sample is found (<em>Cp(1)</em>). From that on will be <em>f(Cp(1))</em>. To even things out we just need to weight the values for their duration:</span></p>
<p><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/24.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/24.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/24.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/24.png" border="0" /></a><br /></span></p>
<p style="text-align:center;"><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/25.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/25.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/25.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/25.png" border="0" /></a><br /></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Wow. Notice that since:&nbsp;</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/26.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/26.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/26.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/26.png" border="0" /></a></span><span style="font-family:Calibri;"><span style="font-size:medium;">we can write the function this way:</span></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;"><span style="font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/27.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/27.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/27.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/27.png" border="0" /></a>.<br /></span></span><span style="font-family:Calibri;"><span style="font-size:medium;">This is the same as:</span></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;"><span style="font-size:medium;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/28.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/28.png"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/28.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/28.png" border="0" /></a></span></span><span style="font-family:Calibri;font-size:medium;">.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">See what we are getting to? I will not cover here the other scenarios because I think you got the hang of it. The algorithm here is easy: for each period calculate the weighted average of its samples (taking account of the previous sample if need be). The code is very easy indeed:</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">public</span> List<span style="color:#808030;">&lt;</span>DateValuePair<span style="color:#808030;">&gt;</span> Push<span style="color:#808030;">(</span>DateValuePair dvp<span style="color:#808030;">)</span>
        <span style="color:#800080;">{</span>
            List<span style="color:#808030;">&lt;</span>DateValuePair<span style="color:#808030;">&gt;</span> lDVPs <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">new</span> List<span style="color:#808030;">&lt;</span>DateValuePair<span style="color:#808030;">&gt;</span><span style="color:#808030;">(</span><span style="color:#808030;">)</span><span style="color:#800080;">;</span>

            <span style="color:#800000;font-weight:bold;">if</span> <span style="color:#808030;">(</span>fFirst<span style="color:#808030;">)</span>
            <span style="color:#800080;">{</span>
                Start<span style="color:#808030;">(</span>dvp<span style="color:#808030;">)</span><span style="color:#800080;">;</span>

                <span style="color:#696969;">// Add itself as first event</span>
                lDVPs<span style="color:#808030;">.</span>Add<span style="color:#808030;">(</span>dvp<span style="color:#808030;">)</span><span style="color:#800080;">;</span>

                <span style="color:#800000;font-weight:bold;">return</span> lDVPs<span style="color:#800080;">;</span>
            <span style="color:#800080;">}</span>

            DateTime NextStep <span style="color:#808030;">=</span> CurrentStep<span style="color:#808030;">.</span>Add<span style="color:#808030;">(</span>Step<span style="color:#808030;">)</span><span style="color:#800080;">;</span>

            <span style="color:#800000;font-weight:bold;">while</span> <span style="color:#808030;">(</span>dvp<span style="color:#808030;">.</span>Date <span style="color:#808030;">&gt;</span><span style="color:#808030;">=</span> NextStep<span style="color:#808030;">)</span>
            <span style="color:#800080;">{</span>
                <span style="color:#800000;font-weight:bold;">double</span> dUsedMS <span style="color:#808030;">=</span> Math<span style="color:#808030;">.</span>Min<span style="color:#808030;">(</span><span style="color:#808030;">(</span>NextStep <span style="color:#808030;">-</span> CurrentTime<span style="color:#808030;">)</span><span style="color:#808030;">.</span>TotalMilliseconds<span style="color:#808030;">,</span> <span style="color:#008c00;">1000</span><span style="color:#808030;">)</span><span style="color:#800080;">;</span>
                AccumulatedValue <span style="color:#808030;">+</span><span style="color:#808030;">=</span> <span style="color:#808030;">(</span>dUsedMS <span style="color:#808030;">*</span> Current<span style="color:#808030;">.</span>Value<span style="color:#808030;">)</span> <span style="color:#808030;">/</span> <span style="color:#008000;">1000.</span>0D<span style="color:#800080;">;</span>
                lDVPs<span style="color:#808030;">.</span>Add<span style="color:#808030;">(</span><span style="color:#800000;font-weight:bold;">new</span> DateValuePair<span style="color:#808030;">(</span><span style="color:#808030;">-</span><span style="color:#008c00;">1</span><span style="color:#808030;">)</span> <span style="color:#800080;">{</span> Date <span style="color:#808030;">=</span> NextStep<span style="color:#808030;">,</span> Value <span style="color:#808030;">=</span> AccumulatedValue <span style="color:#800080;">}</span><span style="color:#808030;">)</span><span style="color:#800080;">;</span>
                AccumulatedValue <span style="color:#808030;">=</span> <span style="color:#008c00;">0</span><span style="color:#800080;">;</span>

                CurrentStep <span style="color:#808030;">=</span> NextStep<span style="color:#800080;">;</span>
                CurrentTime <span style="color:#808030;">=</span> NextStep<span style="color:#800080;">;</span>
                NextStep <span style="color:#808030;">=</span> NextStep<span style="color:#808030;">.</span>Add<span style="color:#808030;">(</span>Step<span style="color:#808030;">)</span><span style="color:#800080;">;</span>
            <span style="color:#800080;">}</span>

            <span style="color:#800000;font-weight:bold;">double</span> dRemainining <span style="color:#808030;">=</span> Math<span style="color:#808030;">.</span>Min<span style="color:#808030;">(</span><span style="color:#808030;">(</span>dvp<span style="color:#808030;">.</span>Date <span style="color:#808030;">-</span> CurrentTime<span style="color:#808030;">)</span><span style="color:#808030;">.</span>TotalMilliseconds<span style="color:#808030;">,</span> <span style="color:#008c00;">1000</span><span style="color:#808030;">)</span><span style="color:#800080;">;</span>
            AccumulatedValue <span style="color:#808030;">+</span><span style="color:#808030;">=</span> <span style="color:#808030;">(</span>dRemainining <span style="color:#808030;">*</span> Current<span style="color:#808030;">.</span>Value<span style="color:#808030;">)</span> <span style="color:#808030;">/</span> <span style="color:#008000;">1000.</span>0D<span style="color:#800080;">;</span>
            CurrentTime <span style="color:#808030;">=</span> dvp<span style="color:#808030;">.</span>Date<span style="color:#800080;">;</span>

            Current <span style="color:#808030;">=</span> dvp<span style="color:#800080;">;</span>

            <span style="color:#800000;font-weight:bold;">return</span> lDVPs<span style="color:#800080;">;</span>
        <span style="color:#800080;">}</span>
</pre>
</div>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">We expose a method to be called for each sample. Notice that for each call we may receive an arbitrary number of results. This is expected as we cannot know in advance how many time frames have passed between a sample and the next one. </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">The algorithm revolves around an <i>accumulator </i>(called AccumulatedValue) that holds the weighted partial value for a given interval. As you can see, I am arbitrarily setting the </span> <span style="font-family:Calibri;"><span style="font-size:medium;">&nbsp;to 1 millisecond: this should be enough for most scenarios but feel free to change if you need. With the accumulator in place it&rsquo;s just a matter of looping through the samples until you complete an interval.&nbsp; </span></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Our last task is to expose the method via T-SQL. There are many ways of doing this but given the limitation of SQLCLR dataset passing I opted for using the context connection (see </span><a href="https://msdn.microsoft.com/en-us/library/ms131053.aspx"><span style="color:#0563c1;font-family:Calibri;font-size:medium;">https://msdn.microsoft.com/en-us/library/ms131053.aspx</span></a><span style="font-family:Calibri;font-size:medium;">). This is not elegant at all but gets the job done. If you think of a better approach please let me know.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">The definition is:</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">CREATE</span> <span style="color:#800000;font-weight:bold;">FUNCTION</span> <span style="color:#808030;">[</span>Normalization<span style="color:#808030;">]</span><span style="color:#808030;">.</span>TimeNormalize<span style="color:#808030;">(</span><span style="color:#797997;">@statement</span> NVARCHAR<span style="color:#808030;">(</span><span style="color:#bb7977;font-weight:bold;">MAX</span><span style="color:#808030;">)</span><span style="color:#808030;">,</span> <span style="color:#797997;">@days</span> <span style="color:#800000;font-weight:bold;">INT</span><span style="color:#808030;">,</span> <span style="color:#797997;">@hours</span> <span style="color:#800000;font-weight:bold;">INT</span><span style="color:#808030;">,</span> <span style="color:#797997;">@minutes</span> <span style="color:#800000;font-weight:bold;">INT</span><span style="color:#808030;">,</span> <span style="color:#797997;">@seconds</span> <span style="color:#800000;font-weight:bold;">INT</span><span style="color:#808030;">,</span> <span style="color:#797997;">@milliseconds</span> <span style="color:#800000;font-weight:bold;">INT</span><span style="color:#808030;">)</span>
<span style="color:#800000;font-weight:bold;">RETURNS</span> <span style="color:#800000;font-weight:bold;">TABLE</span><span style="color:#808030;">(</span>
	<span style="color:#808030;">[</span>EventTime<span style="color:#808030;">]</span>			DATETIME<span style="color:#808030;">,</span>
	<span style="color:#808030;">[</span>NormalizedValue<span style="color:#808030;">]</span>	<span style="color:#800000;font-weight:bold;">FLOAT</span>
<span style="color:#808030;">)</span> 
<span style="color:#800000;font-weight:bold;">AS</span> <span style="color:#800000;font-weight:bold;">EXTERNAL</span> NAME <span style="color:#808030;">[</span>ITPCfSQL<span style="color:#808030;">.</span>Azure<span style="color:#808030;">.</span>CLR<span style="color:#808030;">]</span><span style="color:#808030;">.</span><span style="color:#808030;">[</span>ITPCfSQL<span style="color:#808030;">.</span>Azure<span style="color:#808030;">.</span>CLR<span style="color:#808030;">.</span>TimeNormalization<span style="color:#808030;">.</span>TimeNormalizer<span style="color:#808030;">]</span><span style="color:#808030;">.</span>TimeNormalize<span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">GO</span>
</pre>
</div>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">As you can see, we should pass this SP the TSQL statement that will produce the dataset to normalize. The dataset must have two columns, the first one being a DATETIME and the second a number. The other parameters specify the time interval used for the normalization. You can go as low as one millisecond (as explained above).</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;"></span><span style="font-family:Calibri;"><span style="font-size:medium;">Let&rsquo;s try a demo. First we create a staging table:</span></span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">CREATE</span> <span style="color:#800000;font-weight:bold;">TABLE</span> tbl<span style="color:#808030;">(</span>Evt DATETIME<span style="color:#808030;">,</span> Val <span style="color:#800000;font-weight:bold;">FLOAT</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
</pre>
</div>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;</span><span style="font-family:Calibri;font-size:medium;">And we put some events in it. The events are hardly evenly spaced:</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:10.000&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">0</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:10.123&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">230</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:10.145&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">244</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:10.153&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">240</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:10.165&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">248</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:10.175&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">246</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:10.215&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">100</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:10.218&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">14</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:11.218&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">13</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:12.218&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">13</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:13.218&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">13</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
</pre>
</div>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Now let&rsquo;s see our data with the linearized timescale (using our algorithm):</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">SELECT</span> <span style="color:#808030;">*</span> <span style="color:#800000;font-weight:bold;">FROM</span> tbl<span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">SELECT</span> <span style="color:#808030;">*</span> <span style="color:#800000;font-weight:bold;">FROM</span> <span style="color:#808030;">[</span>Normalization<span style="color:#808030;">]</span><span style="color:#808030;">.</span>TimeNormalize<span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;SELECT * FROM tbl&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">0</span><span style="color:#808030;">,</span> <span style="color:#008c00;">0</span><span style="color:#808030;">,</span><span style="color:#008c00;">0</span><span style="color:#808030;">,</span><span style="color:#008c00;">1</span><span style="color:#808030;">,</span><span style="color:#008c00;">0</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
</pre>
</div>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">This gives us:</span></p>
<p style="text-align:justify;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/29.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/29.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/29.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/29.png" border="0" /></a><span style="font-family:Calibri;font-size:medium;">Notice here a how the same starting <i>information </i>we are getting two different graphs: the first one is clearly misleading (look at the scale: it goes up to 500!), the second is much easier to understand. Don&rsquo;t misunderstand me here: I&rsquo;m not saying that the first graph is wrong. It is not. It&rsquo;s just misleading because we expect the graph to have linear axis. </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Last demo. Let&rsquo;s simulate a connection loss. To do so, we just skip some time in our last sample:</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">TRUNCATE</span> <span style="color:#800000;font-weight:bold;">TABLE</span> tbl<span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:00:10&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">14</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:02:11&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">13</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:02:12&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">14</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:02:13&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">14</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:02:14&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">13</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:02:15&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">33</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:02:16&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">7</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:02:17&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">33</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:02:18&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">30</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">INSERT</span> <span style="color:#800000;font-weight:bold;">INTO</span> tbl<span style="color:#808030;">(</span>Evt<span style="color:#808030;">,</span> Val<span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">VALUES</span><span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;20140101 17:14:17&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">14</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">SELECT</span> <span style="color:#808030;">*</span> <span style="color:#800000;font-weight:bold;">FROM</span> tbl<span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">SELECT</span> <span style="color:#808030;">*</span> <span style="color:#800000;font-weight:bold;">FROM</span> <span style="color:#808030;">[</span>Normalization<span style="color:#808030;">]</span><span style="color:#808030;">.</span>TimeNormalize<span style="color:#808030;">(</span><span style="color:#0000e6;">&#39;SELECT * FROM tbl&#39;</span><span style="color:#808030;">,</span> <span style="color:#008c00;">0</span><span style="color:#808030;">,</span> <span style="color:#008c00;">0</span><span style="color:#808030;">,</span><span style="color:#008c00;">0</span><span style="color:#808030;">,</span><span style="color:#008c00;">1</span><span style="color:#808030;">,</span><span style="color:#008c00;">0</span><span style="color:#808030;">)</span><span style="color:#808030;">;</span>
</pre>
</div>
<p><span style="font-family:Calibri;font-size:medium;">This is the result (notice I&rsquo;ve blurred the normalized values just because they are too many):</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/30.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/30.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/30.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/30.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">The two graphs are once again very different.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">Long story short: just because a graph is correct don&rsquo;t assume the viewer will interpret it in the right way. Sometimes it&rsquo;s best to help him a little, even if that means blending information.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:medium;">PS: I&rsquo;ve almost forgot to mention: you will find the method (along with the stored procedure) for free in the Microsoft SQL Server To Windows Azure helper library (</span><a href="https://sqlservertoazure.codeplex.com/"><span style="color:#0563c1;font-family:Calibri;font-size:medium;">https://sqlservertoazure.codeplex.com/</span></a><span style="font-family:Calibri;font-size:medium;">) open source library.</span></p>
<p><span style="font-family:Calibri;font-size:medium;">&nbsp;</span></p>
<p><span style="font-family:Calibri;font-size:medium;">Happy Coding,</span></p>
<p><strong><span style="font-family:Calibri;font-size:medium;"><a title="Francesco Cogno" href="mailto:Francesco.Cogno@microsoft.com">Francesco Cogno</a></span></strong></p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server 2014 and Windows Azure Blob Storage Service: Better Together</title>
      <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/sql-server-2014-and-windows-azure-blob-storage-service-better-together</link>
      <pubDate>Wed, 16 Apr 2014 03:05:45 GMT</pubDate>
      <dc:creator><![CDATA[Italian Premier Center for SQL Server]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/italian_premier_center_for_sql_server/2014/04/16/sql-server-2014-and-windows-azure-blob-storage-service-better-together/</guid>
      <description><![CDATA[Just a quick post to point you to this new SQL Server 2014 whitepaper: SQL Server 2014 and Windows...]]></description>
      <content:encoded><![CDATA[<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Just a quick post to point you to this new SQL Server 2014 whitepaper: <span lang="EN"><a href="https://download.microsoft.com/download/D/2/0/D20E1C5F-72EA-4505-9F26-FEF9550EFD44/SQL%20Server%202014%20and%20Windows%20Azure%20Blob%20Storage%20Service%20-%20Better%20Together.docx"><strong><span style="color:#0563c1;">SQL Server 2014 and Windows Azure Blob Storage Service: Better Together.</span></strong></a> You will find many</span>&nbsp;interesting best practices and a WSFC-like framework.<br /></span><span style="font-family:trebuchet ms,geneva;font-size:small;"><strong></strong></span></p>
<p style="text-align:justify;margin-left:30px;"><span style="font-family:trebuchet ms,geneva;font-size:small;"><strong><span style="font-size:medium;">Summary:</span><br /></strong></span></p>
<p style="text-align:justify;margin-left:30px;"><span style="font-family:trebuchet ms,geneva;font-size:small;"><span lang="EN">SQL Server 2014 introduces significant new features toward a deeper integration with Microsoft Azure, thus unlocking new scenarios and provide more flexibility in the database space for IaaS data models. This technical article will cover in depth SQL Server 2014 Data Files on Azure Blob storage service, starting from step-by-step configuration, then providing guidance on scenarios, benefits and limitations, best practices and lessons learned from early testing and adoption. Additionally, a fully featured example of a new (Windows Server Failover Clustering) - like feature will be introduced to demonstrate the power of Microsoft Azure and SQL Server 2014 when combined together.</span>&nbsp;</span></p>
<p style="text-align:justify;"></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Happy coding,<br /></span></p>
<p style="text-align:justify;"><span style="font-family:&#39;Calibri&#39;,&#39;sans-serif&#39;;font-size:11pt;"><span style="font-family:verdana,geneva;font-size:small;"><a title="Francesco Cogno" href="mailto:Francesco.Cogno@microsoft.com">Francesco Cogno</a></span><br /></span></p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server 2014 Dynamic-link library load</title>
      <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/sql-server-2014-dynamic-link-library-load</link>
      <pubDate>Fri, 04 Apr 2014 06:47:14 GMT</pubDate>
      <dc:creator><![CDATA[Italian Premier Center for SQL Server]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/italian_premier_center_for_sql_server/2014/04/04/sql-server-2014-dynamic-link-library-load/</guid>
      <description><![CDATA[Have you ever wondered how SQL Server 2014 accomplishes the &ldquo;Native compilation&rdquo;...]]></description>
      <content:encoded><![CDATA[<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Have you ever wondered how SQL Server 2014 accomplishes the &ldquo;Native compilation&rdquo; feature? In this post I&rsquo;ll show you how to inspect what SQL Server is doing behind the scenes while &ldquo;compiling&rdquo; your native code. This will be a deep post that will require a <span style="text-decoration:underline;">non production</span> instance since we will restart it many times.</span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">In order to inspect sqlservr.exe we will use a powerful tool called Dependency Walker. You can find it in many Microsoft distribution kits; the author, however, keeps an update page with the latest binaries: you can get them here: <a href="https://dependencywalker.com/"><span style="color:#0563c1;">https://dependencywalker.com/</span></a>. </span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Dependency walker allows you &ndash; among other things - to inspect dynamic DLL handling by user code. That is exactly what SQL Server is doing when loading your native compiled code into its own address space. </span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">SQL Server will perform these tasks:</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/ddl%20process.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/ddl-process.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/ddl%20process.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/ddl-process.png" border="0" /></a></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">For each natively compiled entity. Note that is just an oversimplification meant to show what happens in that specific moment. There is a lot more involved before (Mixed Abstract Trees, Pure Imperative Trees, etc&hellip;) and afterwards of course.</span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">First, we need to start dependency walker and ask it to open the main SQL Server executable. If you have trouble finding the right exe you can use the SQL Configuration Manager:</span></p>
<p style="text-align:center;"><span style="font-family:verdana,geneva;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/dep%20open%20sql.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/dep-open-sql.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/dep%20open%20sql.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/dep-open-sql.jpg" border="0" /></a><br /></span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Once open Dependency walker will show you the module linked by the executable. You will find the familiar DLLs here:</span></p>
<p><span style="font-family:verdana,geneva;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/dw%20sqlserver.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/dw-sqlserver.jpg"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/dw%20sqlserver.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/dw-sqlserver.jpg" border="0" /></a></span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">This is, however, the static representation of sqlservr.exe. Dependency walker is able to inspect a running instance of that executable much like a debugger does. This is very helpful since we want to show what happens during a native compilation. </span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Select Start profile from Profile menu:</span></p>
<p style="text-align:center;"><span style="font-family:verdana,geneva;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/dw%20start%20profile.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/dw-start-profile.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/dw%20start%20profile.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/dw-start-profile.jpg" border="0" /></a><br /></span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">As you can see we are starting sqlservr.exe from scratch. You will need to shut down the running instance first (there cannot be two instances owning the same files) and copy the relevant parameters from the configuration manager. If you want more details on how to start SQL Server from command line please refer here: <a href="https://technet.microsoft.com/en-US/library/ms180965(v=SQL.105).aspx"><span style="color:#0563c1;">https://technet.microsoft.com/en-US/library/ms180965(v=SQL.105).aspx</span></a>. </span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">You will see the console popping out: just wait for SQL Server to finish its initialization (note: if you already have many natively compiled entities the startup will take a while; this is normal and the reason of if should become clear in a moment).</span></p>
<p><span style="font-family:verdana,geneva;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/sql%20server%20started%20by%20dw.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/sql-server-started-by-dw.jpg"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/sql%20server%20started%20by%20dw.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/sql-server-started-by-dw.jpg" border="0" /></a></span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Before proceding further let&rsquo;s look at the Window menu of Dependency Walker:</span></p>
<p style="text-align:center;"><span style="font-family:verdana,geneva;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/de%20clear%20log%20window.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/de-clear-log-window.jpg"></a><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/sql%20and%20conhost.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/sql-and-conhost.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/sql%20and%20conhost.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/sql-and-conhost.jpg" border="0" /></a><br /></span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Notice that SQL Server has spawned another process during its startup: CONHOST.exe. DW will show the latest process spawned as default so we need to select sqlservr.exe back before proceeding further.</span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">If you want you can clear the <span style="font-family:Verdana;font-size:small;">Dependency Walker</span>&rsquo;s log window now:</span></p>
<p><span style="font-family:verdana,geneva;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/de%20clear%20log%20window.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/de-clear-log-window.jpg"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/de%20clear%20log%20window.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/de-clear-log-window.jpg" border="0" /></a>Now that our instance is running and Dependency Walker is actively monitoring it we can create a demo database on it (we can use SSMS, sqlcmd, whatever you like):</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">CREATE</span> <span style="color:#800000;font-weight:bold;">DATABASE</span> <span style="color:#808030;">[</span>NativeDemo<span style="color:#808030;">]</span>
<span style="color:#800000;font-weight:bold;">ON</span>  <span style="color:#800000;font-weight:bold;">PRIMARY</span> 
<span style="color:#808030;">(</span> NAME <span style="color:#808030;">=</span> N<span style="color:#0000e6;">&#39;NativeDemo_data&#39;</span><span style="color:#808030;">,</span> FILENAME <span style="color:#808030;">=</span> N<span style="color:#0000e6;">&#39;C:\Demo\NativeDemo_data.mdf&#39;</span><span style="color:#808030;">)</span><span style="color:#808030;">,</span>  
FILEGROUP <span style="color:#808030;">[</span>InMemoryOLTP_InMemory<span style="color:#808030;">]</span> <span style="color:#800000;font-weight:bold;">CONTAINS</span> MEMORY_OPTIMIZED_DATA  
<span style="color:#808030;">(</span> NAME <span style="color:#808030;">=</span> N<span style="color:#0000e6;">&#39;NativeDemo_memopt&#39;</span><span style="color:#808030;">,</span> FILENAME <span style="color:#808030;">=</span> N<span style="color:#0000e6;">&#39;C:\Demo\NativeDemo_memopt&#39;</span><span style="color:#808030;">)</span> 
<span style="color:#bb7977;font-weight:bold;">LOG</span> <span style="color:#800000;font-weight:bold;">ON</span> <span style="color:#808030;">(</span> NAME <span style="color:#808030;">=</span> N<span style="color:#0000e6;">&#39;NativeDemo_log&#39;</span><span style="color:#808030;">,</span> FILENAME <span style="color:#808030;">=</span> N<span style="color:#0000e6;">&#39;C:\Demo\NativeDemo_log.ldf&#39;</span><span style="color:#808030;">)</span>
<span style="color:#800000;font-weight:bold;">GO</span>
</pre>
</div>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Now we try and create a natively compiled table. Note that as soon as we start the batch Dependency Walker will start to output info (that&rsquo;s what we wanted in the first place) and slow down the batch considerably:</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">USE</span> <span style="color:#808030;">[</span>NativeDemo<span style="color:#808030;">]</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">GO</span>
<span style="color:#800000;font-weight:bold;">CREATE</span> <span style="color:#800000;font-weight:bold;">TABLE</span> <span style="color:#808030;">[</span>Customer<span style="color:#808030;">]</span><span style="color:#808030;">(</span>
    <span style="color:#808030;">[</span>PKIDBucketCount64<span style="color:#808030;">]</span> <span style="color:#800000;font-weight:bold;">INT</span> <span style="color:#800000;font-weight:bold;">NOT</span> <span style="color:#800000;font-weight:bold;">NULL</span> <span style="color:#800000;font-weight:bold;">PRIMARY</span> <span style="color:#800000;font-weight:bold;">KEY</span> <span style="color:#800000;font-weight:bold;">NONCLUSTERED</span> <span style="color:#800000;font-weight:bold;">HASH</span> <span style="color:#800000;font-weight:bold;">WITH</span> <span style="color:#808030;">(</span>BUCKET_COUNT <span style="color:#808030;">=</span> <span style="color:#008c00;">64</span><span style="color:#808030;">)</span><span style="color:#808030;">,</span>
    <span style="color:#808030;">[</span>AnINTField<span style="color:#808030;">]</span> <span style="color:#800000;font-weight:bold;">INT</span> <span style="color:#800000;font-weight:bold;">NOT</span> <span style="color:#800000;font-weight:bold;">NULL</span><span style="color:#808030;">,</span>
	<span style="color:#808030;">[</span>AVarchar200Field<span style="color:#808030;">]</span> <span style="color:#800000;font-weight:bold;">VARCHAR</span><span style="color:#808030;">(</span><span style="color:#008c00;">200</span><span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">NOT</span> <span style="color:#800000;font-weight:bold;">NULL</span><span style="color:#808030;">,</span>
    <span style="color:#808030;">[</span>ANVarchar500Field<span style="color:#808030;">]</span> NVARCHAR<span style="color:#808030;">(</span><span style="color:#008c00;">500</span><span style="color:#808030;">)</span> <span style="color:#800000;font-weight:bold;">NOT</span> <span style="color:#800000;font-weight:bold;">NULL</span>
 <span style="color:#808030;">)</span>
<span style="color:#800000;font-weight:bold;">WITH</span> <span style="color:#808030;">(</span>MEMORY_OPTIMIZED <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">ON</span><span style="color:#808030;">,</span>  DURABILITY <span style="color:#808030;">=</span> SCHEMA_AND_DATA  <span style="color:#808030;">)</span><span style="color:#808030;">;</span>
<span style="color:#800000;font-weight:bold;">GO</span>
</pre>
</div>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">If all went well we should have our own table. Now go back to Dependency Walker and look at the Window menu:</span></p>
<p style="text-align:center;"><span style="font-family:verdana,geneva;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/dw%20cl%20and%20linker.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/dw-cl-and-linker.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/dw%20cl%20and%20linker.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/dw-cl-and-linker.jpg" border="0" /></a></span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">As we can see there are <span style="text-decoration:underline;">two</span> new processes captured by Dependency Walker: CL.exe and LINK.exe. These are the compiler and the linker processes spawned by SQL Server for the native compilation of our table. </span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Let&rsquo;s start selecting CL.exe. </span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">If we scroll all the way up in the log we will find something like this:</span></p>
<p><span style="font-family:verdana,geneva;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/cl%20windows.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/cl-windows.jpg"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/cl%20windows.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/cl-windows.jpg" border="0" /></a><br /></span></p>
<p style="text-align:justify;"></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Worth noting here are the command line parameters. In my case they were: </span></p>
<p style="text-align:left;"><span style="font-family:courier new,courier;"><code><b>Program Arguments: </b>/O2 /d2Zi+ /GL /Z7 /Gy- /I &quot;C:\Program Files\Microsoft SQL Server\MSSQL12.P00\MSSQL\Binn\Xtp\gen\include&quot; /W3 /wd4101 /wd4723 /wd4724 /wd4049 /WX /GS /fp:strict /LD &quot;xtp_t_6_277576027.c&quot; hkgenlib.lib hkruntime.lib hkengine.lib hkgenexp.exp hkcrt.lib hkk32.lib hkversion.obj /link /LIBPATH:&quot;C:\Program Files\Microsoft SQL Server\MSSQL12.P00\MSSQL\Binn\Xtp\gen\lib&quot; /LIBPATH:&quot;C:\Program Files\Microsoft SQL Server\MSSQL12.P00\MSSQL\Binn\Xtp\VC\lib&quot; /noentry /nodefaultlib /incremental:no /ltcg /wx /FUNCTIONPADMIN</code></span></p>
<p style="text-align:justify;"><span style="font-family:courier new,courier;font-size:small;"></span><span style="font-family:verdana,geneva;font-size:small;">If you have experience in C Windows coding you will recognize many of them. Just to point a few, notice the <em>/7Z</em> flag that helps debugging; for the performance point of&nbsp;view notice&nbsp;the <em>/O2</em> flag&nbsp;that asks the compiler to perform code optimization favoring speed over size&nbsp;(see <a href="https://msdn.microsoft.com/en-us/library/8f8h5cxt.aspx)">https://msdn.microsoft.com/en-us/library/8f8h5cxt.aspx)</a> while the <em>/fp:strict</em> flag forces the floating point operations to favor precision over speed (see <a href="https://msdn.microsoft.com/en-us/library/e7s85ffb.aspx">https://msdn.microsoft.com/en-us/library/e7s85ffb.aspx</a>). </span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Now if we switch to SQL Server process, we should see something like this:</span></p>
<p style="text-align:center;"><span style="font-family:verdana,geneva;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/loadlibrary.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/loadlibrary.jpg"><img alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/loadlibrary.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/loadlibrary.jpg" border="0" /></a></span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Notice two things here:</span></p>
<ul style="text-align:justify;">
<li>
<p><span style="font-family:verdana,geneva;font-size:small;">SQL Server calls LoadLibrary (see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx"><span style="color:#0563c1;">https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx</span></a>) to import in its own process the DLL just compiled.</span></p>
</li>
<li>
<p><span style="font-family:verdana,geneva;font-size:small;">SQL Server calls GetProcAddress to find the address of the exported functions (see <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx)"><span style="color:#0563c1;">https://msdn.microsoft.com/en-us/library/windows/desktop/ms683212(v=vs.85).aspx)</span></a>.</span></p>
</li>
</ul>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">Now SQL Server 2014 can call the compiled functions just pointing at the (local) address given by GetProcAddress.</span></p>
<p style="text-align:justify;"><span style="font-family:verdana,geneva;font-size:small;">&nbsp;</span></p>
<p style="text-align:justify;"></p>
<p style="text-align:justify;"><strong><span style="font-family:verdana,geneva;font-size:small;">Happy Coding,</span></strong></p>
<p style="text-align:justify;"><strong><span style="font-family:verdana,geneva;font-size:small;"><a title="Francesco Cogno" href="mailto:Francesco.Cogno@microsoft.com">Francesco Cogno</a></span></strong></p>
<p style="text-align:justify;"></p>
<p></p>
<p></p>
<p></p>]]></content:encoded>
    </item>
    <item>
      <title>Streaming in SQL Server using SQL CLR</title>
      <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/streaming-in-sql-server-using-sql-clr</link>
      <pubDate>Thu, 23 Jan 2014 02:39:58 GMT</pubDate>
      <dc:creator><![CDATA[Italian Premier Center for SQL Server]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/italian_premier_center_for_sql_server/2014/01/23/streaming-in-sql-server-using-sql-clr/</guid>
      <description><![CDATA[The SQL Server engine execution operators are of two kinds: blocking and non-blocking. Blocking...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family:Calibri;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/00-block.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/00_2D00_block.png"></a><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/01-stream.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/01_2D00_stream.jpg"></a>The SQL Server engine execution operators are of two kinds: blocking and non-blocking. Blocking operators need to consume the complete dataset before returning an output. Think about the COUNT(*) operator: in order to tell you the result it has to go over all your rows. Another example of blocking operator is the Sort operator. Proper sorting requires the dataset to be <i>completely</i> sorted. </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">Non-blocking operators, on the contrary, can produce output before having processed all the input rows. Think about at this query: </span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="font-size:small;"><span style="color:#800000;font-weight:bold;">SELECT</span> <span style="color:#800000;font-weight:bold;">a</span><span style="color:#808030;">,</span>b<span style="color:#808030;">,</span> <span style="color:#800000;font-weight:bold;">a</span><span style="color:#808030;">+</span>b <span style="color:#800000;font-weight:bold;">FROM</span> <span style="color:#800000;font-weight:bold;">Table</span>
</span></pre>
</div>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">SQL Server can tell the exact result of a+b of each row as soon as it has read the row itself. In this case SQL Server will not wait for the whole table to be read from disk and will <i>stream</i> the data to the output as soon as it&rsquo;s ready. </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">As you might have guessed by now non-blocking operators are generally better: the less bottlenecks your execution plan has the better. </span></p>
<p style="text-align:justify;"><span style="font-size:small;"><span style="font-family:Calibri;">The SQL Server optimizer, of course, knows when it&rsquo;s best to use &ndash; and where &ndash; these operators on its own. You should however be mindful of the implications of a blocking function in your code, especially when dealing with slow-to-retrieve datasets. As a real example suppose we want to access the OpenData Lombardia and perform some statistical calculations. The data is available as an URL: </span><a href="https://www.dati.lombardia.it/api/views/sd8x-w4h3/rows.csv?accessType=DOWNLOAD"><span style="color:#0563c1;font-family:Calibri;">https://www.dati.lombardia.it/api/views/sd8x-w4h3/rows.csv?accessType=DOWNLOAD</span></a><span style="font-family:Calibri;"> (rows are available in other formats such as JSON and XML but for the purpose of this article we will work with CSV).</span></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">In order to show a real example I&rsquo;ve created a much bigger version of the recordset (exactly 1,305,487,617 bytes) replicating the original dataset.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">Using the CLR we can access the remote recordset and return as SQL NVARCHAR rows. A first blocking approach can be: </span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#808030;">[</span>SqlFunction<span style="color:#808030;">(</span>
    DataAccess <span style="color:#808030;">=</span> DataAccessKind<span style="color:#808030;">.</span>None<span style="color:#808030;">,</span>
    SystemDataAccess <span style="color:#808030;">=</span> SystemDataAccessKind<span style="color:#808030;">.</span>None<span style="color:#808030;">,</span>
    FillRowMethodName <span style="color:#808030;">=</span> <span style="color:#800000;">&quot;</span><span style="color:#0000e6;">_StreamLine</span><span style="color:#800000;">&quot;</span><span style="color:#808030;">,</span>
    IsDeterministic <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">false</span><span style="color:#808030;">,</span>
    IsPrecise <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">true</span><span style="color:#808030;">,</span>
    TableDefinition <span style="color:#808030;">=</span> <span style="color:#808030;">(</span>@<span style="color:#800000;">&quot;</span><span style="color:#0000e6;">Line NVARCHAR(MAX)</span><span style="color:#800000;">&quot;</span><span style="color:#808030;">)</span><span style="color:#808030;">)</span><span style="color:#808030;">]</span>
<span style="color:#800000;font-weight:bold;">public</span> <span style="color:#800000;font-weight:bold;">static</span> System<span style="color:#808030;">.</span>Collections<span style="color:#808030;">.</span>IEnumerable BlockingFileLine<span style="color:#808030;">(</span>
    SqlString fileName<span style="color:#808030;">)</span>
<span style="color:#800080;">{</span>
    List<span style="color:#808030;">&lt;</span><span style="color:#800000;font-weight:bold;">string</span><span style="color:#808030;">&gt;</span> lStreams <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">new</span> List<span style="color:#808030;">&lt;</span><span style="color:#800000;font-weight:bold;">string</span><span style="color:#808030;">&gt;</span><span style="color:#808030;">(</span><span style="color:#808030;">)</span><span style="color:#800080;">;</span>

    <span style="color:#800000;font-weight:bold;">using</span> <span style="color:#808030;">(</span>System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>FileStream fs <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">new</span> System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>FileStream<span style="color:#808030;">(</span>
                    fileName<span style="color:#808030;">.</span>Value<span style="color:#808030;">,</span>
                    System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>FileMode<span style="color:#808030;">.</span>Open<span style="color:#808030;">,</span>
                    System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>FileAccess<span style="color:#808030;">.</span>Read<span style="color:#808030;">,</span>
                    System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>FileShare<span style="color:#808030;">.</span>Read<span style="color:#808030;">)</span><span style="color:#808030;">)</span>
    <span style="color:#800080;">{</span>

        <span style="color:#800000;font-weight:bold;">using</span> <span style="color:#808030;">(</span>System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>StreamReader sr <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">new</span> System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>StreamReader<span style="color:#808030;">(</span>fs<span style="color:#808030;">)</span><span style="color:#808030;">)</span>
        <span style="color:#800080;">{</span>
            <span style="color:#800000;font-weight:bold;">string</span> str<span style="color:#800080;">;</span>
            <span style="color:#800000;font-weight:bold;">while</span> <span style="color:#808030;">(</span><span style="color:#808030;">(</span>str <span style="color:#808030;">=</span> sr<span style="color:#808030;">.</span>ReadLine<span style="color:#808030;">(</span><span style="color:#808030;">)</span><span style="color:#808030;">)</span> <span style="color:#808030;">!</span><span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">null</span><span style="color:#808030;">)</span>
                lStreams<span style="color:#808030;">.</span>Add<span style="color:#808030;">(</span>str<span style="color:#808030;">)</span><span style="color:#800080;">;</span>
        <span style="color:#800080;">}</span>
    <span style="color:#800080;">}</span>

    <span style="color:#800000;font-weight:bold;">return</span> lStreams<span style="color:#800080;">;</span>
<span style="color:#800080;">}</span>
</pre>
</div>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">This undoubtedly works as expected generating a line-by-line TVF. However if we look at the memory footprint (I suppose a recently started instance for the sake of simplicity): </span></p>
<p><span style="font-family:Calibri;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/00-block.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/00_2D00_block.png"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/00-block.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/00_2D00_block.png" border="0" /></a></span></p>
<p></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">This is far from optimal. Look at the virtual_memory_committed_kb delta: it&rsquo;s a LOT. SQL went from 13264 KB to 4132364 KB. It&rsquo;s almost 4GB just for this function (~3.5 times the initial dataset)!</span></p>
<p style="text-align:justify;"><span style="font-size:small;"><span style="font-family:Calibri;">In SQL CLR functions we can &ndash; and should - use lazy evaluation instead: your main function is expected to return a </span>System.Collections.IEnumerable <span style="font-family:Calibri;">instance. This is good: IEnumerable instances are <b><span style="text-decoration:underline;">not</span></b> required to be able to tell the exact number of items in advance. This means that we can populate an IEnumerable while it&rsquo;s being traversed. Using the streaming approach we don&rsquo;t need to read all the file in advance. We can just read the relevant bits when requested.</span></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">In the previous example we returned a List (that implements IEnumerable). The list was populated in advance (hence the heavy memory usage). To use a streaming approach we need to return a custom class that implements IEnumerable directly:</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#808030;">[</span>SqlFunction<span style="color:#808030;">(</span>
    DataAccess <span style="color:#808030;">=</span> DataAccessKind<span style="color:#808030;">.</span>None<span style="color:#808030;">,</span>
    SystemDataAccess <span style="color:#808030;">=</span> SystemDataAccessKind<span style="color:#808030;">.</span>None<span style="color:#808030;">,</span>
    FillRowMethodName <span style="color:#808030;">=</span> <span style="color:#800000;">&quot;</span><span style="color:#0000e6;">_StreamLine</span><span style="color:#800000;">&quot;</span><span style="color:#808030;">,</span>
    IsDeterministic <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">false</span><span style="color:#808030;">,</span>
    IsPrecise <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">true</span><span style="color:#808030;">,</span>
    TableDefinition <span style="color:#808030;">=</span> <span style="color:#808030;">(</span>@<span style="color:#800000;">&quot;</span><span style="color:#0000e6;">Line NVARCHAR(MAX)</span><span style="color:#800000;">&quot;</span><span style="color:#808030;">)</span><span style="color:#808030;">)</span><span style="color:#808030;">]</span>
<span style="color:#800000;font-weight:bold;">public</span> <span style="color:#800000;font-weight:bold;">static</span> System<span style="color:#808030;">.</span>Collections<span style="color:#808030;">.</span>IEnumerable StreamFileLine<span style="color:#808030;">(</span>
    SqlString fileName<span style="color:#808030;">)</span>
<span style="color:#800080;">{</span>
    System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>FileStream fs <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">new</span> System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>FileStream<span style="color:#808030;">(</span>
                    fileName<span style="color:#808030;">.</span>Value<span style="color:#808030;">,</span>
                    System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>FileMode<span style="color:#808030;">.</span>Open<span style="color:#808030;">,</span>
                    System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>FileAccess<span style="color:#808030;">.</span>Read<span style="color:#808030;">,</span>
                    System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>FileShare<span style="color:#808030;">.</span>Read<span style="color:#808030;">)</span><span style="color:#800080;">;</span>

    <span style="color:#800000;font-weight:bold;">return</span> <span style="color:#800000;font-weight:bold;">new</span> LineStreamer<span style="color:#808030;">(</span>fs<span style="color:#808030;">)</span><span style="color:#800080;">;</span>
<span style="color:#800080;">}</span>
</pre>
</div>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">Here our LineStreamer class is just a wrapper around our real implementation:</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">public</span> <span style="color:#800000;font-weight:bold;">class</span> LineStreamer <span style="color:#808030;">:</span> Streamer<span style="color:#808030;">,</span> System<span style="color:#808030;">.</span>Collections<span style="color:#808030;">.</span>IEnumerable
<span style="color:#800080;">{</span>
    <span style="color:#800000;font-weight:bold;">public</span> LineStreamer<span style="color:#808030;">(</span>System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>Stream stream<span style="color:#808030;">)</span>
        <span style="color:#808030;">:</span> <span style="color:#800000;font-weight:bold;">base</span><span style="color:#808030;">(</span>stream<span style="color:#808030;">)</span>
    <span style="color:#800080;">{</span> <span style="color:#800080;">}</span>

    System<span style="color:#808030;">.</span>Collections<span style="color:#808030;">.</span>IEnumerator System<span style="color:#808030;">.</span>Collections<span style="color:#808030;">.</span>IEnumerable<span style="color:#808030;">.</span>GetEnumerator<span style="color:#808030;">(</span><span style="color:#808030;">)</span>
    <span style="color:#800080;">{</span>
        <span style="color:#800000;font-weight:bold;">return</span> <span style="color:#800000;font-weight:bold;">new</span> LineStreamerEnumerator<span style="color:#808030;">(</span>stream<span style="color:#808030;">)</span><span style="color:#800080;">;</span>
    <span style="color:#800080;">}</span>
<span style="color:#800080;">}</span>
</pre>
</div>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">The real code is in LineStreamerEnumerator class. That class will implement System.Collections.IEnumerator allowing it to be traversed in a foreach loop. In order to achieve streaming we should produce a row only when explicitly requested. We should also discard any non essential information in order to minimize the memory footprint.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">Here we go:</span></p>
<div style="overflow:scroll;font-size:12pt;">
<pre><span style="color:#800000;font-weight:bold;">public</span> <span style="color:#800000;font-weight:bold;">class</span> LineStreamerEnumerator <span style="color:#808030;">:</span> System<span style="color:#808030;">.</span>Collections<span style="color:#808030;">.</span>IEnumerator<span style="color:#808030;">,</span> IDisposable
<span style="color:#800080;">{</span>
    <span style="color:#800000;font-weight:bold;">protected</span> System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>StreamReader sr <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">null</span><span style="color:#800080;">;</span>
    <span style="color:#800000;font-weight:bold;">protected</span> <span style="color:#800000;font-weight:bold;">string</span> _CurrentLine <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">null</span><span style="color:#800080;">;</span>

    <span style="color:#800000;font-weight:bold;">public</span> LineStreamerEnumerator<span style="color:#808030;">(</span>System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>Stream s<span style="color:#808030;">)</span>
    <span style="color:#800080;">{</span>
        sr <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">new</span> System<span style="color:#808030;">.</span>IO<span style="color:#808030;">.</span>StreamReader<span style="color:#808030;">(</span>s<span style="color:#808030;">)</span><span style="color:#800080;">;</span>
    <span style="color:#800080;">}</span>

    <span style="color:#800000;font-weight:bold;">object</span> System<span style="color:#808030;">.</span>Collections<span style="color:#808030;">.</span>IEnumerator<span style="color:#808030;">.</span>Current
    <span style="color:#800080;">{</span>
        get <span style="color:#800080;">{</span> <span style="color:#800000;font-weight:bold;">return</span> _CurrentLine<span style="color:#800080;">;</span> <span style="color:#800080;">}</span>
    <span style="color:#800080;">}</span>

    <span style="color:#800000;font-weight:bold;">bool</span> System<span style="color:#808030;">.</span>Collections<span style="color:#808030;">.</span>IEnumerator<span style="color:#808030;">.</span>MoveNext<span style="color:#808030;">(</span><span style="color:#808030;">)</span>
    <span style="color:#800080;">{</span>
        _CurrentLine <span style="color:#808030;">=</span> sr<span style="color:#808030;">.</span>ReadLine<span style="color:#808030;">(</span><span style="color:#808030;">)</span><span style="color:#800080;">;</span>
        <span style="color:#800000;font-weight:bold;">return</span> _CurrentLine <span style="color:#808030;">!</span><span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">null</span><span style="color:#800080;">;</span>
    <span style="color:#800080;">}</span>

    <span style="color:#800000;font-weight:bold;">void</span> System<span style="color:#808030;">.</span>Collections<span style="color:#808030;">.</span>IEnumerator<span style="color:#808030;">.</span>Reset<span style="color:#808030;">(</span><span style="color:#808030;">)</span>
    <span style="color:#800080;">{</span>
        <span style="color:#800000;font-weight:bold;">throw</span> <span style="color:#800000;font-weight:bold;">new</span> NotImplementedException<span style="color:#808030;">(</span><span style="color:#808030;">)</span><span style="color:#800080;">;</span>
    <span style="color:#800080;">}</span>

    #region IDisposable <span style="color:#808030;">/</span> destructor
    <span style="color:#800000;font-weight:bold;">void</span> IDisposable<span style="color:#808030;">.</span>Dispose<span style="color:#808030;">(</span><span style="color:#808030;">)</span>
    <span style="color:#800080;">{</span>
        <span style="color:#800000;font-weight:bold;">if</span> <span style="color:#808030;">(</span>sr <span style="color:#808030;">!</span><span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">null</span><span style="color:#808030;">)</span>
        <span style="color:#800080;">{</span>
            sr<span style="color:#808030;">.</span>Dispose<span style="color:#808030;">(</span><span style="color:#808030;">)</span><span style="color:#800080;">;</span>
            sr <span style="color:#808030;">=</span> <span style="color:#800000;font-weight:bold;">null</span><span style="color:#800080;">;</span>
        <span style="color:#800080;">}</span>
    <span style="color:#800080;">}</span>

    <span style="color:#696969;">// Finalizers are not supported in SQL CLR</span>
    <span style="color:#696969;">//~LineStreamerEnumerator()</span>
    <span style="color:#696969;">//{</span>
    <span style="color:#696969;">//    if (sr != null)</span>
    <span style="color:#696969;">//        sr.Dispose();</span>
    <span style="color:#696969;">//}</span>
    #endregion
<span style="color:#800080;">}</span>
</pre>
</div>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">Notice that I&rsquo;ve implemented the IDisposable interface explicitly. SQL Server will call Dispose on our enumerator as soon as it&rsquo;s done with it. This will give us a chance to cleanup any lingering streams. We cannot use finalizers in SQLCLR as the example above illustrated.</span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">Let&rsquo;s try streaming in action:</span></p>
<p><span style="font-family:Calibri;font-size:small;"><span>&nbsp;&nbsp;<span style="font-family:Calibri;font-size:small;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/00-block.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/00_2D00_block.png"></a><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/01-stream.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/01_2D00_stream.jpg"><img style="margin-right:auto;margin-left:auto;display:block;" alt=" " src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/01-stream.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/01_2D00_stream.jpg" border="0" /></a></span></span></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;"><span>Here the memory delta is a LOT less (107728 &ndash; 16844 = 90884 kb). We lowered our memory footprint <b><span style="text-decoration:underline;">from 4GB to 100MB</span></b>. </span></span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">Impressive isn&rsquo;t it? </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">Of course this is an ad-hoc example so you should not expect such big gains in real world. It is however a good practice to avoid blocking operators whenever possible. </span></p>
<p style="text-align:justify;"><span style="font-family:Calibri;font-size:small;">More on the topic:</span></p>
<ul>
<li>
<p><span style="font-size:small;">[MSDN] IEnumerable Interface (<a href="https://msdn.microsoft.com/library/system.collections.ienumerable(v=vs.110).aspx)"><span style="color:#0563c1;">https://msdn.microsoft.com/library/system.collections.ienumerable(v=vs.110).aspx)</span></a>.</span></p>
</li>
<li>
<p><span style="font-size:small;">[MSDN] IEnumerator Interface (<a href="https://msdn.microsoft.com/library/system.collections.ienumerator(v=vs.110).aspx)"><span style="color:#0563c1;">https://msdn.microsoft.com/library/system.collections.ienumerator(v=vs.110).aspx)</span></a>.</span></p>
</li>
<li>
<p><span style="font-size:small;">[MSDN] IDisposable Interface (<a href="https://msdn.microsoft.com/library/system.idisposable(v=vs.110).aspx)"><span style="color:#0563c1;">https://msdn.microsoft.com/library/system.idisposable(v=vs.110).aspx)</span></a>.</span></p>
</li>
</ul>
<p style="text-align:justify;"><span style="font-size:small;"><span style="font-family:Calibri;">Remember also that most .Net streams have automatic buffering so you don&rsquo;t have to worry about it. This feature fits nicely in the streaming pattern; try it using the System.Net.WebRequest to understand why (or just look </span><a href="https://sqlservertoazure.codeplex.com/SourceControl/latest#ITPCfSQL.Azure.CLR/Streaming/Stream.cs"><span style="color:#0563c1;font-family:Calibri;">here</span></a><span><span style="font-family:Calibri;"> if you&rsquo;re lazy :)</span><span style="font-family:Calibri;">).</span></span></span></p>
<p><span style="font-family:Calibri;font-size:small;">&nbsp;</span></p>
<p><span style="font-size:small;"><b><span style="font-family:Calibri;">Happy Coding,</span></b></span></p>
<p><span style="font-size:small;"><a href="mailto:francesco.cogno@microsoft.com"><b><span style="color:#0563c1;font-family:Calibri;">Francesco Cogno</span></b></a></span></p>
<p><span style="font-family:Calibri;font-size:small;">&nbsp;</span></p>
<p></p>
<p></p>]]></content:encoded>
    </item>
    <item>
      <title>SQLSaturday 264 slide deck</title>
      <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/sqlsaturday-264-slide-deck</link>
      <pubDate>Wed, 18 Dec 2013 09:00:15 GMT</pubDate>
      <dc:creator><![CDATA[Italian Premier Center for SQL Server]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/italian_premier_center_for_sql_server/2013/12/18/sqlsaturday-264-slide-deck/</guid>
      <description><![CDATA[Hi all,
here are the slides of our recent speech at SQLSaturday 264 in Ancona...]]></description>
      <content:encoded><![CDATA[<p>Hi all,</p>
<p style="text-align:justify;">here are the slides of our recent speech at SQLSaturday 264 in Ancona (<a title="https://www.sqlsaturday.com/264/eventhome.aspx" href="https://www.sqlsaturday.com/264/eventhome.aspx">https://www.sqlsaturday.com/264/eventhome.aspx</a>).</p>
<p style="text-align:justify;">You will also find the demo scripts. Feel free to share your thoughts.</p>
<p></p>
<p><strong>Happy Coding,</strong></p>
<p><a title="Francesco Cogno" href="mailto:francesco.cogno@microsoft.com">Francesco Cogno</a> (@MindFlavor) and <a title="Giuseppe Zagarrio" href="mailto:giuseppe.zagarrio@microsoft.com">Giuseppe Zagarrio</a> (@ZagaMimmo)</p>
<p>[View:~/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6-degrees-of-separation.pdf:550:0]</p>
<p>[View:~/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6254.Demos.zip:550:0]</p>]]></content:encoded>
    </item>
    <item>
      <title>About Container Shared Access Signature for SQL Server XI</title>
      <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/about-container-shared-access-signature-for-sql-server-xi</link>
      <pubDate>Thu, 05 Dec 2013 01:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Italian Premier Center for SQL Server]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/italian_premier_center_for_sql_server/2013/12/05/about-container-shared-access-signature-for-sql-server-xi/</guid>
      <description><![CDATA[Hi all,
Ever since the MSDN post about SQL Server XI, available from SQL 2014 (see...]]></description>
      <content:encoded><![CDATA[<p>Hi all,</p>
<p style="text-align: justify;">Ever since the MSDN post about SQL Server XI, available from SQL 2014 (see &nbsp;<a href="https://blogs.msdn.com/b/igorpag/archive/2013/10/23/create-a-sql-server-2014-database-directly-on-azure-blob-storage-with-sqlxi.aspx">https://blogs.msdn.com/b/igorpag/archive/2013/10/23/create-a-sql-server-2014-database-directly-on-azure-blob-storage-with-sqlxi.aspx</a>) there is a lot of buzz about Azure Storage in the SQL Server community. One recurring question is: What is the Shared Access Signature (SAS) and why SQL Server XI needs it?</p>
<p style="text-align: justify;">First some background: in the Azure storage platform, each blob is contained in a, er, container. Each container, in turn, is related to a specific Storage Account:</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3482.00.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3482.00.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3482.00.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3482.00.png" alt="" border="0" /></a>&nbsp;</p>
<p style="text-align: justify;">So, in order to access a blob you need to specify:</p>
<ul>
<li>The account.</li>
<li>The container.</li>
<li>The blob name itself.</li>
</ul>
<p style="text-align: justify;">So, for example, suppose you have a storage account called frcogno. In that account you have created a blob called database.mdf and placed it into the container mindflavor.</p>
<p align="center">&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3823.01.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3823.01.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3823.01.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3823.01.png" alt="" border="0" /></a></p>
<p style="text-align: justify;">In the Azure world, this is a REST URI:</p>
<p style="text-align: center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/2768.02.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/2768.02.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/2768.02.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/2768.02.png" alt="" border="0" /></a></p>
<p>&nbsp;<a href="https://frcogno.blob.core.windows.net/mindflavor/database.mdf">https://frcogno.blob.core.windows.net/mindflavor/database.mdf</a></p>
<p style="text-align: justify;">&nbsp;Of course, unless you&rsquo;ve specified the container or the blob to be publicly accessible, you cannot access it directly. The Get Blob operation (<a href="https://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx">https://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx</a>) requires you to specify the <em>Authorization </em><em>header.</em> Without it any access will fail. But what is required to specify the authorization header? Simply put you need the Azure Account shared key. You can find them in the portal:</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6710.03.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6710.03.png"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6710.03.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6710.03.png" alt="" border="0" /></a></p>
<p style="text-align: justify;">As you can see the access keys are linked to your Azure Storage account:</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4452.04.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4452.04.png"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4452.04.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4452.04.png" alt="" border="0" /></a></p>
<p style="text-align: justify;">Our picture now shows that in order to access <a href="https://frcogno.blob.core.windows.net/mindflavor/database.mdf">https://frcogno.blob.core.windows.net/mindflavor/database.mdf</a> we need the Shared Access Keys of the account <em>frcogno</em>. But what if we have two containers?</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/2046.05.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/2046.05.png"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/2046.05.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/2046.05.png" alt="" border="0" /></a></p>
<p style="text-align: justify;">As you can see, knowing the Shared Access Keys of frcogno would allow you to access <em>both containers</em>. Aside from that, each REST API call must be <em>independently</em> authorized. Since the authorization involves a SHA256 algorithm it will be hard on your CPU (suppose 50K IOPS: it means up to 50K SHA256/sec!). &nbsp;</p>
<p style="text-align: justify;">In order to avoid the continuous authorization we should create a reusable signed request. In the Azure platform it&rsquo;s done by using a &ldquo;self-signed&rdquo; URI (or, more correctly, Shared Access Signature URI). &nbsp;That is, an URI that contains the authorization header once and for all.</p>
<p style="text-align: justify;">Referring here we find exactly how to generate that URI: <a href="https://msdn.microsoft.com/en-us/library/windowsazure/dn140255.aspx">https://msdn.microsoft.com/en-us/library/windowsazure/dn140255.aspx</a>; don&rsquo;t worry, though, you can use the easier T-SQL method (just install the SQL Server to Windows Azure helper library available here: <a href="https://sqlservertoazure.codeplex.com/">https://sqlservertoazure.codeplex.com/</a>).</p>
<p style="text-align: justify;">Using the library we can call the <strong>GenerateDirectBlobSharedAccessSignatureURI</strong> function to do the job for us:</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #800000; font-weight: bold;">SELECT</span> <span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>GenerateDirectBlobSharedAccessSignatureURI<span style="color: #808030;">(</span>
	<span style="color: #0000e6;">'https://frcogno.blob.core.windows.net/mindflavor/database.mdf'</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'cQhAGiYCTw09dg+i4YkciTiG2g0g5Sn5AMvKD2bnG9csjxuLOf8fNq7dKoY4I48LEFLTUGDZXxNxBz0oxGSUNQ=='</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'rwd'</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'b'</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'2010-01-01'</span><span style="color: #808030;">,</span> <span style="color: #0000e6;">'2015-12-31'</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>
</pre>
</div>
<p style="text-align: justify;">The parameters are:</p>
<ol>
<li style="text-align: justify;">The URI you want to sign. In our case is 'https://frcogno.blob.core.windows.net/mindflavor/database.mdf'.</li>
<li style="text-align: justify;">The Storage account shared Key.</li>
<li style="text-align: justify;">The permission to grant the SAS URI (in this case we give it Read, Write, Delete. Please refer to <a href="https://msdn.microsoft.com/en-us/library/windowsazure/dn140255.aspx">https://msdn.microsoft.com/en-us/library/windowsazure/dn140255.aspx</a> for the list of permissions available).</li>
<li style="text-align: justify;">The type of resource. In this case we use <em>b</em> as Blob. If we were to grant a container it would have been <em>c</em>.</li>
<li style="text-align: justify;">The validity interval of the SAS URI. In this case we specify from '2010-01-01' to '2015-12-31'.</li>
</ol>
<p style="text-align: justify;">The result would be a rather complex URI that will allow you to access the resource <em>without</em> knowing the Azure account shared key.</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6201.06.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6201.06.png"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6201.06.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6201.06.png" alt="" border="0" /></a></p>
<p style="text-align: justify;">&nbsp;Notice that in this case we are creating a SAS URI for the single blob. We could have done it at container level. In that case it would be possible to access all the blobs in that container. For example this SAS URI would allow access to any blob in the mindflavor container:</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/1464.07.png" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/1464.07.png"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/1464.07.png" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/1464.07.png" alt="" border="0" /></a></p>
<p style="text-align: justify;">Now all you have to do is to create the credential in SQL Server:</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #800000; font-weight: bold;">CREATE</span> CREDENTIAL <span style="color: #808030;">[</span>https<span style="color: #797997;">:</span><span style="color: #696969;">//frcogno.blob.core.windows.net/mindflavor]</span>
<span style="color: #800000; font-weight: bold;">WITH</span> <span style="color: #800000; font-weight: bold;">IDENTITY</span><span style="color: #808030;">=</span><span style="color: #0000e6;">'SHARED ACCESS SIGNATURE'</span>
SECRET<span style="color: #808030;">=</span><span style="color: #0000e6;">'sv=2012-02-12&amp;st=2009-12-31T23:00:00Z&amp;se=2015-12-30T23:00:00Z&amp;sr=c&amp;sp=rwdl&amp;sig=OR4xtXnPXe%2BYHpZ9J5EiZ0Fm9R664wc7%2BK0RVELffIQ%3D'</span><span style="color: #808030;">;</span>
</pre>
</div>
<p style="text-align: justify;">And now SQL Server can manage the blobs in the mindflavor container. And, more importantly, not in <span style="text-decoration: underline;">any other container of the same Azure Storage Account.</span></p>
<p style="text-align: justify;">There are a couple of things to note:</p>
<ul>
<li style="text-align: justify;">The SAS URI has a validity time frame. Outside that timespan the SAS URI would expire.</li>
<li style="text-align: justify;">Knowing the SAS URI will allow uncontrolled access to the container. Make sure to not share it.</li>
</ul>
<p style="text-align: justify;">The second point leads to another thought: what if the SAS URI is stolen? Is there a way to revoke the permissions?</p>
<p style="text-align: justify;">In our case we&rsquo;ll have to change the Azure Account Shared key (the one we used to generate the SAS URI). That will, of course, invalidate <span style="text-decoration: underline;">every single SAS URI generated with it</span>. This is far from ideal so the Azure platform has another solution for you.</p>
<p style="text-align: justify;">You can generate a access policy of a resource and then grant access to that policy. If the SAS URI is stolen all you have to do is to revoke that single policy.</p>
<p style="text-align: justify;">But that will be shown in another post since it requires you to play with the container ACLs. More on that later.</p>
<p>&nbsp;</p>
<p>Happy Coding,</p>
<p><a title="Francesco Cogno " href="mailto:francesco.cogno@microsoft.com"><strong>Francesco Cogno</strong></a></p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Backup to Azure using TSQL (and CLR)</title>
      <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/backup-to-azure-using-tsql-and-clr</link>
      <pubDate>Fri, 15 Nov 2013 03:09:00 GMT</pubDate>
      <dc:creator><![CDATA[Italian Premier Center for SQL Server]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/italian_premier_center_for_sql_server/2013/11/15/backup-to-azure-using-tsql-and-clr/</guid>
      <description><![CDATA[Hi All,
as a sample of how to use Microsoft SQL Server To Windows Azure helper library let me show...]]></description>
      <content:encoded><![CDATA[<p>Hi All,</p>
<p style="text-align: justify;">as a sample of how to use <a href="https://blogs.technet.com/controlpanel/blogs/posteditor.aspx/the https:/sqlservertoazure.codeplex.com/">Microsoft SQL Server To Windows Azure helper library</a> let me show you how to perform a backup to azure using the TSQL. As prerequisite, of course, you should have downloaded and installed the helper assembly (for how to do that please refer to the project documentation).&nbsp;</p>
<p style="text-align: justify;">In our sample we will be using the Azure page blob. The page blob is well suited for random access allowing us to upload the backup in data chunks. It's useful since we can resend only the failing chunks instead of the whole backup. In order to use a page blob we need to define its maximum size first. In a way it acts like a sparse file: your tell the file system how big the file should be and then start putting content in it.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4628.00.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4628.00.jpg"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4628.00.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4628.00.jpg" alt="" border="0" /></a></p>
<p style="text-align: justify;">Of course we should put an exclusive lease on the blob. We should release the lease only when the upload procedure is complete. Failing to do so might allow readers to get a non complete copy (we all know the SQL isolation levels enough to know how bad that could be). In this sample, however, will leave that out to a later post.</p>
<p style="text-align: justify;">So in order to upload a backup we should follow this macro-code:</p>
<ol>
<li style="text-align: justify;">Backup to temporary storage.</li>
<li style="text-align: justify;">Create the page blob with maximum size = backup size.</li>
<li style="text-align: justify;">Split the backup in pages of reasonable size (as usual, big chunks are most efficient but a failed upload would mean more data to retransmit).</li>
<li style="text-align: justify;">Create a table to keep track of the uploaded chunks.</li>
<li style="text-align: justify;">Upload the pages verifying the outcome.</li>
</ol>
<p style="text-align: justify;">Let's get down to the code:</p>
<h2>Backup to temp storage</h2>
<p>This is easy:</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #800000; font-weight: bold;">SET</span> NOCOUNT <span style="color: #800000; font-weight: bold;">ON</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">BACKUP</span> <span style="color: #800000; font-weight: bold;">DATABASE</span> <span style="color: #808030;">[</span>DemoAzureCLR<span style="color: #808030;">]</span> <span style="color: #800000; font-weight: bold;">TO</span> <span style="color: #800000; font-weight: bold;">DISK</span><span style="color: #808030;">=</span><span style="color: #0000e6;">'C:\temp\DemoAzureCLR.bak'</span> <span style="color: #800000; font-weight: bold;">WITH</span> INIT<span style="color: #808030;">,</span> COMPRESSION<span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">GO</span>
</pre>
</div>
<p style="text-align: justify;">Nothing fancy here.</p>
<h2 style="text-align: justify;">Create the page blob with maximum size = backup size</h2>
<p style="text-align: justify;">This is much more interesting. First use a pretty CLR function that returns us the backup size.</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #800000; font-weight: bold;">DECLARE</span> <span style="color: #797997;">@size</span> <span style="color: #800000; font-weight: bold;">BIGINT</span> <span style="color: #808030;">=</span> <span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>GetFileSizeBytes<span style="color: #808030;">(</span><span style="color: #0000e6;">'C:\temp\DemoAzureCLR.bak'</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>
</pre>
</div>
<p style="text-align: justify;">&nbsp;Now that we have the size we can call the correct [Azure] stored procedure: CreateOrReplacePageBlob:</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #696969;">-- Create the "sparse" page blob.</span>
<span style="color: #800000; font-weight: bold;">EXEC</span> <span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>CreateOrReplacePageBlob    
	<span style="color: #0000e6;">'your_account'</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'your_shared_key'</span><span style="color: #808030;">,</span> <span style="color: #008c00;">1</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'your_container'</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'DemoAzureCLR.bak'</span><span style="color: #808030;">,</span>
	<span style="color: #797997;">@size</span>
</pre>
</div>
<p style="text-align: justify;">Of course you should replace the parameters with the one of your Azure container.</p>
<h2 style="text-align: justify;">Split the backup in pages of reasonable size</h2>
<p style="text-align: justify;">Now we must calculate in how many chunks we want to split the backup file. I like to upload 32KB for each call so we divide the total size by<span style="font-family: courier new,courier; color: #008000;"> 32*1024</span>. Note that since we round up to the nearest integer we might end up with unused space. This must be accounted during the last upload: <strong>if we upload too much data - even if zeroed - the backup would be unusable</strong>.</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #800000; font-weight: bold;">DECLARE</span> <span style="color: #797997;">@PageCount</span> <span style="color: #800000; font-weight: bold;">INT</span> <span style="color: #808030;">=</span> <span style="color: #bb7977; font-weight: bold;">CEILING</span><span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">CONVERT</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">FLOAT</span><span style="color: #808030;">,</span> <span style="color: #797997;">@size</span><span style="color: #808030;">)</span> <span style="color: #808030;">/</span> <span style="color: #808030;">(</span><span style="color: #008000;">1024.0</span><span style="color: #808030;">*</span><span style="color: #008000;">32.0</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>
</pre>
</div>
<p style="text-align: justify;">&nbsp;</p>
<h2 style="text-align: justify;">Create a table to keep track of the uploaded chunks</h2>
<p style="text-align: justify;">To keep things simple we can use a simple table with an integer ID and a text field. The Chunk field identifies the chunk (page) number. Any non null string in the text field indicates that the chunk is yet to be uploaded. Since we know that the upload function will return null in case of success and a text in case of error all we have to do is to iterate between non-null rows, try to upload the corresponding chunk and then update the text field.</p>
<p style="text-align: justify;">First the table definition:</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #800000; font-weight: bold;">IF</span> <span style="color: #800000; font-weight: bold;">EXISTS</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">SELECT</span> <span style="color: #808030;">*</span> <span style="color: #800000; font-weight: bold;">FROM</span> tempdb<span style="color: #808030;">.</span><span style="color: #bb7977; font-weight: bold;">sys</span><span style="color: #808030;">.</span>objects <span style="color: #800000; font-weight: bold;">WHERE</span> name <span style="color: #808030;">=</span> <span style="color: #0000e6;">'##progressTable'</span><span style="color: #808030;">)</span>
<span style="color: #800000; font-weight: bold;">DROP</span> <span style="color: #800000; font-weight: bold;">TABLE</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable<span style="color: #808030;">;</span></pre>
<pre><span style="color: #800000; font-weight: bold;">CREATE</span> <span style="color: #800000; font-weight: bold;">TABLE</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable<span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">ID</span> <span style="color: #800000; font-weight: bold;">INT</span> <span style="color: #800000; font-weight: bold;">IDENTITY</span><span style="color: #808030;">(</span><span style="color: #008c00;">1</span><span style="color: #808030;">,</span><span style="color: #008c00;">1</span><span style="color: #808030;">)</span> <span style="color: #800000; font-weight: bold;">PRIMARY</span> <span style="color: #800000; font-weight: bold;">KEY</span> <span style="color: #800000; font-weight: bold;">CLUSTERED</span><span style="color: #808030;">,</span> <span style="color: #800000; font-weight: bold;">Chunk</span> <span style="color: #800000; font-weight: bold;">INT</span> <span style="color: #800000; font-weight: bold;">NOT</span> <span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">,</span> OpStatus NVARCHAR<span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">MAX</span><span style="color: #808030;">)</span> <span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>
</pre>
</div>
<p style="text-align: justify;">Then we initialize it (rember: a null value means "chunk uploaded successfully!"):</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #696969;">-- Prestage the progess table</span>
<span style="color: #800000; font-weight: bold;">DECLARE</span> <span style="color: #797997;">@iCnt</span> <span style="color: #800000; font-weight: bold;">INT</span> <span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">WHILE</span> <span style="color: #797997;">@iCnt</span> <span style="color: #808030;">&lt;</span> <span style="color: #797997;">@pageCount</span> <span style="color: #800000; font-weight: bold;">BEGIN</span>
	<span style="color: #800000; font-weight: bold;">INSERT</span> <span style="color: #800000; font-weight: bold;">INTO</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable<span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">Chunk</span><span style="color: #808030;">,</span> OpStatus<span style="color: #808030;">)</span> <span style="color: #800000; font-weight: bold;">VALUES</span><span style="color: #808030;">(</span><span style="color: #797997;">@iCnt</span><span style="color: #808030;">,</span> <span style="color: #0000e6;">'ToUpload'</span><span style="color: #808030;">)</span>
	<span style="color: #800000; font-weight: bold;">SET</span> <span style="color: #797997;">@iCnt</span> <span style="color: #808030;">+</span><span style="color: #808030;">=</span> <span style="color: #008c00;">1</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">END</span>
</pre>
</div>
<p style="text-align: justify;">&nbsp;</p>
<h2 style="text-align: justify;">Upload the pages verifying the outcome</h2>
<p style="text-align: justify;">All that's left to do is, for each non null row, upload the corresponding chunk:</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #800000; font-weight: bold;">DECLARE</span> <span style="color: #797997;">@pageNum</span> <span style="color: #800000; font-weight: bold;">INT</span><span style="color: #808030;">,</span> <span style="color: #797997;">@ID</span> <span style="color: #800000; font-weight: bold;">INT</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">DECLARE</span> <span style="color: #797997;">@len</span> <span style="color: #800000; font-weight: bold;">INT</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">WHILE</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">EXISTS</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">SELECT</span> <span style="color: #808030;">*</span> <span style="color: #800000; font-weight: bold;">FROM</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable <span style="color: #800000; font-weight: bold;">WHERE</span> OpStatus <span style="color: #800000; font-weight: bold;">IS</span> <span style="color: #800000; font-weight: bold;">NOT</span> <span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span>
<span style="color: #800000; font-weight: bold;">BEGIN</span>
	<span style="color: #800000; font-weight: bold;">SELECT</span> <span style="color: #800000; font-weight: bold;">TOP</span> <span style="color: #008c00;">1</span> <span style="color: #797997;">@pageNum</span> <span style="color: #808030;">=</span> <span style="color: #800000; font-weight: bold;">Chunk</span><span style="color: #808030;">,</span> <span style="color: #797997;">@ID</span> <span style="color: #808030;">=</span> <span style="color: #800000; font-weight: bold;">ID</span> <span style="color: #800000; font-weight: bold;">FROM</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable <span style="color: #800000; font-weight: bold;">WHERE</span> OpStatus <span style="color: #800000; font-weight: bold;">IS</span> <span style="color: #800000; font-weight: bold;">NOT</span> <span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">;</span>

	<span style="color: #800000; font-weight: bold;">SET</span> <span style="color: #797997;">@len</span> <span style="color: #808030;">=</span> <span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">;</span>
	<span style="color: #800000; font-weight: bold;">IF</span> <span style="color: #808030;">(</span><span style="color: #808030;">(</span><span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">*</span><span style="color: #797997;">@pageNum</span><span style="color: #808030;">)</span><span style="color: #808030;">+</span><span style="color: #797997;">@len</span><span style="color: #808030;">)</span><span style="color: #808030;">&gt;</span><span style="color: #797997;">@size</span> 
		<span style="color: #800000; font-weight: bold;">SET</span> <span style="color: #797997;">@len</span> <span style="color: #808030;">=</span> <span style="color: #797997;">@size</span> <span style="color: #808030;">-</span><span style="color: #808030;">(</span><span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">*</span><span style="color: #797997;">@pageNum</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>

	<span style="color: #800000; font-weight: bold;">PRINT</span> <span style="color: #0000e6;">'Uploading page number '</span> <span style="color: #808030;">+</span> <span style="color: #bb7977; font-weight: bold;">CONVERT</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">VARCHAR</span><span style="color: #808030;">,</span> <span style="color: #797997;">@pageNum</span><span style="color: #808030;">)</span> <span style="color: #808030;">+</span> <span style="color: #0000e6;">'. '</span> <span style="color: #808030;">+</span>  <span style="color: #bb7977; font-weight: bold;">CONVERT</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">VARCHAR</span><span style="color: #808030;">,</span> <span style="color: #797997;">@len</span><span style="color: #808030;">)</span> <span style="color: #808030;">+</span> <span style="color: #0000e6;">' bytes to upload.'</span><span style="color: #808030;">;</span>

	<span style="color: #800000; font-weight: bold;">UPDATE</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable <span style="color: #800000; font-weight: bold;">SET</span> OpStatus <span style="color: #808030;">=</span> <span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>PutPageFunction<span style="color: #808030;">(</span>
		<span style="color: #0000e6;">'your_account'</span><span style="color: #808030;">,</span>	<span style="color: #0000e6;">'your_shared_key'</span><span style="color: #808030;">,</span> <span style="color: #008c00;">1</span><span style="color: #808030;">,</span>
		<span style="color: #0000e6;">'your_container'</span><span style="color: #808030;">,</span>
		<span style="color: #0000e6;">'DBPartition.bak'</span><span style="color: #808030;">,</span>
		<span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>GetFileBlock<span style="color: #808030;">(</span>
			<span style="color: #0000e6;">'C:\temp\DBPartition.bak'</span><span style="color: #808030;">,</span>
			<span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">*</span><span style="color: #797997;">@pageNum</span><span style="color: #808030;">,</span>
			<span style="color: #797997;">@len</span><span style="color: #808030;">,</span>
			<span style="color: #0000e6;">'Read'</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span>
		<span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">*</span><span style="color: #797997;">@pageNum</span><span style="color: #808030;">,</span>
		<span style="color: #797997;">@len</span><span style="color: #808030;">,</span>
		<span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">,</span>
		<span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">,</span>
		<span style="color: #008c00;">0</span><span style="color: #808030;">,</span>
		<span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">)</span>
	<span style="color: #800000; font-weight: bold;">WHERE</span> <span style="color: #800000; font-weight: bold;">ID</span> <span style="color: #808030;">=</span> <span style="color: #797997;">@ID</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">END</span>
</pre>
</div>
<p style="text-align: justify;">Note that the T-SQL UPDATE statement is very handy in this case. Note, also, that we account for the last upload: since it might not be aligned to the 32KB boundary we check to make sure to upload only the valid data.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/7824.05.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/7824.05.jpg"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/7824.05.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/7824.05.jpg" alt="" border="0" /></a></p>
<p>Notice that in my sample execution the last upload should not be 32KB since the backup isn't 32KB-aligned. Our code, however, handles that:</p>
<p style="text-align: center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6558.06.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6558.06.jpg"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6558.06.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6558.06.jpg" alt="" border="0" /></a></p>
<p style="text-align: justify;">Notice that the last chunk is smaller than the previous ones. As usual, we can query the container to find our brand new blob (using the ListBlobs TVF):</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #800000; font-weight: bold;">SELECT</span> <span style="color: #808030;">*</span> <span style="color: #800000; font-weight: bold;">FROM</span> <span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>ListBlobs<span style="color: #808030;">(</span>
	<span style="color: #0000e6;">'your_account'</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'your_shared_key'</span><span style="color: #808030;">,</span> <span style="color: #008c00;">1</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'your_container'</span><span style="color: #808030;">,</span>
	<span style="color: #008c00;">1</span><span style="color: #808030;">,</span><span style="color: #008c00;">1</span><span style="color: #808030;">,</span><span style="color: #008c00;">1</span><span style="color: #808030;">,</span><span style="color: #008c00;">1</span><span style="color: #808030;">,</span>
	<span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>
</pre>
</div>
<p style="text-align: justify;">Here is our backup:</p>
<p style="text-align: center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4237.07.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4237.07.jpg"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4237.07.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4237.07.jpg" alt="" border="0" /></a></p>
<p style="text-align: justify;">You can try to download the blob using your browser (the URI is there for a reason!) and restore it. You will find that your backup was saved to the cloud successfully.</p>
<p style="text-align: justify;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4237.09.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4237.09.jpg"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/4237.09.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/4237.09.jpg" alt="" border="0" /></a>Last but not least, even though there is no MD5 show by the ListBlobs function each upload was MD5ed separately and checked server-side by azure. So, since every chunk is checksumed the whole file is checksumed as well :). Want to know how this is done by the library? Check the open source code in <a title="SQLServer2Azure CodePlex project" href="https://blogs.technet.com/controlpanel/blogs/posteditor.aspx/https:/sqlservertoazure.codeplex.com/">Microsoft SQL Server To Windows Azure helper library</a> project in CodePlex.</p>
<p style="text-align: justify;">&nbsp;Here is the complete script for this sample:</p>
<div style="overflow: scroll; font-size: 10pt;">
<pre><span style="color: #800000; font-weight: bold;">IF</span> <span style="color: #800000; font-weight: bold;">EXISTS</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">SELECT</span> <span style="color: #808030;">*</span> <span style="color: #800000; font-weight: bold;">FROM</span> tempdb<span style="color: #808030;">.</span><span style="color: #bb7977; font-weight: bold;">sys</span><span style="color: #808030;">.</span>objects <span style="color: #800000; font-weight: bold;">WHERE</span> name <span style="color: #808030;">=</span> <span style="color: #0000e6;">'##progressTable'</span><span style="color: #808030;">)</span>
<span style="color: #800000; font-weight: bold;">DROP</span> <span style="color: #800000; font-weight: bold;">TABLE</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable<span style="color: #808030;">;</span>

<span style="color: #800000; font-weight: bold;">SET</span> NOCOUNT <span style="color: #800000; font-weight: bold;">ON</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">BACKUP</span> <span style="color: #800000; font-weight: bold;">DATABASE</span> <span style="color: #808030;">[</span>AdventureWorks<span style="color: #808030;">]</span> <span style="color: #800000; font-weight: bold;">TO</span> <span style="color: #800000; font-weight: bold;">DISK</span><span style="color: #808030;">=</span><span style="color: #0000e6;">'C:\temp\AdventureWorks.bak'</span> <span style="color: #800000; font-weight: bold;">WITH</span> INIT<span style="color: #808030;">,</span> COMPRESSION<span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">GO</span>

<span style="color: #800000; font-weight: bold;">DECLARE</span> <span style="color: #797997;">@size</span> <span style="color: #800000; font-weight: bold;">BIGINT</span> <span style="color: #808030;">=</span> <span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>GetFileSizeBytes<span style="color: #808030;">(</span><span style="color: #0000e6;">'C:\temp\AdventureWorks.bak'</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>

<span style="color: #800000; font-weight: bold;">CREATE</span> <span style="color: #800000; font-weight: bold;">TABLE</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable<span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">ID</span> <span style="color: #800000; font-weight: bold;">INT</span> <span style="color: #800000; font-weight: bold;">IDENTITY</span><span style="color: #808030;">(</span><span style="color: #008c00;">1</span><span style="color: #808030;">,</span><span style="color: #008c00;">1</span><span style="color: #808030;">)</span> <span style="color: #800000; font-weight: bold;">PRIMARY</span> <span style="color: #800000; font-weight: bold;">KEY</span> <span style="color: #800000; font-weight: bold;">CLUSTERED</span><span style="color: #808030;">,</span> <span style="color: #800000; font-weight: bold;">Chunk</span> <span style="color: #800000; font-weight: bold;">INT</span> <span style="color: #800000; font-weight: bold;">NOT</span> <span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">,</span> OpStatus NVARCHAR<span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">MAX</span><span style="color: #808030;">)</span> <span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>

<span style="color: #800000; font-weight: bold;">DECLARE</span> <span style="color: #797997;">@PageCount</span> <span style="color: #800000; font-weight: bold;">INT</span> <span style="color: #808030;">=</span> <span style="color: #bb7977; font-weight: bold;">CEILING</span><span style="color: #808030;">(</span><span style="color: #bb7977; font-weight: bold;">CONVERT</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">FLOAT</span><span style="color: #808030;">,</span> <span style="color: #797997;">@size</span><span style="color: #808030;">)</span> <span style="color: #808030;">/</span> <span style="color: #808030;">(</span><span style="color: #008000;">1024.0</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>

<span style="color: #800000; font-weight: bold;">PRINT</span> <span style="color: #bb7977; font-weight: bold;">CONVERT</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">VARCHAR</span><span style="color: #808030;">,</span> <span style="color: #797997;">@pageCount</span><span style="color: #808030;">)</span> <span style="color: #808030;">+</span><span style="color: #0000e6;">' 32KB-pages to upload (total '</span> <span style="color: #808030;">+</span>  <span style="color: #bb7977; font-weight: bold;">CONVERT</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">VARCHAR</span><span style="color: #808030;">,</span> <span style="color: #797997;">@size</span><span style="color: #808030;">)</span> <span style="color: #808030;">+</span> <span style="color: #0000e6;">' bytes). Added '</span> <span style="color: #808030;">+</span> <span style="color: #bb7977; font-weight: bold;">CONVERT</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">VARCHAR</span><span style="color: #808030;">,</span><span style="color: #808030;">(</span><span style="color: #797997;">@PageCount</span><span style="color: #808030;">*</span><span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">)</span> <span style="color: #808030;">-</span> <span style="color: #797997;">@size</span><span style="color: #808030;">)</span> <span style="color: #808030;">+</span> <span style="color: #0000e6;">' bytes as padding.'</span><span style="color: #808030;">;</span>

<span style="color: #696969;">-- Prestage the progess table</span>
<span style="color: #800000; font-weight: bold;">DECLARE</span> <span style="color: #797997;">@iCnt</span> <span style="color: #800000; font-weight: bold;">INT</span> <span style="color: #808030;">=</span> <span style="color: #008c00;">0</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">WHILE</span> <span style="color: #797997;">@iCnt</span> <span style="color: #808030;">&lt;</span> <span style="color: #797997;">@pageCount</span> <span style="color: #800000; font-weight: bold;">BEGIN</span>
	<span style="color: #800000; font-weight: bold;">INSERT</span> <span style="color: #800000; font-weight: bold;">INTO</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable<span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">Chunk</span><span style="color: #808030;">,</span> OpStatus<span style="color: #808030;">)</span> <span style="color: #800000; font-weight: bold;">VALUES</span><span style="color: #808030;">(</span><span style="color: #797997;">@iCnt</span><span style="color: #808030;">,</span> <span style="color: #0000e6;">'ToUpload'</span><span style="color: #808030;">)</span>
	<span style="color: #800000; font-weight: bold;">SET</span> <span style="color: #797997;">@iCnt</span> <span style="color: #808030;">+</span><span style="color: #808030;">=</span> <span style="color: #008c00;">1</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">END</span>

<span style="color: #696969;">-- Create the "sparse" page blob.</span>
<span style="color: #800000; font-weight: bold;">EXEC</span> <span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>CreateOrReplacePageBlob    
	<span style="color: #0000e6;">'your_account'</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'your_shared_key'</span><span style="color: #808030;">,</span> <span style="color: #008c00;">1</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'your_container'</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'AdventureWorks.bak'</span><span style="color: #808030;">,</span>
	<span style="color: #797997;">@size</span>

<span style="color: #800000; font-weight: bold;">PRINT</span> <span style="color: #0000e6;">'"Sparse" blob created.'</span>

<span style="color: #800000; font-weight: bold;">DECLARE</span> <span style="color: #797997;">@pageNum</span> <span style="color: #800000; font-weight: bold;">INT</span><span style="color: #808030;">,</span> <span style="color: #797997;">@ID</span> <span style="color: #800000; font-weight: bold;">INT</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">DECLARE</span> <span style="color: #797997;">@len</span> <span style="color: #800000; font-weight: bold;">INT</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">WHILE</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">EXISTS</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">SELECT</span> <span style="color: #808030;">*</span> <span style="color: #800000; font-weight: bold;">FROM</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable <span style="color: #800000; font-weight: bold;">WHERE</span> OpStatus <span style="color: #800000; font-weight: bold;">IS</span> <span style="color: #800000; font-weight: bold;">NOT</span> <span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">)</span><span style="color: #808030;">)</span>
<span style="color: #800000; font-weight: bold;">BEGIN</span>
	<span style="color: #800000; font-weight: bold;">SELECT</span> <span style="color: #800000; font-weight: bold;">TOP</span> <span style="color: #008c00;">1</span> <span style="color: #797997;">@pageNum</span> <span style="color: #808030;">=</span> <span style="color: #800000; font-weight: bold;">Chunk</span><span style="color: #808030;">,</span> <span style="color: #797997;">@ID</span> <span style="color: #808030;">=</span> <span style="color: #800000; font-weight: bold;">ID</span> <span style="color: #800000; font-weight: bold;">FROM</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable <span style="color: #800000; font-weight: bold;">WHERE</span> OpStatus <span style="color: #800000; font-weight: bold;">IS</span> <span style="color: #800000; font-weight: bold;">NOT</span> <span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">;</span>

	<span style="color: #800000; font-weight: bold;">SET</span> <span style="color: #797997;">@len</span> <span style="color: #808030;">=</span> <span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">;</span>
	<span style="color: #800000; font-weight: bold;">IF</span> <span style="color: #808030;">(</span><span style="color: #808030;">(</span><span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">*</span><span style="color: #797997;">@pageNum</span><span style="color: #808030;">)</span><span style="color: #808030;">+</span><span style="color: #797997;">@len</span><span style="color: #808030;">)</span><span style="color: #808030;">&gt;</span><span style="color: #797997;">@size</span> 
		<span style="color: #800000; font-weight: bold;">SET</span> <span style="color: #797997;">@len</span> <span style="color: #808030;">=</span> <span style="color: #797997;">@size</span> <span style="color: #808030;">-</span><span style="color: #808030;">(</span><span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">*</span><span style="color: #797997;">@pageNum</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>

	<span style="color: #800000; font-weight: bold;">PRINT</span> <span style="color: #0000e6;">'Uploading page number '</span> <span style="color: #808030;">+</span> <span style="color: #bb7977; font-weight: bold;">CONVERT</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">VARCHAR</span><span style="color: #808030;">,</span> <span style="color: #797997;">@pageNum</span><span style="color: #808030;">)</span> <span style="color: #808030;">+</span> <span style="color: #0000e6;">'. '</span> <span style="color: #808030;">+</span>  <span style="color: #bb7977; font-weight: bold;">CONVERT</span><span style="color: #808030;">(</span><span style="color: #800000; font-weight: bold;">VARCHAR</span><span style="color: #808030;">,</span> <span style="color: #797997;">@len</span><span style="color: #808030;">)</span> <span style="color: #808030;">+</span> <span style="color: #0000e6;">' bytes to upload.'</span><span style="color: #808030;">;</span>

	<span style="color: #800000; font-weight: bold;">UPDATE</span> <span style="color: #808030;">#</span><span style="color: #808030;">#</span>progressTable <span style="color: #800000; font-weight: bold;">SET</span> OpStatus <span style="color: #808030;">=</span> <span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>PutPageFunction<span style="color: #808030;">(</span>
		<span style="color: #0000e6;">'your_account'</span><span style="color: #808030;">,</span>	<span style="color: #0000e6;">'your_shared_key'</span><span style="color: #808030;">,</span> <span style="color: #008c00;">1</span><span style="color: #808030;">,</span>
		<span style="color: #0000e6;">'your_container'</span><span style="color: #808030;">,</span>
		<span style="color: #0000e6;">'AdventureWorks.bak'</span><span style="color: #808030;">,</span>
		<span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>GetFileBlock<span style="color: #808030;">(</span>
			<span style="color: #0000e6;">'C:\temp\AdventureWorks.bak'</span><span style="color: #808030;">,</span>
			<span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">*</span><span style="color: #797997;">@pageNum</span><span style="color: #808030;">,</span>
			<span style="color: #797997;">@len</span><span style="color: #808030;">,</span>
			<span style="color: #0000e6;">'Read'</span><span style="color: #808030;">)</span><span style="color: #808030;">,</span>
		<span style="color: #008c00;">1024</span><span style="color: #808030;">*</span><span style="color: #008c00;">32</span><span style="color: #808030;">*</span><span style="color: #797997;">@pageNum</span><span style="color: #808030;">,</span>
		<span style="color: #797997;">@len</span><span style="color: #808030;">,</span>
		<span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">,</span>
		<span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">,</span>
		<span style="color: #008c00;">0</span><span style="color: #808030;">,</span>
		<span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">)</span>
	<span style="color: #800000; font-weight: bold;">WHERE</span> <span style="color: #800000; font-weight: bold;">ID</span> <span style="color: #808030;">=</span> <span style="color: #797997;">@ID</span><span style="color: #808030;">;</span>
<span style="color: #800000; font-weight: bold;">END</span>

<span style="color: #800000; font-weight: bold;">SELECT</span> <span style="color: #808030;">*</span> <span style="color: #800000; font-weight: bold;">FROM</span> <span style="color: #808030;">[</span>Azure<span style="color: #808030;">]</span><span style="color: #808030;">.</span>ListBlobs<span style="color: #808030;">(</span>
	<span style="color: #0000e6;">'your_account'</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'your_shared_key'</span><span style="color: #808030;">,</span> <span style="color: #008c00;">1</span><span style="color: #808030;">,</span>
	<span style="color: #0000e6;">'your_container'</span><span style="color: #808030;">,</span>
	<span style="color: #008c00;">1</span><span style="color: #808030;">,</span><span style="color: #008c00;">1</span><span style="color: #808030;">,</span><span style="color: #008c00;">1</span><span style="color: #808030;">,</span><span style="color: #008c00;">1</span><span style="color: #808030;">,</span>
	<span style="color: #800000; font-weight: bold;">NULL</span><span style="color: #808030;">)</span><span style="color: #808030;">;</span>
</pre>
</div>
<p style="text-align: justify;">&nbsp;</p>
<p><strong>Happy Coding,</strong></p>
<p><a title="Francesco Cogno" href="mailto:francesco.cogno@microsoft.com">Francesco Cogno</a></p>]]></content:encoded>
    </item>
    <item>
      <title>SQL Server To Windows Azure helper library - A SQL Server open source CodePlex project</title>
      <link>https://docs.microsoft.com/archive/blogs/italian_premier_center_for_sql_server/sql-server-to-windows-azure-helper-library-a-sql-server-open-source-codeplex-project</link>
      <pubDate>Wed, 13 Nov 2013 14:03:00 GMT</pubDate>
      <dc:creator><![CDATA[Italian Premier Center for SQL Server]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/italian_premier_center_for_sql_server/2013/11/13/sql-server-to-windows-azure-helper-library-a-sql-server-open-source-codeplex-project/</guid>
      <description><![CDATA[Hi all,
since my last SQLRally presentation in Amsterdam people kept asking for a working build of...]]></description>
      <content:encoded><![CDATA[<p style="text-align: justify;">Hi all,</p>
<p style="text-align: justify;">since my last SQLRally presentation in Amsterdam people kept asking for a working build of the SQLCLR Windows Azure REST API&nbsp; DLL. Many snippets of it can be found in this blog; however most of you don't really care about the implementation boilerplate. On the contrary, some of you might actually like to contribute to this library. In order to please everyone I've created - with the help of a fellow PFE Matteo Teruzzi - a GIT enabled open source&nbsp;project hosted on CodePlex. You can find it here (<a title="https://sqlservertoazure.codeplex.com/" href="https://sqlservertoazure.codeplex.com/">https://sqlservertoazure.codeplex.com/</a>).</p>
<p style="text-align: justify;">For those unfamiliar with CodePlex, just know that you can:</p>
<ol>
<li style="text-align: justify;">Download a precompiled DLL to import in your Database (easy). You can also download a sample script to test the library in a matter of minutes.</li>
<li style="text-align: justify;">Download the source code to build your own copy (I'll explain in a moment why you should do that).</li>
<li style="text-align: justify;">Just browse come class straight from your browser.</li>
<li style="text-align: justify;">Post comments!</li>
<li style="text-align: justify;">Create issue tasks for the community to correct.</li>
<li style="text-align: justify;">Start a discussion for a feature to implement.</li>
</ol>
<p style="text-align: justify;">Right now the project needs - badly - a proper documentation (as it is now there's just an empty page) and a bunch of willful testers.</p>
<p style="text-align: justify;">Please note that this is a pet project so I cannot guarantee any support. The full license is here (<a title="https://sqlservertoazure.codeplex.com/license" href="https://sqlservertoazure.codeplex.com/license">https://sqlservertoazure.codeplex.com/license</a>); it's a the standard Mozilla Public License Version 2.0.</p>
<hr style="width: 75%;" width="75%" />
<p style="text-align: justify;">As I said the library can be used in its compiled form. I, however, encourage you to build you own version.</p>
<p style="text-align: justify;">First of all you should replace the dummy <span style="color: #003300; font-family: courier new,courier;">snk</span> file with your own. This is fairly straightforward, all you have to do is to right click every library and change the strong name key file:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3225.00.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3225.00.jpg"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/3225.00.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/3225.00.jpg" alt="" border="0" /></a></p>
<p style="text-align: justify;">If you don't have a strong name key file you can generate one using the <span style="font-family: courier new,courier; color: #003300;">sn.exe</span> utility that ships with the Microsoft SDK. The syntax is just:</p>
<div style="overflow: scroll;">
<pre><span style="font-size: 12pt;"><code>sn -k &lt;output_file_name.snk&gt;</code></span></pre>
</div>
<p style="text-align: justify;">Second if you want to use the <span style="font-family: courier new,courier; color: #003300;">[Azure.Embedded]</span> schema you need to customize the <span style="color: #003300; font-family: courier new,courier;">Connections.xml</span> file embedded into the library:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6138.01.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6138.01.jpg"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/6138.01.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/6138.01.jpg" alt="" border="0" /></a></p>
<p style="text-align: justify;">As you can see in the image above there are two account already configured (a dummy one and the simulator). All you have to do is to add a Connection section for each account you want to be able to address without specifying all the parameters in the T-SQL (as I've done in my SQLRally presentation). For example, if you have an Azure Storage account called <span style="font-family: courier new,courier; color: #003300;">myazurestorageaccount</span> and one of your shared keys is <span style="font-family: courier new,courier; color: #003300;">Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==</span> you can add a section like this one:</p>
<div style="overflow: scroll; font-size: 12pt;">
<pre><span style="color: #a65700;">&lt;</span><span style="color: #5f5035;">Connection</span><span style="color: #a65700;">&gt;</span>
  <span style="color: #a65700;">&lt;</span><span style="color: #5f5035;">LogicalName</span><span style="color: #a65700;">&gt;</span>azurestorage<span style="color: #a65700;">&lt;/</span><span style="color: #5f5035;">LogicalName</span><span style="color: #a65700;">&gt;</span>
  <span style="color: #a65700;">&lt;</span><span style="color: #5f5035;">AccountName</span><span style="color: #a65700;">&gt;</span>myazurestorageaccount<span style="color: #a65700;">&lt;/</span><span style="color: #5f5035;">AccountName</span><span style="color: #a65700;">&gt;</span>
  <span style="color: #a65700;">&lt;</span><span style="color: #5f5035;">SharedKey</span><span style="color: #a65700;">&gt;</span>Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==<span style="color: #a65700;">&lt;/</span><span style="color: #5f5035;">SharedKey</span><span style="color: #a65700;">&gt;</span>
  <span style="color: #a65700;">&lt;</span><span style="color: #5f5035;">UseHTTPS</span><span style="color: #a65700;">&gt;</span>True<span style="color: #a65700;">&lt;/</span><span style="color: #5f5035;">UseHTTPS</span><span style="color: #a65700;">&gt;</span>
<span style="color: #a65700;">&lt;/</span><span style="color: #5f5035;">Connection</span><span style="color: #a65700;">&gt;</span>
</pre>
</div>
<div style="text-align: justify;">Recompile your library, import it into SQL Server and you should be able to call the <span style="color: #003300; font-family: courier new,courier;">[Azure.Embedded]</span> schema functions/SPs specifying <span style="font-family: courier new,courier; color: #003300;">azurestorage</span> as logical connection name.</div>
<div style="text-align: justify;"><strong>Note: </strong>you can find all those parameters in the Windows Azure management portal (<a title="https://manage.windowsazure.com" href="https://manage.windowsazure.com">https://manage.windowsazure.com</a>) clicking the "Manage Access Keys button" in the lower bar:</div>
<div style="text-align: center;"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/5102.02.jpg" original-url="https://blogs.technet.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/5102.02.jpg"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/prod.evol.blogs.technet.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/87/37/5102.02.jpg" original-url="https://blogs.technet.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-87-37/5102.02.jpg" alt="" border="0" /></a></div>
<div style="text-align: justify;">Third you might want to expose only a <em>few selected methods/SPs</em> instead of all of them. In order to do so all you have to do is to comment the relevant method in <span style="font-family: courier new,courier; color: #003300;">ITPCfSQL.Azure.CLR</span> and recompile.</div>
<div style="text-align: justify;"><strong>Happy coding,</strong></div>
<div style="text-align: justify;"><a title="Francesco Cogno" href="mailto:francesco.cogno@microsoft.com">Francesco Cogno</a></div>]]></content:encoded>
    </item>
  </channel>
</rss>