Compartilhar via


SQL Server: SET x SELECT

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 TesteSetSelect 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 TesteSetSelect where Codigo=2)
Select @NomeSet
 
Declare @NomeSelect varchar(20)
Select @NomeSelect=Nome from TesteSetSelect 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.

Ozimar Henrique

http://ozimar.com/