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

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

Declare @NomeSelect varchar(20) Select @NomeSelect=Nome from TesteSet
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é'

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

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

DECLARE @Error int, @RowCount int SELECT Codigo/0 FROM Teste
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.