Uma dúvida comum está relacionada ao uso do SET e SELECT para atribuição de variáveis.
A partir da versão 7.0 o SQL possui a instrução SET. Seguindo o Padrão ANSI. Mostrarei algumas diferenças entre o SET e o SELECT para que você possa escolher o comando ideal para cada cenário.
Vamos Criar o ambiente:
Create Table TesteSetSelect ( Codigo int, Nome varchar(20) )
INSERT INTO TesteSetSelect VALUES(1,'João'),(2,'Carlos'),(3,'Maria')
Vamos declarar uma variável usando o SET e atribuir um valor:
Declare @NomeSet varchar(20) SET @NomeSet=(Select Nome from TesteSet
Select where Codigo=2) Select @NomeSet
Select where Codigo=2) Select @NomeSet
Funcionou normalmente, agora vamos inserir um registro:
INSERT INTO TesteSetSelect VALUES(2,'José')
Compare este dois comandos:
Declare @NomeSet varchar(20) SET @NomeSet=(Select Nome from TesteSet
Select where Codigo=2) Select @NomeSet
Select where Codigo=2) Select @NomeSet
Declare @NomeSelect varchar(20) Select @NomeSelect=Nome from TesteSet
Select where Codigo=2 Select @NomeSelect
Select where Codigo=2 Select @NomeSelect
DIFERENÇA 1: -O SET não permite uma subconsulta com vários registros.(retorna erro) -O Select permite, porém só traz o último registro. Assim, é melhor usar o SET e refinar a sua consulta, ao invés de receber o ultimo valor de uma consulta.
DIFERENÇA 2: -O SET só permite uma atribuição por comando. -O Select permite múltiplas atribuições. Exemplo:
Declare @Codigo int, @Nome varchar(25) SET @Codigo=1 SET @Nome='José'
SELECT @Codigo=1, @Nome='José'
SELECT @Codigo=1, @Nome='José'
Num cenário onde você atribui várias variáveis dentro de um loop, melhor utilizar o SELECT pois terá melhor performance.
DIFERENÇA 3: -O SET retorna NULL caso não encontre um novo valor. -O SELECT retorna o antigo valor caso não encontre um novo valor.
Declare @CodigoSet int, @CodigoSelect int SET @CodigoSet=1
SET @CodigoSet=(select 2 from Teste where codigo=100)
SELECT @CodigoSelect=1 SELECT @CodigoSelect=2 from Teste where codigo=100
SELECT @CodigoSet as CodigoSet, @CodigoSelect as CodigoSelect
SET @CodigoSet=(select 2 from Teste where codigo=100)
SELECT @CodigoSelect=1 SELECT @CodigoSelect=2 from Teste where codigo=100
SELECT @CodigoSet as CodigoSet, @CodigoSelect as CodigoSelect
Para evitar perda de valores utilize o SELECT.
DIFERENÇA 4: Para manipulação de erros no T-SQL sabemos que as variáveis de sistema @@ERROR e @@ROWCOUNT deverão ser capturadas, imediatamente depois de uma sentença de manipulação de dados, caso contrário, estas variáveis de sistema serão resetadas para 0.
Veja exemplo:
DECLARE @Error int, @RowCount int SELECT Codigo/0 FROM Teste SET @RowCount = @@ROWCOUNT SET @Error = @@ERROR
SELECT @Error AS Erro
SELECT @Error AS Erro
DECLARE @Error int, @RowCount int SELECT Codigo/0 FROM Teste
SELECT @RowCount = @@ROWCOUNT, @Error = @@ERROR SELECT @Error AS Erro
SELECT @RowCount = @@ROWCOUNT, @Error = @@ERROR SELECT @Error AS Erro
Veja que com o SET o erro retornado foi 0(zero), sendo que o correto seria 8134. Neste cenário utilize o SELECT.
Assim como na maioria dos comandos, temos que analisar o cenário para tomar a melhor decisão. Espero ter esclarecido estes comandos.