Como uso a cláusula OUTPUT de uma instrução INSERT para obter o valor da identidade?

240

Se eu tiver uma instrução de inserção como:

INSERT INTO MyTable
(  
  Name,
  Address,
  PhoneNo
)
VALUES
(
  'Yatrix',
   '1234 Address Stuff',
   '1112223333'
)

Como defino @var INTo valor de identidade da nova linha (chamada Id) usando a cláusula OUTPUT? Já vi exemplos de inserção de INSERTED.Name em variáveis ​​de tabela, por exemplo, mas não consigo inseri-lo em uma variável que não seja de tabela.

Eu tentei OUPUT INSERTED.Id AS @var, SET @var = INSERTED.Idmas nenhum deles funcionou.

Yatrix
fonte
3
Eu já conheço @@ SCOPE_IDENTITY, quero especificamente saber como fazê-lo com OUPUT. Obrigado.
Yatrix
6
Você precisa inseri-lo em uma variável da tabela e selecionar a partir dela. Não há sintaxe para atribuir diretamente a uma variável escalar da OUTPUTcláusula.
Martin Smith
3
A cláusula OUTPUT deve saída em uma variável de tabela ou tabela ..
mellamokb
5
A OUTPUTcláusula grava em uma tabela. Pode ser uma variável de tabela, tabela temporária, ....
HABO
2
Minha pergunta pede especificamente a cláusula OUTPUT.
Yatrix 30/09/16

Respostas:

464

Você pode ter o ID recém-inserido sendo enviado para o console do SSMS da seguinte maneira:

INSERT INTO MyTable(Name, Address, PhoneNo)
OUTPUT INSERTED.ID
VALUES ('Yatrix', '1234 Address Stuff', '1112223333')

Você também pode usar isso em, por exemplo, C #, quando precisar recuperar o ID do seu aplicativo de chamada - basta executar a consulta SQL com .ExecuteScalar()(em vez de .ExecuteNonQuery()) para ler o resultado resultante ID.

Ou, se você precisar capturar o recém-inserido IDdentro do T-SQL (por exemplo, para processamento posterior posterior), precisará criar uma variável de tabela:

DECLARE @OutputTbl TABLE (ID INT)

INSERT INTO MyTable(Name, Address, PhoneNo)
OUTPUT INSERTED.ID INTO @OutputTbl(ID)
VALUES ('Yatrix', '1234 Address Stuff', '1112223333')

Dessa forma, você pode colocar vários valores @OutputTble fazer um processamento adicional sobre eles. Você também pode usar uma tabela temporária "regular" ( #temp) ou mesmo uma tabela persistente "real" como seu "destino de saída" aqui.

marc_s
fonte
2
A resposta aqui para o código por trás foi concisa. ExecuteScalar () FTW
Joe Johnston
10
Você pode inserir o resultado em um real persistent table - isso é extremamente fantástico, pois significa que você pode INSERTobter informações nas TWOtabelas ao mesmo tempo.
gotqn
7
Nunca use @@ IDENTITY para puxar de cima. Escondido da maneira mais difícil, trabalhando com gatilhos e como eles estavam registrando o histórico de alterações feitas em uma tabela e inserindo uma nova tabela ao mesmo tempo, @@ IDENTITY começou a retornar valores da tabela de histórico. hilaridade se segue a partir daí! Por favor, use a solução de marc_s. por enquanto, segui o método @OutputTbl, mas estou intrigado com as outras opções.
Eric Bishard 20/09/16
4
OUTPUT INTO é extremamente fantástico, exceto que "A tabela de destino da cláusula OUTPUT INTO não pode estar nos dois lados de um relacionamento (chave primária, chave estrangeira)", o que para mim representa cerca de 99% dos casos de uso em potencial. Suponho que isso ocorre porque a cláusula OUTPUT pode retornar dados mesmo quando a transação é revertida, mas é um pouco chato que é tão difícil inserir dados nos quadros A e B relacionados de uma só vez.
9788 Robert Calhoun #
3
@EricBishard SCOPE_IDENTITY()funciona melhor para isso.
Derreck Dean