Clause de sortie SQL Server dans une variable scalaire


134

Existe-t-il un moyen "simple" de le faire ou dois-je passer par une variable de table avec la syntaxe "OUTPUT ... INTO"?

DECLARE @someInt int

INSERT INTO MyTable2(AIntColumn)
OUTPUT @SomeInt = Inserted.AIntColumn
VALUES(12)

Réponses:


161

Vous avez besoin d'une variable de table et cela peut être aussi simple que cela.

declare @ID table (ID int)

insert into MyTable2(ID)
output inserted.ID into @ID
values (1)

45
Mais alors je devrais "SELECT @someInt = ID FROM @ID". Je voulais savoir s'il est possible de sauter cette étape supplémentaire (et la variable de table intermédiaire) si tout ce dont j'ai besoin est le résultat int.
Benoittr

@Benoittr - Cela dépend de la façon dont vous allez utiliser la valeur, cela peut ne pas être nécessaire, vous pouvez utiliser la table dans une clause from d'une instruction select. Lorsque vous affectez une variable, vous devez également vous assurer que l'insert n'a inséré qu'une seule ligne. Et si l'insertion n'a inséré qu'une seule ligne, il est peut-être plus facile de saisir directement ce qui est utilisé dans la clause values ​​au lieu d'utiliser output?
Mikael Eriksson

4
Dans le cas d'une valeur auto-générée, il n'est pas toujours possible de connaître les valeurs à l'avance (identité, colonnes calculées). Je comprends qu'il existe de nombreuses solutions de contournement. Pourtant, vous m'avez donné la réponse que je cherchais. Merci
Benoittr

Vous en avez besoin dans une variable régulière? DECLARE @InsertedIDResults TABLE (ID int); INSERT INTO MyTable (Name, Age) OUTPUT INSERTED.ID INTO @InsertedIDResults VALUES('My Name', 30); DECLARE @InsertedID int = (SELECT TOP 1 ID FROM @InsertedIDResults);
Arvo Bowen

30

Plus d'un an plus tard ... si vous avez besoin d'obtenir l'identifiant généré automatiquement d'une table, vous pouvez

SELECT @ReportOptionId = SCOPE_IDENTITY()

Sinon, il semble que vous ne soyez pas obligé d'utiliser une table.


6
La variable que je recherchais était vraiment autre chose que la colonne d'identité. Encore merci pour la réponse.
Benoittr

26
Apparemment, cela pose des problèmes dans un plan parallèle multiprocesseur, et OUTPUT est la seule méthode toujours digne de confiance.
andrewb

6
SCOPE_IDENTITY () peut retourner quelque chose même si le dernier INSERT n'a rien inséré, non? Cela le rendrait inutilisable dans certains cas.
Patrick Honorez

2
mieux utiliser la clause de sortie
Clay Smith

1
Le bogue auquel @andrewb fait référence est corrigé dans 2008 R2 SP1 .
adam0101 le

6

Bien plus tard, mais il convient de mentionner que vous pouvez également utiliser des variables pour afficher des valeurs dans la clause SET d'un UPDATE ou dans les champs d'un SELECT;

DECLARE @val1 int;
DECLARE @val2 int;
UPDATE [dbo].[PortalCounters_TEST]
SET @val1 = NextNum, @val2 = NextNum = NextNum + 1
WHERE [Condition] = 'unique value'
SELECT @val1, @val2

Dans l'exemple ci-dessus, @ val1 a la valeur avant et @ val2 a la valeur après bien que je soupçonne que tout changement d'un déclencheur ne serait pas dans val2, vous devrez donc utiliser la table de sortie dans ce cas. Pour tout sauf le cas le plus simple, je pense que la table de sortie sera également plus lisible dans votre code.

Ceci est très utile si vous souhaitez transformer une colonne en une liste séparée par des virgules;

DECLARE @list varchar(max) = '';
DECLARE @comma varchar(2) = '';
SELECT @list = @list + @comma + County, @comma = ', ' FROM County
print @list

Merci! C'était l'information dont j'avais besoin
Wizou

1
HOU LA LA! Je ne savais pas que tu pouvais le faire SET @val2 = NextNum = NextNum + 1.
Sam

Complètement différent de ce qui a été demandé, n'a pas du tout aidé, parce que je cherchais un moyen d'attribuer une OUTPUTvaleur à une variable dans une INSERTclause en utilisant l' INSERT-OUTPUT-VALUESapproche demandée par le demandeur.
Fwd079 Il y a
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.