164 votes

Clause de sortie du serveur SQL dans une variable scalaire

Existe-t-il un moyen "simple" de faire cela 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)

204voto

Mikael Eriksson Points 77190

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)

64 votes

Mais alors je devrais "SELECT @someInt = ID FROM @ID". Je voulais savoir s'il était possible de sauter cette étape supplémentaire (et la variable de table intermédiaire) si je n'avais besoin que de l'entier résultant.

0 votes

@Benoittr - Cela dépend de la façon dont vous allez utiliser la valeur, cela peut ne pas être nécessaire, vous pourriez utiliser la table dans une clause from d'une instruction select. Lorsque vous affectez une variable, vous devez également vous assurer que l'insertion 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 s'emparer directement de ce qui est utilisé dans la clause values plutôt que d'utiliser la clause output ?

5 votes

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

37voto

AlejoBrz Points 1510

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

SELECT @ReportOptionId = SCOPE_IDENTITY()

Sinon, il semble que vous soyez obligé d'utiliser un tableau.

8 votes

La variable que je cherchais était en fait autre chose que la colonne d'identité. Merci quand même pour la réponse.

29 votes

Apparemment, cela pose des problèmes dans un plan parallèle à plusieurs processeurs, et OUTPUT est la seule méthode toujours fiable.

8 votes

SCOPE_IDENTITY() peut renvoyer quelque chose même si le fichier dernier INSERT n'a rien inséré, n'est-ce pas ? Cela le rendrait inutilisable dans certains cas.

12voto

Jay13 Points 323

Bien plus tard, mais cela vaut la peine d'être mentionné, vous pouvez également utiliser des variables pour sortir 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 provenant d'un déclencheur ne serait pas dans val2, donc vous devriez utiliser la table de sortie dans ce cas. Pour tout autre cas que le cas le plus simple, je pense que le tableau de sortie sera plus lisible dans votre code également.

Cela peut s'avérer 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

9voto

Simon Points 325

Réponse :

Vous pouvez utiliser @@IDENTITY pour obtenir le dernier identifiant inséré.

DECLARE @someInt int
INSERT INTO MyTable2(AIntColumn)
VALUES(12)
SET @someInt = @@IDENTITY;

En supposant que votre table a une clé primaire que vous cherchez à définir comme ladite variable.

Exemple de schéma

CREATE TABLE MyTable2(
    [ID] [INT] IDENTITY(1,1),
    [aIntColumn] [INT]
)
CREATE TABLE MyTable3(
    [ID] [INT] IDENTITY(1,1),
    [newInt] [INT],
    [FK_int] [INT]
)

Vous pouvez ensuite l'utiliser dans la partie suivante de votre script, par ex.

DECLARE @someInt INT;
INSERT INTO MyTable2(AIntColumn)
VALUES(12)
SET @someInt = @@IDENTITY;

--do something else
DECLARE @someInt2 INT;
INSERT INTO MyTable3(newInt, FK_int)
VALUES(101, @someInt)
SET @someInt2 = @@IDENTITY;

SELECT @someInt AS 'First Inserted ID ',  @someInt2 AS 'Second inserted ID';

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X