<?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>Diário de um DBA &#187; comparar</title>
	<atom:link href="http://silasmendes.com/dba/tag/comparar/feed" rel="self" type="application/rss+xml" />
	<link>http://silasmendes.com/dba</link>
	<description>Tecnologia &#38; Banco de Dados</description>
	<lastBuildDate>Tue, 27 Dec 2011 12:53:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>T-SQL &#8211; Mesclando dados</title>
		<link>http://silasmendes.com/dba/t-sql-mesclando-dados</link>
		<comments>http://silasmendes.com/dba/t-sql-mesclando-dados#comments</comments>
		<pubDate>Fri, 10 Sep 2010 15:01:51 +0000</pubDate>
		<dc:creator>Silas Mendes</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Vida Real]]></category>
		<category><![CDATA[comparar]]></category>
		<category><![CDATA[Juntar]]></category>
		<category><![CDATA[MERGE]]></category>
		<category><![CDATA[Mesclar]]></category>
		<category><![CDATA[Sincronizar]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[T-SQL]]></category>

		<guid isPermaLink="false">http://silasmendes.com/dba/?p=660</guid>
		<description><![CDATA[O SQL Server 2008 trouxe para o T-SQL um comando brilhante que realmente facilita a vida de muita gente; o comando em questão é o MERGE. A idéia deste comando é mesclar dados, logo você pode comparar duas tabelas e utilizar o comando MERGE para sincronizá-las. Vamos a um exemplo simples: Primeiro criamos duas tabelas [...]]]></description>
			<content:encoded><![CDATA[<p>O SQL Server 2008 trouxe para o T-SQL um comando brilhante que realmente facilita a vida de muita gente; o comando em questão é o MERGE. A idéia deste comando é mesclar dados, logo você pode comparar duas tabelas e utilizar o comando MERGE para sincronizá-las.</p>
<p>Vamos a um exemplo simples:</p>
<p>Primeiro criamos duas tabelas com estrutura idêntica. A chave primária destas tabelas é o campo CPF:</p>
<pre class="brush: sql; title: ; notranslate">
create table Tabela1 (
Nome varchar(50),
Idade int,
CPF char(11) primary key);

create table Tabela2 (
Nome varchar(50),
Idade int,
CPF char(11) primary key);
</pre>
<p>Agora inserimos dados nas tabelas. Observe que os dados estão diferentes, alguns tem diferença no nome, outros registros estão sobrando ou faltando em ambas tabelas:</p>
<pre class="brush: sql; title: ; notranslate">
insert into Tabela1 values
('Silas Mendes' , 29, '08148338716'),
('Maria José'   , 49, '55978913269'),
('Pedro Ribeiro', 53, '05899714732'),
('Joana Silva'  , 18, '74105689623');

insert into Tabela2 values
('SILAS Mendes'       , 29, '08148338716'),
('Maria Jose'         , 49, '55978913269'),
('Pedro Ribeiro Souza', 53, '05899714732'),
('Carlos Mania'       , 19, '12345678999');
</pre>
<p>Agora precisamos sincronizar as tabelas, vamos analisar passo-a-passo a construção do comando MERGE (o comando completo está disponível no fim do texto) .</p>
<p>A tabela de destino (target) é a <strong>tabela2</strong>; a tabela de origem (source) é a <strong>tabela1. </strong>A chave primária das tabelas será utilizada na comparação:</p>
<pre class="brush: sql; title: ; notranslate">
merge into tabela2 as target
using (select nome, idade, cpf from tabela1)
  as source (nome, idade, cpf)
  on (target.cpf = source.cpf)
</pre>
<p>Quando os números dos CPFs forem encontrados em ambas tabelas então atualizamos os dados na tabela alvo (target):</p>
<pre class="brush: sql; title: ; notranslate">
when matched then
		 update set target.nome = source.nome,
					target.idade = source.idade,
					target.cpf = source.cpf
</pre>
<p>Quando os números dos CPFs não forem encontrados na tabela de destino, então inserimos os dados da tabela de origem:</p>
<pre class="brush: sql; title: ; notranslate">
when not matched by target then
		 insert (nome, idade, cpf) values (nome, idade, cpf)
</pre>
<p>E finalmente, quando existirem números de CPFs no destino que não existem na origem, apagamos os registros que sobram:</p>
<pre class="brush: sql; title: ; notranslate">
when not matched by source then
		 delete;
</pre>
<p>Veja o código completo do comando MERGE:</p>
<pre class="brush: sql; title: ; notranslate">
merge into tabela2 as target
using (select nome, idade, cpf from tabela1)
  as source (nome, idade, cpf)
  on (target.cpf = source.cpf)

-- Atualiza registros diferentes
when matched then
		 update set target.nome = source.nome,
					target.idade = source.idade,
					target.cpf = source.cpf

-- Insere registros que não existem no destino
when not matched by target then
		 insert (nome, idade, cpf) values (nome, idade, cpf)

-- Se existir no destino e não existir na origem é apagado
when not matched by source then
		 delete;
</pre>
<p>Por fim realizamos o SELECT nas duas tabelas para verificar o resultado após a sincronização:</p>
<pre class="brush: sql; title: ; notranslate">

select * from Tabela1;
select * from Tabela2;
</pre>
<p><a href="http://silasmendes.com/dba/wp-content/uploads/2010/09/MERGE_Resultado.png"><img class="aligncenter size-full wp-image-673" title="MERGE_Resultado" src="http://silasmendes.com/dba/wp-content/uploads/2010/09/MERGE_Resultado.png" alt="" width="246" height="247" /></a></p>
<div>Bom trabalho, bom estudo!</div>
<div><span style="font-size: 12.0pt; font-family: &amp;amp;amp; mso-fareast-font-family: &amp;amp;amp; mso-ansi-language: PT-BR; mso-fareast-language: PT-BR; mso-bidi-language: AR-SA;"><br />
</span></div>
]]></content:encoded>
			<wfw:commentRss>http://silasmendes.com/dba/t-sql-mesclando-dados/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comparando text / ntext</title>
		<link>http://silasmendes.com/dba/comparando-text-ntext</link>
		<comments>http://silasmendes.com/dba/comparando-text-ntext#comments</comments>
		<pubDate>Mon, 18 Aug 2008 17:13:31 +0000</pubDate>
		<dc:creator>Silas Mendes</dc:creator>
				<category><![CDATA[Dicas]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[SQL SERVER 2000]]></category>
		<category><![CDATA[SQL SERVER 2005]]></category>
		<category><![CDATA[SQL SERVER 2008]]></category>
		<category><![CDATA[SQL SERVER 2008 R2]]></category>
		<category><![CDATA[SQL SERVER 7]]></category>
		<category><![CDATA[comparar]]></category>
		<category><![CDATA[datatype]]></category>
		<category><![CDATA[sql server 2000]]></category>

		<guid isPermaLink="false">http://diariodba.wordpress.com/?p=57</guid>
		<description><![CDATA[  No SQL Server 2005 temos os novos campos do tipo VAR&#8230;(MAX) que vieram aliviar o trabalho de muita gente. Um dos problemas mais comuns na versão anterior (2000) é quando precisamos comparar dados de campos do tipo text ou ntext, aí nos deparamos com um erro do tipo: Server: Msg 306, Level 16, State [...]]]></description>
			<content:encoded><![CDATA[<p style="margin:0 0 10pt;"> </p>
<p style="margin:0 0 10pt;">No SQL Server 2005 temos os novos campos do tipo VAR&#8230;(MAX) que vieram aliviar o trabalho de muita gente. Um dos problemas mais comuns na versão anterior (2000) é quando precisamos comparar dados de campos do tipo text ou ntext, aí nos deparamos com um erro do tipo:</p>
<p class="MsoNormal" style="margin:0 0 10pt;"><span style="color:#ff0000;">Server: Msg 306, Level 16, State 1, Line 1</span></p>
<p class="MsoNormal" style="margin:0 0 10pt;"><span style="color:#ff0000;">The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator.</span></p>
<p style="margin:0 0 10pt;">Eu já vivi essa situação algumas vezes e deixo aqui a forma como tentei resolver (Se tiverem outras sugestões fiquem a vontade para expor, ok?).</p>
<p style="margin:0 0 10pt;">(Não fiz testes de perfomance nessa solução, o foco está somente em comparar as colunas tipo text / ntext.)</p>
<p style="margin:0 0 10pt;">Imagine que eu tenha duas tabelas:</p>
<p class="MsoNormal" style="margin:0 0 10pt;"><span style="color:#0000ff;">CREATE TABLE #tb_msg_tela<br />
(id INT IDENTITY(1,1), texto TEXT)</span></p>
<p class="MsoNormal" style="margin:0 0 10pt;"><span style="color:#0000ff;">GO</span></p>
<p class="MsoNormal" style="margin:0 0 10pt;"><span style="color:#0000ff;">CREATE TABLE #tb_msg_impressao<br />
(id INT IDENTITY(1,1), texto TEXT)</span></p>
<p style="margin:0 0 10pt;">Com os seguintes dados:</p>
<p style="margin:0 0 10pt;"><span style="color:#0000ff;">INSERT INTO #tb_msg_tela VALUES <span style="color:#ff0000;">(NULL)<br />
</span>INSERT INTO #tb_msg_tela VALUES (&#8216;Campo text&#8217;)<br />
INSERT INTO #tb_msg_tela VALUES (&#8216;Teste <span style="color:#ff0000;">comparação</span>&#8216;)<br />
INSERT INTO #tb_msg_tela VALUES (&#8216;Se ca<span style="color:#ff0000;">í</span>sse para o e<span style="color:#ff0000;">x</span>terior, <span style="color:#ff0000;">para </span>o limite do universo, encontraria uma perto e pôsteres que indicassem BECO SEM SAÍDA?&#8217;)</span></p>
<p style="margin:0 0 10pt;"><span style="color:#0000ff;">INSERT INTO #tb_msg_impressao VALUES <span style="color:#ff0000;">(&#8221;)<br />
</span>INSERT INTO #tb_msg_impressao VALUES (&#8216;Campo text&#8217;)<br />
INSERT INTO #tb_msg_impressao VALUES (&#8216;Teste <span style="color:#ff0000;">comparacao</span>&#8216;)<br />
INSERT INTO #tb_msg_impressao VALUES (&#8216;Se ca<span style="color:#ff0000;">i</span>sse para o e<span style="color:#ff0000;">s</span>terior, <span style="color:#ff0000;">p/</span> o limite do universo, encontraria uma perto e pôsteres que indicassem BECO SEM SAÍDA?&#8217;)</span></p>
<p style="margin:0 0 10pt;">Observe que existem diferenças em alguns textos (em vermelho).</p>
<p style="margin:0 0 10pt;">Para realizar o relacionamento das duas tabelas e encontrar os campos diferentes não podemos simplesmente utilizar:</p>
<p class="MsoNormal" style="margin:0 0 10pt;"><span style="color:#0000ff;">SELECT * FROM #tb_msg_tela a, #tb_msg_impressao b<br />
WHERE a.id = b.id AND <span style="color:#ff0000;">a.texto &lt;&gt; b.texto</span></span></p>
<p style="margin:0 0 10pt;">Essa consulta retornará um erro porque estamos comparando os campos text utilizando o &lt;&gt;.</p>
<p style="margin:0 0 10pt;">Então o primeiro passo é encontrar o maior texto nessa coluna, para isso podemos usar as funções DATALENGHT e MAX:</p>
<p class="MsoNormal" style="margin:0 0 10pt;"><span style="color:#0000ff;">SELECT MAX(DATALENGTH(texto)) FROM #tb_msg_tela<br />
SELECT MAX(DATALENGTH(texto)) FROM #tb_msg_impressao</span></p>
<p style="margin:0 0 10pt;">O resultado será:</p>
<p style="margin:0 0 10pt;">&#8212;&#8212;&#8212;&#8211;</p>
<p style="margin:0 0 10pt;">658</p>
<p style="margin:0 0 10pt;">&#8212;&#8212;&#8212;&#8211;</p>
<p style="margin:0 0 10pt;">656</p>
<p style="margin:0 0 10pt;">Então sabemos que o maior texto dessa coluna não ultrapassa 700 caracteres, logo, podemos utilizar esse número como apoio no próximo passo, onde utilizaremos a função SUBSTRING:</p>
<p class="MsoNormal" style="line-height:normal;margin:0 0 10pt;"><span style="color:#0000ff;">SELECT<br />
                *<br />
FROM  <br />
                #tb_msg_tela a,<br />
                #tb_msg_impressao b<br />
WHERE<br />
                a.id = b.id<br />
                AND ISNULL(SUBSTRING(a.texto, 0, 700),&#8221;) &lt;&gt; ISNULL(SUBSTRING(b.texto, 0, 700),&#8221;) </span></p>
<p class="MsoNormal" style="line-height:normal;margin:0 0 10pt;"><span lang="EN-US"> </span></p>
<p style="line-height:normal;margin:0 0 10pt;">A função <strong>ISNULL</strong> é importante pois sem ela os campos Nulos serão ignorados.</p>
<p style="line-height:normal;margin:0 0 10pt;">Veja que a consulta só ira retornar os campos com as diferenças.</p>
<p class="MsoNormal" style="margin:0 0 10pt;">É um processo simples, mas que pode dar dor de cabeça por conta das limitações do tipo de dados. Pra quem ta iniciando o desenvolvimento utilizando o SQL Server 2005 a recomendação é: substitua os datatypes <em>ntext</em>, <em>text</em>, <em>image</em> por <em>nvarchar(Max), varchar(Max)</em> e <em>varbinary(Max).</em> Além de outras vantagens, com os novos datatypes não existem as antigas diferenças entre varchar e text.</p>
<p class="MsoNormal" style="margin:0 0 10pt;"><span style="font-family:Calibri;"><span style="font-family:Calibri;"> </span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://silasmendes.com/dba/comparando-text-ntext/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

