<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>generare-un-recordset-contenente &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/generare-un-recordset-contenente/</link>
	<description>Feed of posts on WordPress.com tagged "generare-un-recordset-contenente"</description>
	<pubDate>Thu, 03 Dec 2009 08:55:11 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Generare un recordset contenente tutti gli elementi di un intervallo in SQL Server 2005]]></title>
<link>http://gianfrasoft.wordpress.com/2008/04/13/generare-un-recordset-contenente-tutti-gli-elementi-di-un-intervallo-in-sql-server-2005/</link>
<pubDate>Sun, 13 Apr 2008 16:13:36 +0000</pubDate>
<dc:creator>gianfrasoft</dc:creator>
<guid>http://gianfrasoft.wordpress.com/2008/04/13/generare-un-recordset-contenente-tutti-gli-elementi-di-un-intervallo-in-sql-server-2005/</guid>
<description><![CDATA[Talvolta ci si trova a dover incrociare i dati di una query con le date di uno specifico intervallo.]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Talvolta ci si trova a dover incrociare i dati di una query con le date di uno specifico intervallo.</p>
<p>Ad esempio, consideriamo una tabella che contiene le vendite effettuate da un&#8217;azienda nell&#8217;arco di un anno: vogliamo rappresentare in un recordset gli importi totali delle vendite di ogni mese. La questione si risolve con un semplice raggruppamento dati, ammenocché non si voglia riportare un importo nullo <span style="text-decoration:underline;">anche in corrispondenza dei mesi in cui non sono state effettuate vendite</span>.</p>
<p>La soluzione ideale è quella di effettuare il raggruppamento dopo avere incrociato i dati delle vendite con un recordset contenente una riga per ciascuna data di inizio o di fine mese. Questo è possibile generando una tabella temporanea e popolandola, prima di effettuare la query sulle vendite.</p>
<p>Un&#8217;alternativa che agisca <em>on the fly</em> è quella basata sulle <strong>CTE</strong> ovvero <strong>Common Table Expression</strong>: le CTE consentono di effettuare query SQL di tipo ricorsivo, che è proprio quanto a noi serve.</p>
<p><!--more--></p>
<p>Nell&#8217;esempio seguente, ho realizzato uno script SQL che produce un recordset contenente tutte le date di tipo inizio mese che coprono il periodo che va dall&#8217;01/01/2007 all&#8217;01/01/2008:</p>
<pre><span style="font-family:Courier New;">WITH CTE(X)</span><span style="font-family:Courier New;">
AS</span><span style="font-family:Courier New;">
(</span><span style="font-family:Courier New;">
  SELECT X = convert(datetime, '20070101')</span><span style="font-family:Courier New;">
</span><span style="font-family:Courier New;"> </span><span style="font-family:Courier New;"> UNION ALL</span><span style="font-family:Courier New;">
</span><span style="font-family:Courier New;"> </span><span style="font-family:Courier New;"> SELECT X = DATEADD(month, 1, X) FROM CTE</span><span style="font-family:Courier New;">
</span><span style="font-family:Courier New;"> </span><span style="font-family:Courier New;">  WHERE X &#60; '20080101'</span><span style="font-family:Courier New;">
)</span><span style="font-family:Courier New;">
SELECT X FROM CTE</span>
<span style="font-family:Courier New;">ORDER BY X</span><span style="font-family:Courier New;">
</span></pre>
<p><span style="font-family:Courier New;"> </span></p>
<p>Il recordset X può facilmente essere messo in join nell&#8217;ambito dello script &#8220;SELECT X&#8230;&#8221;.</p>
<p>Da questo script è facile ricavare recordset contenenti, ad esempio, intervalli di numerazione progressiva ascendene o discendente.</p>
<p>Attenzione, però: testando questa query su intervalli di date che richiedono più di 100 ricorsioni ci s&#8217;imbatterà nel messaggio di errore: &#8220;Istruzione interrotta. Numero massimo di ricorsioni 100 esaurito prima del completamento dell&#8217;istruzione.&#8221;. Difatti, il numero massimo di ricorsioni possibili di default in SQL Server è limitato a 100. Per consentire alla query di superare questo limite basterà fissare un nuovo limite e dichiararlo nell&#8217;ambito della stessa interrogazione con l&#8217;opzione MAXRECURSION come di seguito riportato:</p>
<pre><span style="font-family:Courier New;">WITH CTE(X)</span><span style="font-family:Courier New;">
AS</span><span style="font-family:Courier New;">
(</span><span style="font-family:Courier New;">
  SELECT X = convert(datetime, '20070101')</span><span style="font-family:Courier New;">
</span><span style="font-family:Courier New;"> </span><span style="font-family:Courier New;"> UNION ALL</span><span style="font-family:Courier New;">
</span><span style="font-family:Courier New;"> </span><span style="font-family:Courier New;"> SELECT X = DATEADD(month, 1, X) FROM CTE</span><span style="font-family:Courier New;">
</span><span style="font-family:Courier New;"> </span><span style="font-family:Courier New;"> WHERE X &#60; '20200101'</span><span style="font-family:Courier New;">
)</span><span style="font-family:Courier New;">
SELECT X FROM CTE</span><span style="font-family:Courier New;">
ORDER BY X </span><span style="font-family:Courier New;">
O</span><span style="font-family:Courier New;">PTION (MAXRECURSION 500);</span><span style="font-family:Courier New;">
</span></pre>
<p>Nell&#8217;esempio appena descritto l&#8217;intervallo di date restituisce un recordset di 157 elementi e senza l&#8217;opzione di cui all&#8217;ultima riga andrebbe in errore.</p>
</div>]]></content:encoded>
</item>

</channel>
</rss>
