Comment définir une variable à partir d'une requête SQL?

324

J'essaie de définir une variable à partir d'une requête SQL:

declare @ModelID uniqueidentifer

Select @ModelID = select modelid from models
where areaid = 'South Coast'

Évidemment, je ne fais pas cela correctement car cela ne fonctionne pas. Quelqu'un peut-il suggérer une solution?

Merci!

Mr Cricket
la source
2
C'est un identifiant unique. Pas uniqueidentifer.
DxTx

Réponses:

519

Utilisation de SELECT:

SELECT @ModelID = m.modelid 
  FROM MODELS m
 WHERE m.areaid = 'South Coast'

Utilisation de SET:

SET @ModelID = (SELECT m.modelid 
                  FROM MODELS m
                 WHERE m.areaid = 'South Coast')

Voir cette question pour la différence entre l'utilisation de SELECT et SET dans TSQL .

avertissement

Si cette instruction select renvoie plusieurs valeurs (mauvaise pour commencer):

  • Lors de l'utilisation SELECT, la variable reçoit la dernière valeur renvoyée (comme l'a dit womp), sans aucune erreur ni avertissement (cela peut provoquer des bogues logiques)
  • Lors de l'utilisation SET, une erreur se produira
Poneys OMG
la source
3
Si cette instruction select renvoie plusieurs valeurs: dans le premier cas, la dernière valeur renvoyée (comme l'a dit womp) est affectée à la variable, sans aucune erreur ni avertissement (cela peut provoquer des bogues logiques); dans le second cas, une erreur se produira.
Francis Niu
3
BTW, le cas utilisant SET nécessite une paire de supports: SET @ModelID = (SELECT ...)
Francis Niu
2
J'utiliserais TOP 1 avec select, pour n'avoir qu'un seul résultat, par exemple SET @ModelID = (SELECT TOP 1 m.modelid FROM MODELS m WHERE m.areaid = 'South Coast')
TPAKTOPA
Si vous utilisez set lorsque plusieurs valeurs sont renvoyées, comment le gérer à l'aide de la gestion des exceptions?
apprenant
Parfois, vous voulez une erreur s'il y a un résultat en double inattendu plutôt que d'utiliser tranquillement un résultat inattendu.
Denise Skidmore du
37
SELECT @ModelID = modelid
FROM Models
WHERE areaid = 'South Coast'

Si votre instruction select renvoie plusieurs valeurs, votre variable se voit attribuer la dernière valeur renvoyée.

Pour plus d'informations sur l'utilisation de SELECT avec des variables: http://msdn.microsoft.com/en-us/library/aa259186%28SQL.80%29.aspx

womp
la source
29
declare @ModelID uniqueidentifer

--make sure to use brackets
set @ModelID = (select modelid from models
where areaid = 'South Coast')

select @ModelID
greg121
la source
Cette question toute prête a une réponse à laquelle il n'était pas nécessaire de répondre à nouveau, je ne vois même pas ce qui est différent entre la vôtre et la réponse de Poneys?
Joshua Duxbury
5
@JoshuaDuxbury fournit une version de copier-coller de travail
greg121
17

Je préfère simplement le définir à partir de la déclaration declare

DECLARE @ModelID uniqueidentifer = (SELECT modelid 
                                    FROM models
                                    WHERE areaid = 'South Coast')
Joshua Duxbury
la source
10

À utiliser TOP 1si la requête renvoie plusieurs lignes.

SELECT TOP 1 @ModelID = m.modelid 
  FROM MODELS m
 WHERE m.areaid = 'South Coast'
manu vijay
la source
Cela ne provoquera pas réellement une erreur dans SQL, il sélectionnera le dernier enregistrement (bien qu'il puisse provoquer une erreur résultante dans une application si vous utilisez cette valeur et qu'elle est incorrecte)
d219
9

Vous pouvez l'utiliser, mais n'oubliez pas que votre requête donne 1 résultat, plusieurs résultats lèveront l'exception.

declare @ModelID uniqueidentifer
Set @ModelID = (select Top(1) modelid from models where areaid = 'South Coast')

Autrement:

Select Top(1)@ModelID = modelid from models where areaid = 'South Coast'
Pranay_Sharma_Ind
la source
4
Select @ModelID =m.modelid 
From   MODELS m
Where  m.areaid = 'South Coast'

Dans ce cas, si vous avez renvoyé deux résultats ou plus, votre résultat est le dernier enregistrement. Soyez donc conscient de cela si vous pouvez renvoyer deux enregistrements supplémentaires car vous ne verrez peut-être pas le résultat attendu.

Mohammad Farahani
la source
4

Il existe trois approches:

  1. DÉCLARER
  2. SET - Approche recommandée par Microsoft
  3. SÉLECTIONNER

La requête ci-dessous détaille les avantages et les inconvénients de chacun:

-- First way, 
DECLARE @test int = (SELECT 1)
       , @test2 int = (SELECT a from (values (1),(2)) t(a)) -- throws error

-- advantage: declare and set in the same place
-- Disadvantage: can be used only during declaration. cannot be used later

-- Second way
DECLARE @test int  
       , @test2 int 

SET @test = (select 1)
SET @test2 = (SELECT a from (values (1),(2)) t(a)) -- throws error

-- Advantage: ANSI standard. 
-- Disadvantage: cannot set more than one variable at a time

-- Third way
DECLARE @test int, @test2 int 
SELECT @test = (select 1)
      ,@test2 = (SELECT a from (values (1),(2)) t(a)) -- throws error

-- Advantage: Can set more than one variable at a time
-- Disadvantage: Not ANSI standard
Venkataraman R
la source
1

Pour ASSIGNER des variables à l'aide d'un SQL, sélectionnez la meilleure pratique comme indiqué ci-dessous

->DECLARE co_id INT ;
->DECLARE sname VARCHAR(10) ;

->SELECT course_id INTO co_id FROM course_details ;
->SELECT student_name INTO sname FROM course_details;

SI vous devez affecter plus d'une variable sur une seule ligne, vous pouvez utiliser ce même SELECT INTO

->DECLARE val1 int;
->DECLARE val2 int;

->SELECT student__id,student_name INTO val1,val2 FROM student_details;

--HAPPY CODING-- 
Venkzz_venki
la source
"meilleure pratique" - source?
Rodney Ellis
SI vous avez plus d'une colonne à sélectionner dans une table, vous pouvez facilement l'affecter en utilisant une seule instruction SELECT INTO au lieu de répéter le code !!
Venkzz_venki