44 votes

SQL Server 2005 Définition d'une variable pour le résultat d'une requête select

Comment définir une variable dans le résultat d'une requête de sélection sans utiliser une procédure stockée ?


Je veux faire quelque chose comme : OOdate DATETIME

SET OOdate = Select OO.Date 
FROM OLAP.OutageHours as OO
WHERE OO.OutageID = 1

Ensuite, je veux utiliser OOdate dans cette requête :

SELECT COUNT(FF.HALID) from Outages.FaultsInOutages as OFIO
INNER join Faults.Faults as FF ON FF.HALID = OFIO.HALID
WHERE CONVERT(VARCHAR(10),OO.Date,126) = CONVERT(VARCHAR(10),FF.FaultDate,126)) 
AND
OFIO.OutageID = 1

70voto

rslite Points 17279

Vous pouvez utiliser quelque chose comme

SET @cnt = (SELECT COUNT(*) FROM User)

ou

SELECT @cnt = (COUNT(*) FROM User)

Pour que cela fonctionne, le SELECT doit renvoyer une seule colonne et un seul résultat et l'instruction SELECT doit être entre parenthèses.

Modifier : Avez-vous essayé quelque chose comme ça ?

DECLARE @OOdate DATETIME

SET @OOdate = Select OO.Date from OLAP.OutageHours as OO where OO.OutageID = 1

Select COUNT(FF.HALID) 
from Outages.FaultsInOutages as OFIO 
inner join Faults.Faults as FF 
    ON FF.HALID = OFIO.HALID 
WHERE @OODate = FF.FaultDate
    AND OFIO.OutageID = 1

13voto

-- Sql Server 2005 Management studio

use Master
go
DECLARE @MyVar bigint
SET @myvar = (SELECT count(*) FROM spt_values);
SELECT @myvar

-- Note : @myvar = @Myvar

3voto

JPrescottSanders Points 1595

Vous pourriez utiliser :

declare @foo as nvarchar(25)

select @foo = 'bar'

select @foo

2voto

Pittsburgh DBA Points 2342

Vous pouvez aussi simplement placer le premier SELECT dans une sous-requête. Comme la plupart des optimiseurs le transformeront de toute façon en une constante, il ne devrait pas y avoir d'impact sur les performances.

Au fait, puisque vous utilisez un prédicat comme celui-ci :

CONVERT(...) = CONVERT(...)

cette expression de prédicat ne peut pas être optimisée correctement ou utiliser des index sur les colonnes référencées par la fonction CONVERT().

Voici une façon d'améliorer quelque peu la requête originale :

DECLARE @ooDate datetime
SELECT @ooDate = OO.Date FROM OLAP.OutageHours AS OO where OO.OutageID = 1

SELECT 
  COUNT(FF.HALID)
FROM
  Outages.FaultsInOutages AS OFIO 
  INNER JOIN Faults.Faults as FF ON 
    FF.HALID = OFIO.HALID 
WHERE
  FF.FaultDate >= @ooDate AND
  FF.FaultDate < DATEADD(day, 1, @ooDate) AND
  OFIO.OutageID = 1

Cette version pourrait s'appuyer sur un index qui fait intervenir FaultDate, et atteint le même objectif.

Le voici, réécrit pour utiliser une sous-requête afin d'éviter la déclaration de variable et le SELECT ultérieur.

SELECT 
  COUNT(FF.HALID)
FROM
  Outages.FaultsInOutages AS OFIO 
  INNER JOIN Faults.Faults as FF ON 
    FF.HALID = OFIO.HALID 
WHERE
  CONVERT(varchar(10), FF.FaultDate, 126) = (SELECT CONVERT(varchar(10), OO.Date, 126) FROM OLAP.OutageHours AS OO where OO.OutageID = 1) AND
  OFIO.OutageID = 1

Notez que cette approche présente le même problème d'utilisation d'index que l'original, en raison de l'utilisation de CONVERT() sur FF.FaultDate. Il est possible de remédier à ce problème en ajoutant deux fois la sous-requête, mais il est préférable d'utiliser l'approche variable dans ce cas. Cette dernière version est uniquement destinée à la démonstration.

Regards.

2voto

Siddhesh Bondre Points 119

Cela fonctionnera pour la question originale posée :

DECLARE @Result INT ; SELECT @Result = COUNT(*) FROM NomTable WHERE Condition

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