web-dev-qa-db-fra.com

Stocker la liste résultante d'un SELECT dans une variable pour compter ET utiliser le résultat

J'ai stocké une procédure qui utilise un curseur et pour chaque extraction un doublon SELECT, une fois pour déterminer le nombre d'ID trouvés (SELECT COUNT(ID) FROM TableA WHERE something.. @cur_var) et si la COUNT(ID) est plus grande puis une valeur spécifiée, un UPDATE est émis pour une autre table WHERE les ID ci-dessus sont utilisés (SELECT ID FROM TableA WHERE something.. @cur_var) ..

L'idée est d'avoir le SELECT stocké dans une variable (pseudo-code idlist = SELECT COUNT(ID) FROM TableA WHERE something.. @cur_var). Ensuite, la longueur de cette liste est utilisée dans le IF (pseudo-code IF longueur (idlist) >100. Dans ce cas, la liste est utilisée à nouveau dans l'instruction WHERE (pseudo-code à nouveau, UPDATE TableB SET value = @cur_var WHERE ID IN idlist)

J'espère être assez précis, je voudrais enregistrer le résultat d'un SELECT dans une variable. Utilisez ensuite le résultat dans WHERE IN variable Et le nombre de lignes de la variable à utiliser dans un IF.

Travailler sur Microsoft SQL Server Enterprise Edition v9.00.3042.00, c'est-à-dire SQL Server 2005 Service Pack 2

MODIFIER

J'ai essayé de garder la procédure aussi raisonnable que possible sans divulguer aucune information privée.

Mon intention est de supprimer le code en double. Le SELECT utilisé dans le IF et le SELECT utilisé dans le WHERE du UPDATE sont les mêmes, sauf que j'ai d'abord besoin la COUNT(ID) puis les réels ID s

DECLARE @cur_id int; 
SET @cur_id = 0;

DECLARE Cur CURSOR FOR
    --this is actually a more complex SELECT but basically gives a list of IDs
    SELECT ID FROM TableC ORDER BY ID DESC

    OPEN Cur;
    FETCH NEXT FROM Cur INTO @cur_id;

WHILE @@FETCH_STATUS = 0
BEGIN

    --here I check if the count of found IDs (with value=NULL and IN the SELECT) is bigger than 5
    IF
    (
        SELECT COUNT(ID) FROM TableA WHERE value=NULL AND ID IN
        (
            SELECT DISTINCT(ID) FROM TableB WHERE ID = @cur_id
        )
    ) > 5
    BEGIN
        --if its bigger, set the value for every ID that is part of the ID list (the same select, but above the count, below no count) 
        UPDATE TableB
        SET value = @cur_id
        WHERE ID IN
        (
            SELECT ID FROM TableA WHERE value=NULL AND ID IN
            (
                SELECT DISTINCT(ID) FROM TableB WHERE ID = @cur_id
            )
        )
    END

    FETCH NEXT FROM Cur INTO @cur_id;
END

MODIFIER 2:

C'est la solution la plus proche possible pour le doublon SELECT que j'ai ci-dessus.

DECLARE @TempIDs TABLE
(
   ID int
);

INSERT INTO 
    @TempIDs 
--this is the select i have twice in the procedure above
SELECT 
    ID
FROM 
    TableA


SELECT COUNT(*) from @TempIDs
SELECT * FROM @TempIDs

Dans ce cas, je SELECT une seule fois, mais suivi de deux autres SELECTS plus tard, une fois en utilisant * Et une fois COUNT(*).

N'y a-t-il aucun moyen d'utiliser @TempIDs Comme ça? ( pseudo-code ):

IF COUNT_ROWS(@TempIDs) > 5
BEGIN
    UPDATE TableB SET value = "wow" WHERE ID IN (@TempIDs)
END
3
Daedalus Mythos

Si vous souhaitez placer un résultat de requête dans une variable de table et parcourir les lignes, cela peut être fait facilement. Soyez prudent avec vos boucles bien sûr.

DECLARE @Value int, @Label varchar(25)  
DECLARE @Tmp table (value int, label varchar(25)) 

INSERT INTO @Tmp (value, label) 
    SELECT 1, 'One' 
UNION SELECT 2, 'Two' 
UNION SELECT 3, 'Three' 

WHILE (SELECT count(1) FROM @Tmp) > 0 
BEGIN 
    SELECT TOP 1 @Value = value, @Label = label FROM @Tmp ORDER BY value 
    DELETE FROM @Tmp WHERE value = @Value 
    SELECT @Value 'value', @Label 'label' 
END 
4
DBNull