A diferença entre SET e SELECT ao Atribuir Valores à Variáveis. Tradicionalmente, os desenvolvedores que utilizam o banco de dados SQL Server, estão acostumados a usar a instrução SELECT para atribuir valores às variáveis. Isto era uma boa prática e muito válida até a versão 6.5 do SQL Server. Porém, a Microsoft liberou o SQL Server 7.0 em 1999 e nesta versão, foi introduzida a nova sentença SET, utilizada para inicializar e atribuir valores às variáveis. O Books Online do SQL Server 7.0 aconselha: "recomenda-se que a instrução SET @variável_ local seja usada para atribuição de variáveis, ao invés de SELECT @variável_ local." Isto causou um pouco de confusão na comunidade de desenvolvedores, uma vez que a Microsoft nunca mencionou, porque é recomendável utilizar-se SET ao invés de SELECT para atribuir valores às variáveis. Neste artigo, serão destacadas as principais diferenças entre SET e SELECT, e algumas coisas que se deve levar em conta, ao usar-se tanto SET quanto SELECT. Se você for completamente novo no TRANSACT-SQL, então os seguintes exemplos o ajudarão a entender melhor: /* Declarando as variáveis */ /* Atribuindo o valor 1 à @Variable1 usando SELECT */ /* Atribuindo o valor 2 à @Variable2 usando SET */ Agora vamos às diferenças entre o SET E SELECT! Os padrões são importantes para você? Se sua resposta for “sim”, então você deve utilizar SET. O motivo é que SET, é o formato ANSI padrão para atribuição de valores às variáveis, e o SELECT não é. Uma outra diferença fundamental entre SET e SELECT, é que é possível usar SELECT para atribuir valores a mais de uma variável ao mesmo tempo. SET permite que sejam atribuídos dados a somente uma variável de cada vez. Veja como: /* declarando as variáveis */ /* inicializando duas variáveis de uma vez */
Até agora tudo bem. Mas se você nunca escreveu código para manipulação de erros no TRANSACT-SQL, você deve estar ciente de que as variáveis de sistema @@ERROR e @@ROWCOUNT deverão ser capturadas, imediatamente depois de uma sentença de manipulação de dados (DML) como INSERT, UPDATE, DELETE, caso contrário, estas variáveis de sistema serão resetadas para 0. Veja o seguinte exemplo: DECLARE @Error int, @RowCount int Se você executar este trecho de código no banco de dados pubs, que acompanha o SQL Server, o valor da variável de sistema @@ERROR será exibido como 0, mesmo que a “divisão por zero” resulte no erro 8134. Assim, neste cenário particular, esqueça dos padrões e use SELECT, como mostrado abaixo: DECLARE @Error int, @RowCount int Mas se você insistir em usar SET mesmo neste cenário, há sempre uma maneira de fazê-lo. Está aqui um exemplo, embora não muito claro e não recomendado: DECLARE @ErrorAndRowcount AS varchar(25), @Error int, @RowCount int
Outras diferenças entre SET e SELECT: Ao usar uma query para popular uma variável, SET falhará e um erro será gerado, se a consulta retornar mais de um valor. Já o SELECT, atribuirá uma das linhas retornadas à variável e irá mascarar o fato de que a query retornou mais de uma linha. Em conseqüência, os erros em seu código poderiam passar despercebidos com SELECT, e estes tipos de erros são muito difíceis de serem depurados. Veja um exemplo: /* Considere a seguinte tabela com duas linhas */
Server: Msg 512, Level 16, State 1, Line -1074284106 Baseado nos resultados acima, ao usar uma consulta para popular variáveis, utilize sempre SET, se você quiser estar certo de que somente uma linha será retornada. Se preferir não utilizar SET por alguma razão, você poderia obter o mesmo comportamento, usando SELECT, como mostrado abaixo: DECLARE @j varchar(10) Eis aqui uma outra diferença com relação a atribuição de valores baseados em uma query, especialmente quando a consulta não retornar linha alguma. Execute o seguinte exemplo com o banco de dados pubs e veja por você mesmo: /* Returna NULL */ SET @Title = SELECT @Title /* Returna a string 'Not Found' */ SELECT @Title = title SELECT @Title Por último, mas não menos importante! Há alguma diferença de desempenho entre SET e SELECT? Algum deles é mais rápido ou mais lento do que o outro? Esta é uma pergunta que a maioria dos desenvolvedores e DBAs não têm tanta certeza. Acompanhe a seguir, um teste realizado para tentar esclarecer melhor estas questões. Houve muito pouca diferença de desempenho entre SET e SELECT, quando foram feitas inicializações de variáveis ou atribuições de valores para elas. Mas, uma descoberta surpreendente foi feita. Como se sabe, uma única sentença SELECT pode ser usada para atribuir valores à múltiplas variáveis. Esta característica do SELECT o torna superior ao SET neste quesito. No teste realizado, uma única instrução SELECT atribuiu valores a 3 variáveis diferentes, e esta execução foi muito mais rápida do que quando foram utilizadas 3 sentenças diferentes com SET, atribuindo valores a 3 variáveis diferentes. Neste cenário, usar um SELECT foi pelo menos duas vezes mais rápido, do que o uso de SET. Desta forma, a conclusão a que se chegou foi a seguinte: se você tiver um laço em seu procedimento armazenado que manipula os valores de diversas variáveis, e se você quiser obter o máximo de desempenho quanto for possível fora deste laço, então faça todas as manipulações variáveis em uma única sentença SELECT (ou agrupe as variáveis relacionadas em poucas instruções SELECT) como a mostrado abaixo: SELECT @TestVar1 = @TestVar1 + 1, @TestVar2 = @TestVar2 - 1, @CTR = @CTR + 1 O teste foi realizado no SQL Server, versões 7.0, 2000 e SQL Server Yukon Beta 1 e os resultados foram consistentes. Estes mesmos testes foram aplicados tanto em computadores com um processador quanto em computadores com multii-processadores, e os resultados foram os mesmos. Apenas é aconselhável não rodar o teste em uma máquina de produção, uma vez que ele exige 100% de utilização da CPU durante a sua execução. Além disso, se você achar que o teste irá demorar muito para terminar, diminua o valor da variável @TimesToLoop2, de modo que o número de iterações seja reduzido. Ao final do teste, o script exibirá quanto tempo (em segundos) ele levou para atribuir valores às variáveis utilizando SET, SELECT e SELECT com atribuições múltiplas.
Por Edison Costa |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Todos
os direitos reservados: DevMedia Group |