<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Thiago Zavaschi R2 &#187; CTE</title>
	<atom:link href="http://zavaschi.com/index.php/tag/cte/feed/" rel="self" type="application/rss+xml" />
	<link>http://zavaschi.com</link>
	<description>www.zavaschi.com</description>
	<lastBuildDate>Mon, 02 Jan 2012 16:51:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Entendendo as Common Table Expressions &#8211; CTE &#8211; Parte 3 (O Retorno)</title>
		<link>http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-3-o-retorno/</link>
		<comments>http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-3-o-retorno/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 12:24:12 +0000</pubDate>
		<dc:creator>Thiago Zavaschi</dc:creator>
				<category><![CDATA[Common Table Expression]]></category>
		<category><![CDATA[CTE]]></category>

		<guid isPermaLink="false">8DE5A8EFC1819ECA!399</guid>
		<description><![CDATA[Sabe quando você termina uma coisa, mas fica na cabeça de que esqueceu alguma coisa?
Poisé… alguns dos meus posts anteriores trataram de Common Table Expressions e eu não mencionei outra característica muito interessante.
Lembram que o result set da CTE só existe no escopo da query seguinte? Mas será que não é possivél eu ir juntando [...]]]></description>
			<content:encoded><![CDATA[<p>Sabe quando você termina uma coisa, mas fica na cabeça de que esqueceu alguma coisa?
<p>Poisé… alguns dos meus posts anteriores trataram de Common Table Expressions e eu não mencionei outra característica muito interessante.
<p>Lembram que o <em>result set</em> da CTE só existe no escopo da query seguinte? Mas será que não é possivél eu ir juntando várias CTE’s e no final fazer uma query que manipule o conjunto de todas?
<p>É sim! Vejam o seguinte exemplo: </p>
<div style="padding-bottom:0px;margin:0px;padding-left:0px;padding-right:0px;display:inline;float:none;padding-top:0px">
<pre style="background-color:WhiteSmoke;overflow:auto"><span style="color:#000000">;</span><span style="color:#0000FF">WITH</span><span style="color:#000000"> cteA(a)
</span><span style="color:#0000FF">AS</span><span style="color:#000000">
(
    </span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">1</span><span style="color:#000000">
    </span><span style="color:#0000FF">UNION</span><span style="color:#000000"> </span><span style="color:#808080">ALL</span><span style="color:#000000">
    </span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> a </span><span style="color:#808080">+</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">1</span><span style="color:#000000"> </span><span style="color:#0000FF">FROM</span><span style="color:#000000"> cteA </span><span style="color:#0000FF">WHERE</span><span style="color:#000000"> a </span><span style="color:#808080">&lt;</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">10</span><span style="color:#000000">
), cteB(b)
</span><span style="color:#0000FF">AS</span><span style="color:#000000">
(
    </span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">1</span><span style="color:#000000">
    </span><span style="color:#0000FF">UNION</span><span style="color:#000000"> </span><span style="color:#808080">ALL</span><span style="color:#000000">
    </span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> b </span><span style="color:#808080">+</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">1</span><span style="color:#000000"> </span><span style="color:#0000FF">FROM</span><span style="color:#000000"> cteB </span><span style="color:#0000FF">WHERE</span><span style="color:#000000"> b </span><span style="color:#808080">&lt;</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">10</span><span style="color:#000000">
), cteC(c)
</span><span style="color:#0000FF">AS</span><span style="color:#000000">
(
    </span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#800000;font-weight:bold">5</span><span style="color:#000000">
)
</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> ((</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#FF00FF">SUM</span><span style="color:#000000">(b) </span><span style="color:#0000FF">from</span><span style="color:#000000"> cteB) </span><span style="color:#808080">+</span><span style="color:#000000"> (</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#FF00FF">SUM</span><span style="color:#000000">(a) </span><span style="color:#0000FF">from</span><span style="color:#000000"> cteA)) </span><span style="color:#808080">/</span><span style="color:#000000">
((</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#FF00FF">COUNT</span><span style="color:#000000">(b) </span><span style="color:#0000FF">from</span><span style="color:#000000"> cteB) </span><span style="color:#808080">+</span><span style="color:#000000"> (</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> </span><span style="color:#FF00FF">COUNT</span><span style="color:#000000">(a) </span><span style="color:#0000FF">from</span><span style="color:#000000"> cteA)) </span><span style="color:#808080">*</span><span style="color:#000000">
(</span><span style="color:#0000FF">SELECT</span><span style="color:#000000"> c </span><span style="color:#0000FF">FROM</span><span style="color:#000000"> cteC)</span></pre>
</div>
<p>São 3 CTEs sendo executadas. O retorno das duas primeiras já nos é conhecido: é a contagem de 1 a 10 (visto no post anterior), e o retorno da última é 5, bastante trivial.</p>
<p>Esse post não serve apenas para demonstrar essa capacidade, mas também para alertar para os perigos que podem vir atrelados. </p>
<p>E o meu recado é: <strong><em>CUIDADO com a comodidade!</em></strong> Senão a legibilidade ganha com as CTEs de nada servirá. A explicação é facilmente observada através do plano de execução da query acima.</p>
<p><font size="2" face="Courier New">StmtText<br />----------------------------------------------------------------------------------------------------------------------<br />  |--Compute Scalar(DEFINE:([Expr1026]=(([Expr1004]+[Expr1010])/([Expr1016]+[Expr1022]))*(5)))<br />       |--Nested Loops(Inner Join)<br />            |--Nested Loops(Inner Join)<br />            |    |--Nested Loops(Inner Join)<br />            |    |    |--Compute Scalar(DEFINE:([Expr1004]=CASE WHEN [Expr1045]=(0) THEN NULL ELSE [Expr1046] END))<br />            |    |    |    |--Stream Aggregate(DEFINE:([Expr1045]=COUNT_BIG([Recr1003]), [Expr1046]=SUM([Recr1003])))<br />            |    |    |         |--Index Spool(WITH STACK)<br />            |    |    |              |--Concatenation<br />            |    |    |                   |--Compute Scalar(DEFINE:([Expr1041]=(0)))<br />            |    |    |                   |    |--Constant Scan(VALUES:(((1))))<br />            |    |    |                   |--Assert(WHERE:(CASE WHEN [Expr1043]&gt;(100) THEN (0) ELSE NULL END))<br />            |    |    |                        |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1043], [Recr1001]))<br />            |    |    |                             |--Compute Scalar(DEFINE:([Expr1043]=[Expr1042]+(1)))<br />            |    |    |                             |    |--Table Spool(WITH STACK)<br />            |    |    |                             |--Compute Scalar(DEFINE:([Expr1002]=[Recr1001]+(1)))<br />            |    |    |                                  |--Filter(WHERE:(STARTUP EXPR([Recr1001]&lt;(10))))<br />            |    |    |                                       |--Constant Scan<br />            |    |    |--Compute Scalar(DEFINE:([Expr1022]=CONVERT_IMPLICIT(int,[Expr1051],0)))<br />            |    |         |--Stream Aggregate(DEFINE:([Expr1051]=COUNT([Recr1021])))<br />            |    |              |--Index Spool(WITH STACK)<br />            |    |                   |--Concatenation<br />            |    |                        |--Compute Scalar(DEFINE:([Expr1047]=(0)))<br />            |    |                        |    |--Constant Scan(VALUES:(((1))))<br />            |    |                        |--Assert(WHERE:(CASE WHEN [Expr1049]&gt;(100) THEN (0) ELSE NULL END))<br />            |    |                             |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1049], [Recr1019]))<br />            |    |                                  |--Compute Scalar(DEFINE:([Expr1049]=[Expr1048]+(1)))<br />            |    |                                  |    |--Table Spool(WITH STACK)<br />            |    |                                  |--Compute Scalar(DEFINE:([Expr1020]=[Recr1019]+(1)))<br />            |    |                                       |--Filter(WHERE:(STARTUP EXPR([Recr1019]&lt;(10))))<br />            |    |                                            |--Constant Scan<br />            |    |--Compute Scalar(DEFINE:([Expr1016]=CONVERT_IMPLICIT(int,[Expr1056],0)))<br />            |         |--Stream Aggregate(DEFINE:([Expr1056]=COUNT([Recr1015])))<br />            |              |--Index Spool(WITH STACK)<br />            |                   |--Concatenation<br />            |                        |--Compute Scalar(DEFINE:([Expr1052]=(0)))<br />            |                        |    |--Constant Scan(VALUES:(((1))))<br />            |                        |--Assert(WHERE:(CASE WHEN [Expr1054]&gt;(100) THEN (0) ELSE NULL END))<br />            |                             |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1054], [Recr1013]))<br />            |                                  |--Compute Scalar(DEFINE:([Expr1054]=[Expr1053]+(1)))<br />            |                                  |    |--Table Spool(WITH STACK)<br />            |                                  |--Compute Scalar(DEFINE:([Expr1014]=[Recr1013]+(1)))<br />            |                                       |--Filter(WHERE:(STARTUP EXPR([Recr1013]&lt;(10))))<br />            |                                            |--Constant Scan<br />            |--Compute Scalar(DEFINE:([Expr1010]=CASE WHEN [Expr1061]=(0) THEN NULL ELSE [Expr1062] END))<br />                 |--Stream Aggregate(DEFINE:([Expr1061]=COUNT_BIG([Recr1009]), [Expr1062]=SUM([Recr1009])))<br />                      |--Index Spool(WITH STACK)<br />                           |--Concatenation<br />                                |--Compute Scalar(DEFINE:([Expr1057]=(0)))<br />                                |    |--Constant Scan(VALUES:(((1))))<br />                                |--Assert(WHERE:(CASE WHEN [Expr1059]&gt;(100) THEN (0) ELSE NULL END))<br />                                     |--Nested Loops(Inner Join, OUTER REFERENCES:([Expr1059], [Recr1007]))<br />                                          |--Compute Scalar(DEFINE:([Expr1059]=[Expr1058]+(1)))<br />                                          |    |--Table Spool(WITH STACK)<br />                                          |--Compute Scalar(DEFINE:([Expr1008]=[Recr1007]+(1)))<br />                                               |--Filter(WHERE:(STARTUP EXPR([Recr1007]&lt;(10))))<br />                                                    |--Constant Scan </font></p>
<p>Poisé, é executado tudo separado. Se houverem processamento desnecessários nas CTEs, poderemos encontrar sérios gargalos nestas querys!</p>
<p>Então pessoal, era mais isso que eu queria mostrar deste fantástico recurso! Usem CTE’s, e para os que usarem, usem sabendo como funcionam! :)</p>
<p>E para quem não acompanhou, segue os links dos posts anteriores:</p>
<h6>Entendendo as Common Table Expressions – CTE – Parte 1</h6>
<p><a title="http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!390.entry" href="http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!390.entry">http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!390.entry</a></p>
<h6>Entendendo as Common Table Expressions – CTE – Parte 2 (Final)</h6>
<p><a title="http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!391.entry" href="http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!391.entry">http://thiagozavaschi.spaces.live.com/blog/cns!8DE5A8EFC1819ECA!391.entry</a></p>
<p>Abraços,<br />Thiago Zavaschi</p>
]]></content:encoded>
			<wfw:commentRss>http://zavaschi.com/index.php/2009/09/entendendo-as-common-table-expressions-cte-parte-3-o-retorno/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Repostagem &#8211; Fun&#231;&#227;o Split no SQL Server</title>
		<link>http://zavaschi.com/index.php/2009/06/repostagem-funo-split-no-sql-server/</link>
		<comments>http://zavaschi.com/index.php/2009/06/repostagem-funo-split-no-sql-server/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 22:49:00 +0000</pubDate>
		<dc:creator>Thiago Zavaschi</dc:creator>
				<category><![CDATA[Common Table Expression]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[CTE]]></category>
		<category><![CDATA[Function]]></category>
		<category><![CDATA[Split]]></category>

		<guid isPermaLink="false">http://zavaschi.com/?p=33</guid>
		<description><![CDATA[&#160;
Então pessoal, atenção que é uma repostagem! O post sobre Common Table Expressions (CTE) e recursividade já está postado! O de CLR ainda não hehe, mas um dia cumpro todas as promessas!
Função Split no SQL Server
Uma função que sempre senti falta no SQL Server é uma função para split, aonde passaríamos dois parâmetros: 


Frase a [...]]]></description>
			<content:encoded><![CDATA[<h6>&#160;</h6>
<p>Então pessoal, atenção que é uma repostagem! O post sobre Common Table Expressions (CTE) e recursividade já está postado! O de CLR ainda não hehe, mas um dia cumpro todas as promessas!</p>
<h6>Função Split no SQL Server</h6>
<p>Uma função que sempre senti falta no SQL Server é uma função para split, aonde passaríamos dois parâmetros: </p>
<ul>
<ul>
<li>Frase a ser “splitada”. </li>
<li>Delimitador. </li>
</ul>
</ul>
<p>E teríamos uma lista de palavras originadas da frase passada, separada em cada delimitador. </p>
<p>Já desenvolvi várias versões para fazer split, mas a que considero a melhor (e também bastante popular) é a seguinte: </p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:1ab03585-99ae-4fae-bb20-c5f66b7edd1d" class="wlWriterEditableSmartContent">
<pre style="background-color:White;overflow: auto;"><span style="color: #0000FF;">CREATE</span><span style="color: #000000;"> </span><span style="color: #0000FF;">FUNCTION</span><span style="color: #000000;"> dbo.fnSplit(
    </span><span style="color: #008000;">@frase</span><span style="color: #000000;"> </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #FF00FF;">max</span><span style="color: #000000;">)
  , </span><span style="color: #008000;">@delimitador</span><span style="color: #000000;"> </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #FF00FF;">max</span><span style="color: #000000;">) </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF0000;">'</span><span style="color: #FF0000;">,</span><span style="color: #FF0000;">'</span><span style="color: #000000;">
) </span><span style="color: #0000FF;">RETURNS</span><span style="color: #000000;"> </span><span style="color: #008000;">@result</span><span style="color: #000000;"> </span><span style="color: #0000FF;">TABLE</span><span style="color: #000000;"> (item </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">8000</span><span style="color: #000000;">)) 

</span><span style="color: #0000FF;">BEGIN</span><span style="color: #000000;">
</span><span style="color: #0000FF;">DECLARE</span><span style="color: #000000;"> </span><span style="color: #008000;">@parte</span><span style="color: #000000;"> </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">8000</span><span style="color: #000000;">)
</span><span style="color: #0000FF;">WHILE</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@delimitador</span><span style="color: #000000;">,</span><span style="color: #008000;">@frase</span><span style="color: #000000;">,</span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">) </span><span style="color: #808080;">&lt;&gt;</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">
</span><span style="color: #0000FF;">BEGIN</span><span style="color: #000000;">
</span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;">
  </span><span style="color: #008000;">@parte</span><span style="color: #808080;">=</span><span style="color: #FF00FF;">RTRIM</span><span style="color: #000000;">(</span><span style="color: #FF00FF;">LTRIM</span><span style="color: #000000;">(
          </span><span style="color: #FF00FF;">SUBSTRING</span><span style="color: #000000;">(</span><span style="color: #008000;">@frase</span><span style="color: #000000;">,</span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">,
        </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@delimitador</span><span style="color: #000000;">,</span><span style="color: #008000;">@frase</span><span style="color: #000000;">,</span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">)</span><span style="color: #808080;">-</span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">))),
  </span><span style="color: #008000;">@frase</span><span style="color: #808080;">=</span><span style="color: #FF00FF;">RTRIM</span><span style="color: #000000;">(</span><span style="color: #FF00FF;">LTRIM</span><span style="color: #000000;">(</span><span style="color: #FF00FF;">SUBSTRING</span><span style="color: #000000;">(</span><span style="color: #008000;">@frase</span><span style="color: #000000;">,
          </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@delimitador</span><span style="color: #000000;">,</span><span style="color: #008000;">@frase</span><span style="color: #000000;">,</span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">)
        </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">LEN</span><span style="color: #000000;">(</span><span style="color: #008000;">@delimitador</span><span style="color: #000000;">), </span><span style="color: #FF00FF;">LEN</span><span style="color: #000000;">(</span><span style="color: #008000;">@frase</span><span style="color: #000000;">))))
</span><span style="color: #0000FF;">IF</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">LEN</span><span style="color: #000000;">(</span><span style="color: #008000;">@parte</span><span style="color: #000000;">) </span><span style="color: #808080;">&gt;</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">
  </span><span style="color: #0000FF;">INSERT</span><span style="color: #000000;"> </span><span style="color: #0000FF;">INTO</span><span style="color: #000000;"> </span><span style="color: #008000;">@result</span><span style="color: #000000;"> </span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> </span><span style="color: #008000;">@parte</span><span style="color: #000000;">
</span><span style="color: #0000FF;">END</span><span style="color: #000000;"> 

</span><span style="color: #0000FF;">IF</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">LEN</span><span style="color: #000000;">(</span><span style="color: #008000;">@frase</span><span style="color: #000000;">) </span><span style="color: #808080;">&gt;</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">
</span><span style="color: #0000FF;">INSERT</span><span style="color: #000000;"> </span><span style="color: #0000FF;">INTO</span><span style="color: #000000;"> </span><span style="color: #008000;">@result</span><span style="color: #000000;"> </span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> </span><span style="color: #008000;">@frase</span><span style="color: #000000;">
</span><span style="color: #0000FF;">RETURN</span><span style="color: #000000;">
</span><span style="color: #0000FF;">END</span><span style="color: #000000;">
</span><span style="color: #0000FF;">GO</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>Para testar é simples: </p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:a77f7edc-8e66-4e02-b664-c70e3b17ce5e" class="wlWriterEditableSmartContent">
<pre style="background-color:#F9F9F9;overflow: auto;"><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> </span><span style="color: #808080;">*</span><span style="color: #000000;"> </span><span style="color: #0000FF;">FROM</span><span style="color: #000000;"> dbo.fnSplit(</span><span style="color: #FF0000;">'</span><span style="color: #FF0000;">separar por espaço em branco</span><span style="color: #FF0000;">'</span><span style="color: #000000;">, </span><span style="color: #FF0000;">'</span><span style="color: #FF0000;"> </span><span style="color: #FF0000;">'</span><span style="color: #000000;">)</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>---- </p>
<p>Se desejar, há outra forma, utilizando tabela temporária, sem função: </p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:45097557-44c2-47f4-b23a-0e2badb17d77" class="wlWriterEditableSmartContent">
<pre style="background-color:White;overflow: auto;"><span style="color: #0000FF;">SET</span><span style="color: #000000;"> NOCOUNT </span><span style="color: #0000FF;">ON</span><span style="color: #000000;">
</span><span style="color: #0000FF;">DECLARE</span><span style="color: #000000;"> </span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;"> </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">8000</span><span style="color: #000000;">), </span><span style="color: #008000;">@DELIMITADOR</span><span style="color: #000000;"> </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">100</span><span style="color: #000000;">), </span><span style="color: #008000;">@S</span><span style="color: #000000;"> </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">8000</span><span style="color: #000000;">)  

</span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> </span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;"> </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF0000;">'</span><span style="color: #FF0000;">separar por espaço em branco</span><span style="color: #FF0000;">'</span><span style="color: #000000;">
</span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> </span><span style="color: #008000;">@DELIMITADOR</span><span style="color: #000000;"> </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF0000;">'</span><span style="color: #FF0000;"> </span><span style="color: #FF0000;">'</span><span style="color: #000000;">  

</span><span style="color: #0000FF;">IF</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">LEN</span><span style="color: #000000;">(</span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;">) </span><span style="color: #808080;">&gt;</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;"> </span><span style="color: #0000FF;">SET</span><span style="color: #000000;"> </span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;"> </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;"> </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #008000;">@DELIMITADOR</span><span style="color: #000000;">
</span><span style="color: #0000FF;">CREATE</span><span style="color: #000000;"> </span><span style="color: #0000FF;">TABLE</span><span style="color: #000000;"> #ARRAY(ITEM_ARRAY </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">8000</span><span style="color: #000000;">))  

</span><span style="color: #0000FF;">WHILE</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">LEN</span><span style="color: #000000;">(</span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;">) </span><span style="color: #808080;">&gt;</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">
</span><span style="color: #0000FF;">BEGIN</span><span style="color: #000000;">
    </span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> </span><span style="color: #008000;">@S</span><span style="color: #000000;"> </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">LTRIM</span><span style="color: #000000;">(</span><span style="color: #FF00FF;">SUBSTRING</span><span style="color: #000000;">(</span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;">, </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">,
    </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@DELIMITADOR</span><span style="color: #000000;">, </span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;">) </span><span style="color: #808080;">-</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">))
    </span><span style="color: #0000FF;">INSERT</span><span style="color: #000000;"> </span><span style="color: #0000FF;">INTO</span><span style="color: #000000;"> #ARRAY (ITEM_ARRAY) </span><span style="color: #0000FF;">VALUES</span><span style="color: #000000;"> (</span><span style="color: #008000;">@S</span><span style="color: #000000;">)
    </span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> </span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;"> </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">SUBSTRING</span><span style="color: #000000;">(</span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;">,
    </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@DELIMITADOR</span><span style="color: #000000;">, </span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;">) </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">, </span><span style="color: #FF00FF;">LEN</span><span style="color: #000000;">(</span><span style="color: #008000;">@ARRAY</span><span style="color: #000000;">))
</span><span style="color: #0000FF;">END</span><span style="color: #000000;">  

</span><span style="color: #008080;">--</span><span style="color: #008080;"> MOSTRANDO O RESULTADO JÁ POPULADO NA TABELA TEMPORÁRIA  </span><span style="color: #008080;">
</span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> </span><span style="color: #808080;">*</span><span style="color: #000000;"> </span><span style="color: #0000FF;">FROM</span><span style="color: #000000;"> #ARRAY
</span><span style="color: #0000FF;">DROP</span><span style="color: #000000;"> </span><span style="color: #0000FF;">TABLE</span><span style="color: #000000;"> #ARRAY
</span><span style="color: #0000FF;">SET</span><span style="color: #000000;"> NOCOUNT </span><span style="color: #0000FF;">OFF</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>&#160;</p>
<p>Simples não?<br />
  <br />Estas maneiras mostradas resolvem a necessidade da falta do split? Sim! </p>
<p>Porém, desde o SQL Server 2005 temos o recurso das CTEs (Common Table Expression), que também podem ser utilizadas para split. A seguir mostro o exemplo que considero mais elegante para tal tarefa, utiliza recursividade ao invés do loop: </p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:8657ef61-b854-4cb2-a53b-944ba3677ec0" class="wlWriterEditableSmartContent">
<pre style="background-color:White;overflow: auto;"><span style="color: #0000FF;">DECLARE</span><span style="color: #000000;"> </span><span style="color: #008000;">@s</span><span style="color: #000000;"> </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">8000</span><span style="color: #000000;">), </span><span style="color: #008000;">@d</span><span style="color: #000000;"> </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">10</span><span style="color: #000000;">)
</span><span style="color: #0000FF;">SET</span><span style="color: #000000;"> </span><span style="color: #008000;">@s</span><span style="color: #000000;"> </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF0000;">'</span><span style="color: #FF0000;">separar por espaço em branco</span><span style="color: #FF0000;">'</span><span style="color: #000000;">
</span><span style="color: #0000FF;">SET</span><span style="color: #000000;"> </span><span style="color: #008000;">@d</span><span style="color: #000000;"> </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF0000;">'</span><span style="color: #FF0000;"> </span><span style="color: #FF0000;">'</span><span style="color: #000000;"> 

;</span><span style="color: #0000FF;">WITH</span><span style="color: #000000;"> split(i,j) </span><span style="color: #0000FF;">AS</span><span style="color: #000000;">
(
</span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> i </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">, j </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@d</span><span style="color: #000000;">, </span><span style="color: #008000;">@s</span><span style="color: #000000;"> </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #008000;">@d</span><span style="color: #000000;">)
</span><span style="color: #0000FF;">UNION</span><span style="color: #000000;"> </span><span style="color: #808080;">ALL</span><span style="color: #000000;">
</span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> i </span><span style="color: #808080;">=</span><span style="color: #000000;"> j </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">, j </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@d</span><span style="color: #000000;">, </span><span style="color: #008000;">@s</span><span style="color: #000000;"> </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #008000;">@d</span><span style="color: #000000;">, j </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">) </span><span style="color: #0000FF;">FROM</span><span style="color: #000000;"> split
   </span><span style="color: #0000FF;">WHERE</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@d</span><span style="color: #000000;">, </span><span style="color: #008000;">@s</span><span style="color: #000000;"> </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #008000;">@d</span><span style="color: #000000;">, j </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">) </span><span style="color: #808080;">&lt;&gt;</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">
)
</span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">SUBSTRING</span><span style="color: #000000;">(</span><span style="color: #008000;">@s</span><span style="color: #000000;">,i,j</span><span style="color: #808080;">-</span><span style="color: #000000;">i)
</span><span style="color: #0000FF;">FROM</span><span style="color: #000000;"> split
</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p><strong></strong></p>
<p><strong>Observação importante sobre CTEs</strong>: </p>
<p>Ao utilizar CTEs recursivas devemos tomar cuidado com o número máximo de recursões permitidas. </p>
<p>Por padrão esse número é igual a 100. Isso na prática significa que eu só poderia ter 100 delimitadores dentro da minha variável @s. </p>
<p>Caso a recursão máxima seja alcançada, termos uma mensagem igual a essa: </p>
<p>“The statement terminated. The maximum recursion 100 has been exhausted before statement completion.”</p>
<p>Para aumentar este valor, podemos acionar um parâmetro extra para a CTE: maxrecursion. </p>
<p>Na prática, para trocar a recursão máxima para 1000, devemos fazer: </p>
<div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:57F11A72-B0E5-49c7-9094-E3A15BD5B5E6:ccfe6edb-541a-48b5-bc10-409dbdb19740" class="wlWriterEditableSmartContent">
<pre style="background-color:White;overflow: auto;"><span style="color: #0000FF;">DECLARE</span><span style="color: #000000;"> </span><span style="color: #008000;">@s</span><span style="color: #000000;"> </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">8000</span><span style="color: #000000;">), </span><span style="color: #008000;">@d</span><span style="color: #000000;"> </span><span style="color: #0000FF;">VARCHAR</span><span style="color: #000000;">(</span><span style="color: #800000; font-weight: bold;">10</span><span style="color: #000000;">)
</span><span style="color: #0000FF;">SET</span><span style="color: #000000;"> </span><span style="color: #008000;">@s</span><span style="color: #000000;"> </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF0000;">'</span><span style="color: #FF0000;">separar por espaço em branco</span><span style="color: #FF0000;">'</span><span style="color: #000000;">
</span><span style="color: #0000FF;">SET</span><span style="color: #000000;"> </span><span style="color: #008000;">@d</span><span style="color: #000000;"> </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF0000;">'</span><span style="color: #FF0000;"> </span><span style="color: #FF0000;">'</span><span style="color: #000000;"> 

;</span><span style="color: #0000FF;">WITH</span><span style="color: #000000;"> split(i,j) </span><span style="color: #0000FF;">AS</span><span style="color: #000000;">
(
</span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> i </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">, j </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@d</span><span style="color: #000000;">, </span><span style="color: #008000;">@s</span><span style="color: #000000;"> </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #008000;">@d</span><span style="color: #000000;">)
</span><span style="color: #0000FF;">UNION</span><span style="color: #000000;"> </span><span style="color: #808080;">ALL</span><span style="color: #000000;">
</span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> i </span><span style="color: #808080;">=</span><span style="color: #000000;"> j </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">, j </span><span style="color: #808080;">=</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@d</span><span style="color: #000000;">, </span><span style="color: #008000;">@s</span><span style="color: #000000;"> </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #008000;">@d</span><span style="color: #000000;">, j </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">) </span><span style="color: #0000FF;">FROM</span><span style="color: #000000;"> split
   </span><span style="color: #0000FF;">WHERE</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">CHARINDEX</span><span style="color: #000000;">(</span><span style="color: #008000;">@d</span><span style="color: #000000;">, </span><span style="color: #008000;">@s</span><span style="color: #000000;"> </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #008000;">@d</span><span style="color: #000000;">, j </span><span style="color: #808080;">+</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">1</span><span style="color: #000000;">) </span><span style="color: #808080;">&lt;&gt;</span><span style="color: #000000;"> </span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">
)
</span><span style="color: #0000FF;">SELECT</span><span style="color: #000000;"> </span><span style="color: #FF00FF;">SUBSTRING</span><span style="color: #000000;">(</span><span style="color: #008000;">@s</span><span style="color: #000000;">,i,j</span><span style="color: #808080;">-</span><span style="color: #000000;">i)
</span><span style="color: #0000FF;">FROM</span><span style="color: #000000;"> split
</span><span style="color: #0000FF;">OPTION</span><span style="color: #000000;"> (maxrecursion </span><span style="color: #800000; font-weight: bold;">1000</span><span style="color: #000000;">)</span></pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>&#160;</p>
<p>O valor máximo para o parâmetro MAXRECURSION é de 32767, então fiquem atentos. Caso seja necessário uma CTE recursiva com mais de 32767 iterações, então devemos pensar numa estratégia para executar mais de um split (ou mais de uma vez a operação desejada) por iteração. Em casos muito específicos, podemos deixar o máximo de recursão infinito (MAXRECURSION = 0).</p>
<p>Não entendeu muito bem o que é uma CTE? Pode recorrer ao BOL, ou esperar o meu próximo post (há este e o de cursores para postar) que abordarei BEM detalhadamente o que é uma CTE, sintaxe, como funciona, seus usos comuns, e a questão de como funciona a recursividade. Então fiquem atentos!&#160; </p>
<p>--- </p>
<p>Depois destas três maneiras mostradas, ainda há uma quarta possibilidade (a partir do SQL Server 2005 também) que é utilizar as chamadas Functions CLR (programadas em C# por exemplo). O por quê? Porque operações em strings são custosas para o SQL Server, então uma função CLR poderia se comportar de maneira muito interessante (performática) neste caso. </p>
<p>Também não sabe o que é CLR ou como funciona? Então aguarde os próximos posts também! </p>
<p>Mas eu ainda continuo na esperança de algum dia termos isso diretamente no SQL Server, de uma maneira mais otimizada. :) </p>
<p>Abraços,<br />
  <br />Thiago Zavaschi</p>
]]></content:encoded>
			<wfw:commentRss>http://zavaschi.com/index.php/2009/06/repostagem-funo-split-no-sql-server/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

