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
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