<rss version="2.0" xmlns:a10="http://www.w3.org/2005/Atom"><channel><title>Dicas Técnicas BufaloInfo</title><link>http://www.bufaloinfo.com.br/</link><description>Dicas Técnicas Produzidas pela Búfalo Informática</description><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=998</link><title>SQL Server : Pesquisar por uma string em todos os campos de uma tabela</title><description/></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=954</link><title>SQL Server : Exportando dados para o excel</title><description>&lt;br&gt;Frequentemente precisamos fazer exporta&amp;#231;&amp;#245;es de dados para o excel. &amp;#201; claro que podemos fazer essas exporta&amp;#231;&amp;#245;es utilizando o DTS ou o atual SSIS. Mas que tal fazer a exporta&amp;#231;&amp;#227;o utilizando uma instru&amp;#231;&amp;#227;o SQL, mais f&amp;#225;cil de ser disparada do que os pacotes de exporta&amp;#231;&amp;#227;o ?&lt;br&gt;&lt;br&gt;A fun&amp;#231;&amp;#227;o OpenRowSet permite que sejam feitos acessos a outros bancos de dados mesmo que estes n&amp;#227;o estejam cadastrados como linked servers. Funciona como um linked server inline.&lt;br&gt;&lt;br&gt;Desta forma podemos fazer uma exporta&amp;#231;&amp;#227;o para o excel em uma &amp;#250;nica instru&amp;#231;&amp;#227;o, veja :&lt;br&gt;&lt;br&gt;INSERT INTO OPENROWSET('Microsoft.Jet.OLEDB.4.0', &lt;br&gt;'Excel 8.0;Database=C:\teste.xls;User=Admin;Password=', &lt;br&gt;'SELECT ID, Empresa FROM [Sheet1$]') &lt;br&gt;SELECT customerid,companyname from customers&lt;br&gt;&lt;br&gt;&lt;br&gt;Algumas observa&amp;#231;&amp;#245;es :&lt;br&gt;&lt;br&gt;A planilha do excel (no exemplo teste.xls) tem que j&amp;#225; existir com os cabe&amp;#231;alhos de campo, do contr&amp;#225;rio ocorre um erro&lt;br&gt;&lt;br&gt;Permiss&amp;#245;es no diret&amp;#243;rio tempor&amp;#225;rio do usu&amp;#225;rio do servi&amp;#231;o do sql server/sql server agent s&amp;#227;o necess&amp;#225;rias. Os seguintes links ajudam no caso de ocorrerem erros estranhos : http://support.microsoft.com/kb/814398/en-us e http://support.microsoft.com/kb/296711/EN-US/&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=936</link><title>SQL Server : Invertendo o valor de um campo bit</title><description>&lt;br&gt;&lt;br&gt;Uma dica simples, mas que pode ser &amp;#250;til : Como inverter o valor de um campo bit ? Fazer com que verdadeiro seja falso e vice versa ?&lt;br&gt;&lt;br&gt;Uma forma simples de fazer isso &amp;#233; com manipula&amp;#231;&amp;#227;o bin&amp;#225;ria. O SQL Server tem o operador ^ que representa um OR exclusivo bin&amp;#225;rio.&lt;br&gt;&lt;br&gt;Veja um exemplo :&lt;br&gt;&lt;br&gt;&lt;br&gt;update testedicas set valor = 1^valor&lt;br&gt;&lt;br&gt;&lt;br&gt;O &amp;#233; basicamente um bit 1. Como estamos usando um OR exclusivo, se os dois forem 1, o resultado &amp;#233; 0, se valor for 0, permanece ligado o bit 1, desta forma causando a invers&amp;#227;o no campo bit.&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=895</link><title>SQL Server : Passando multiplos registros como parâmetro para procedure</title><description>&lt;br&gt;Na dica em http://www.bufaloinfo.com.br/dicas.asp?cod=306 foi mostrado com realizar esse truque utilizando dados em XML e a instru&amp;#231;&amp;#227;o OpenXML.&lt;br&gt;&lt;br&gt;Por&amp;#233;m, a partir do SQL Server 2005 ficou bem mais simples de realizar esta tarefa com os recursos espec&amp;#237;ficos de manipula&amp;#231;&amp;#227;o de XML existentes no SQL Server.&lt;br&gt;&lt;br&gt;Veja um exemplo :&lt;br&gt;&lt;br&gt;&lt;br&gt;declare @xml xml &lt;br&gt;select @xml='&amp;lt;clientes&amp;gt;&lt;br&gt;&amp;lt;cliente&amp;gt;&amp;lt;customerid&amp;gt;ALFKI&amp;lt;/customerid&amp;gt;&amp;lt;/cliente&amp;gt;&lt;br&gt;&amp;lt;cliente&amp;gt;&amp;lt;customerid&amp;gt;ANATR&amp;lt;/customerid&amp;gt;&amp;lt;/cliente&amp;gt;&lt;br&gt;&amp;lt;cliente&amp;gt;&amp;lt;customerid&amp;gt;ANTON&amp;lt;/customerid&amp;gt;&amp;lt;/cliente&amp;gt;&lt;br&gt;&amp;lt;/clientes&amp;gt;'&lt;br&gt;&lt;br&gt;&lt;br&gt;SELECT&lt;br&gt;clientes.cliente.value('customerid[1]','nvarchar(30)')&lt;br&gt;As Customerid&lt;br&gt;FROM&lt;br&gt;@xml.nodes('/clientes/cliente') clientes(cliente)&lt;br&gt;&lt;br&gt;O m&amp;#233;todo nodes na vari&amp;#225;vel do tipo XML nos permite acessar os elementos do XML como sendo uma tabela. No caso o nome da tabela, para esta query, fica sendo &amp;quot;clientes&amp;quot; e o campo XML retornado pelo nodes fica sendo &amp;quot;cliente&amp;quot;. Ent&amp;#227;o cada cliente se torna um registro&lt;br&gt;&lt;br&gt;Na lista de campos, temos o campo cliente, xml, sobre o qual podemos utilizar o m&amp;#233;todo value para extrairmos a informa&amp;#231;&amp;#227;o que desejamos, sabendo que neste ponto j&amp;#225; estamos lidando com apenas um cliente, que foi separado pelo m&amp;#233;todo nodes. Na XQuery ainda precisamos indexar o elemento que desejamos, mas nesse caso o indice ser&amp;#225; sempre [1]&lt;br&gt;&lt;br&gt;Desta forma podemos passar um XML para nossa stored procedure e a procedure poder&amp;#225; retirar do XML os dados de que necessita.&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=891</link><title>SQL Server : Eliminando linhas duplicadas com campo Text</title><description>&lt;br&gt;J&amp;#225; publiquei aqui antes dicas para a elimina&amp;#231;&amp;#227;o de linhas duplicadas em tabelas do SQL Server. Por&amp;#233;m quando a tabela possui um campo Text a coisa complica.&lt;br&gt;&lt;br&gt;O campo Text n&amp;#227;o pode ser usado junto de um Distinct, tendo tamb&amp;#233;m muitas limita&amp;#231;&amp;#245;es de uso em subQuerys. N&amp;#227;o pode haver uma vari&amp;#225;vel text. Usar varchar como intermedi&amp;#225;rio corta o texto para 8000. &lt;br&gt;&lt;br&gt;Ent&amp;#227;o como eliminar as linhas duplicadas ?&lt;br&gt;&lt;br&gt;Simples, recorrendo ao velho cursor : &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;declare x cursor for select codigo from tabela order by codigo desc&lt;br&gt;declare @velhocodigo int&lt;br&gt;declare @codigo int&lt;br&gt;select @velhocodigo=0&lt;br&gt;open x&lt;br&gt;fetch next from x into @codigo&lt;br&gt;while @@fetch_status=0&lt;br&gt;begin&lt;br&gt;   if @codigo=@velhocodigo&lt;br&gt;      begin&lt;br&gt;        delete tabela where current of x&lt;br&gt;      end&lt;br&gt;   else&lt;br&gt;      begin&lt;br&gt;        select @velhocodigo=@codigo&lt;br&gt;      end&lt;br&gt;fetch next from x into @codigo&lt;br&gt;end&lt;br&gt;close x&lt;br&gt;deallocate x&lt;br&gt;&lt;br&gt;&lt;br&gt;N&amp;#227;o &amp;#233; uma tatica bonitinha ou de excelente performance, mas quando tudo o mais falha, como no caso da presen&amp;#231;a de campos text, o cursor acaba nos salvando&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=887</link><title>SQL Server : Simplificando a exportação de dados</title><description>&lt;br&gt;Especialmente quando se trabalha com a &amp;#225;rea de an&amp;#225;lise de dados para decis&amp;#245;es na empresa &amp;#233; muito comum a necessidade de obten&amp;#231;&amp;#227;o de alguns relat&amp;#243;rios bem personalizados.&lt;br&gt;&lt;br&gt;Em alguns casos, j&amp;#225; encontrei empresas nas quais era bem produtivo deixar que os pr&amp;#243;prios usu&amp;#225;rios da &amp;#225;rea de decis&amp;#227;o tivessem acesso a uma c&amp;#243;pia da base de dados e pudessem realizar suas pr&amp;#243;prias querys.&lt;br&gt;&lt;br&gt;Uma forma de simplificar este trabalho &amp;#233; configurar a janela de resultados das querys para j&amp;#225; mostrar os dados em formato de exporta&amp;#231;&amp;#227;o, desta forma permitindo que o resultado seja salvo em .CSV e aberto no excel.&lt;br&gt;&lt;br&gt;Trata-se de uma tarefa muito simples : No SQL Server Management Studio entra-se em Tools-&amp;gt;Options-&amp;gt;Query Results-&amp;gt;SQL Server-&amp;gt;Results to text altera-se ent&amp;#227;o a configura&amp;#231;&amp;#227;o output format para &amp;quot;comma delimited&amp;quot;.&lt;br&gt;&lt;br&gt;Pode-se ainda, no item Query Results, alterar a &amp;quot;Default destination for results&amp;quot; para &amp;quot;results to text&amp;quot;.&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=872</link><title>SQL Server : Recuperando um banco de dados depois de uma perda de log no SQL 2005</title><description>&lt;br&gt;Na dica em http://www.bufaloinfo.com.br/dicas.asp?cod=255, publicada h&amp;#225; alguns anos, &amp;#233; mostrado como fazer a recupera&amp;#231;&amp;#227;o de um banco de dados do SQL Server 2000 que tenha perdido seu arquivo de log mas esteja com recovery model full.&lt;br&gt;&lt;br&gt;Ocorre que no SQL Server 2005 esta dica n&amp;#227;o &amp;#233; mais v&amp;#225;lida, devido a diversas mudan&amp;#231;as ocorridas no servidor.&lt;br&gt;&lt;br&gt;Ent&amp;#227;o : Como recuperar um banco que possui recovery model full mas perdeu seu arquivo de log, .LDF, possuindo apenas seu arquivo .MDF ?&lt;br&gt;&lt;br&gt;Primeiramente, precisamos colocar o banco em modo de emerg&amp;#234;ncia e single user :&lt;br&gt;&lt;br&gt;alter database nomeBanco set Emergency, Single_User&lt;br&gt;&lt;br&gt;Feito isso, fazemos a recupera&amp;#231;&amp;#227;o :&lt;br&gt;&lt;br&gt;DBCC CheckDB('nomeBanco',REPAIR_ALLOW_DATA_LOSS)&lt;br&gt;&lt;br&gt;Por fim o banco ainda estar&amp;#225; em modo single user, ent&amp;#227;o voltamos ele ao modo multi-user :&lt;br&gt;&lt;br&gt;alter database nomebanco set multi_user&lt;br&gt;&lt;br&gt;Pronto, o banco estar&amp;#225; de volta ao ar. &amp;#201; claro que s&amp;#243; se faz isso em &amp;#250;ltimo caso, no caso do log realmente estar perdido, pois este procedimento pode gerar quebra de integridade nos dados, exatamente devido a perda do log que &amp;#233; o respons&amp;#225;vel por isso.&lt;br&gt;&lt;br&gt;Juntando tudo :&lt;br&gt;&lt;br&gt;alter database nomeBanco set Emergency, Single_User&lt;br&gt;DBCC CheckDB('nomeBanco',REPAIR_ALLOW_DATA_LOSS)&lt;br&gt;alter database nomebanco set multi_user&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=791</link><title>SQL Server : Cuidado com NULLs em sub-queries</title><description>&lt;br&gt;Observem estes selects abaixo. Parecem n&amp;#227;o ter segredo nenhum a esconder, correto ?&lt;br&gt;&lt;br&gt;select count(*) from pessoas where email in (select email from lista)&lt;br&gt;select count(*) from pessoas where email not in (select email from lista)&lt;br&gt;&lt;br&gt;Vamos considerar o seguinte :&lt;br&gt;&lt;br&gt;Pessoas : 200 registros&lt;br&gt;Lista : 1000 registros&lt;br&gt;&lt;br&gt;Agora o resultado :&lt;br&gt;&lt;br&gt;1a) 70&lt;br&gt;2a) 0&lt;br&gt;&lt;br&gt;Ent&amp;#227;o a pergunta : Onde foram parar 140 registros ?&lt;br&gt;&lt;br&gt;Este problema curioso mas perfeitamente normal pode com certeza fundir a cabe&amp;#231;a de muitos programadores que n&amp;#227;o lembrem do significado do valor NULL em um banco de dados.&lt;br&gt;&lt;br&gt;NULL : Identifica um valor desconhecido, o valor pode existir ou n&amp;#227;o no mundo real, mas n&amp;#227;o se tem conhecimento de seu valor nos dados do sistema.&lt;br&gt;&lt;br&gt;Eis ai o segredo oculto, o significado do NULL : Existindo um valor NULL na tabela LISTA, a 1a query consegue ser respondida, indicando os registros que est&amp;#227;o na tabela lista, mas a 2a query tem um resultado invi&amp;#225;vel : Como dizer quantos registros n&amp;#227;o est&amp;#227;o l&amp;#225; se existem valores NULL  ? Se voc&amp;#234; levar em considera&amp;#231;&amp;#227;o o significado do NULL, ver&amp;#225; que n&amp;#227;o h&amp;#225; como saber quantos e-mails n&amp;#227;o est&amp;#227;o na lista, simplesmente porque existem valores na lista que s&amp;#227;o desconhecidos. De fato, se levarmos ao p&amp;#233; da letra nem o valor da 1a query &amp;#233; preciso, poderiam haver mais de 70 pessoas na lista.&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=704</link><title>SQL Server : Cuidado com os hints de lock</title><description>&lt;br&gt;Observem o seguinte select :&lt;br&gt;&lt;br&gt;set @novoSeqCartao=(select isnull(max(cartao),0) +1&lt;br&gt;         from cartao (holdlock rowlock updlock)&lt;br&gt;         where numAgencia=@numAgencia and&lt;br&gt;               numConta=@numConta)&lt;br&gt;&lt;br&gt;Claro que esse select &amp;#233; s&amp;#243; um peda&amp;#231;o de uma stored procedure maior, mas &amp;#233; f&amp;#225;cil perceber que est&amp;#225; fazendo a obten&amp;#231;&amp;#227;o do pr&amp;#243;ximo valor de um n&amp;#250;mero sequencial.&lt;br&gt;&lt;br&gt;Por&amp;#233;m quando foi rodado gerou uma grande surpresa para o desenvolvedor : ao inv&amp;#233;s de lockar apenas alguns registros, de acordo com a clausula where, fez lock na tabela inteira.&lt;br&gt;&lt;br&gt;Depois de muito procurar identificou-se o problema : Por n&amp;#227;o haver indice em numAgencia e numConta o select precisou fazer um table scan e, fazendo isso, lockou todos os registros envolvidos, mesmo os que n&amp;#227;o atendiam a clausula where. Como eram muitos, mudou o lock de rowlock para tablelock.&lt;br&gt;&lt;br&gt;Cuidado com os hints !&lt;br&gt;&lt;br&gt;Dica obtida no blog de Gilberto Uchoa - http://br.thespoke.net/BlogReader/SingleEntry.aspx?ID=11898&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><link>http://www.bufaloinfo.com.br/dicas.asp?cod=698</link><title>SQL Server : Salvando scripts automaticamente no EM</title><description>&lt;br&gt;No artigo em http://www.bufaloinfo.com.br/artigos/artigo3111.asp falamos sobre m&amp;#233;todos para controlar vers&amp;#227;o de objetos no banco, tal como manter o script destes objetos arquivado.&lt;br&gt;&lt;br&gt;O Enterprise Manager gera estes scripts para n&amp;#243;s, mas devemos lembrar de salvar tais scripts. Se em um momento de distra&amp;#231;&amp;#227;o esquecermos teremos problemas com o versionamento.&lt;br&gt;&lt;br&gt;Para evitar pequenos descuidos podemos configurar o enterprise manager para salvar automaticamente os scripts. Isso far&amp;#225; com que sempre que ocorrer uma altera&amp;#231;&amp;#227;o em um objeto o enterprise manager automaticamente pe&amp;#231;a o nome do arquivo com o qual deve gravar o script.&lt;br&gt;&lt;br&gt;Para fazermos isso basta, ap&amp;#243;s uma altera&amp;#231;&amp;#227;o, quando voc&amp;#234; clicar em salvar script, marcar a checkbox &amp;quot;automaticaly generate save script on every save&amp;quot;&lt;br&gt;&lt;br&gt;Uma alternativa &amp;#233; ir direto na chave de registry :&lt;br&gt;&lt;br&gt;HKEY_CURRENT_USER\Software\Microsoft\Microsoft SQL Server\80\Tools\SQLEW\DataTools\AutoSaveChangeScript&lt;br&gt;&lt;br&gt;Basta definir esta chave do registry como 1 e o Enterprise Manager sempre pedir&amp;#225; o nome do arquivo para salvar o script de altera&amp;#231;&amp;#227;o nas tabelas.&lt;br&gt;&lt;br&gt;</description></item></channel></rss>