salve,
personalmente non vedo perche' tu debba usare una cosa cosi' "brutta" come un cursore..
non l'ho guardato piu' che bene, ma mi pare tu possa addivenire a una soluzione molto piu' elegante e sicuramente piu' efficiente utilizzando le funzionalita' native di SQL Server basate completamente su set di dati e non su porcherie quali i cursori..
di seguito un esempio triviale,
SET NOCOUNT ON;
USE tempdb;
GO
CREATE TABLE dbo.t (
Id int
);
CREATE TABLE dbo.t2 (
Id int,
IdT int
);
GO
INSERT INTO dbo.t VALUES (1), (2) , (2), (3), (3), (3);
INSERT INTO dbo.t2 VALUES (1, 1), (2,2), (3,2), (4,3), (5,3), (6,3);
GO
SELECT Id
FROM dbo.t
GROUP BY Id;
PRINT 'che andrebbe meglio riscritto in un DISTINCT';
PRINT 'visto che in effetti l''optimizer cosi'' riscrive';
PRINT 'la query stessa.. vedi ad esempio il piano di esecuzione';
SELECT DISTINCT Id
FROM dbo.t
ORDER BY Id;
GO
DECLARE @param int;
DECLARE cur CURSOR FOR
SELECT DISTINCT Id
FROM dbo.t
ORDER BY Id;
OPEN cur;
FETCH NEXT FROM cur INTO @param;
WHILE @@FETCH_STATUS = 0 BEGIN
PRINT @param;
SELECT TOP (1) t2.Id
FROM dbo.t2
WHERE t2.IdT = @param
ORDER BY t2.Id DESC;
FETCH NEXT FROM cur INTO @param;
END;
CLOSE cur;
DEALLOCATE cur;
GO
CREATE FUNCTION dbo.ufnGetT2 (
@Id int
) RETURNS TABLE
AS
RETURN
SELECT TOP (1) t2.Id
FROM dbo.t2 t2
WHERE t2.Idt = @Id
ORDER BY t2.Id DESC;
GO
WITH cte AS (
SELECT DISTINCT Id
FROM dbo.t
)
SELECT f.Id
FROM cte
CROSS APPLY dbo.ufnGetT2 ( cte.Id ) AS f;
GO
PRINT 'che senza ufn si puo'' anche riscrivere in';
WITH cte AS (
SELECT DISTINCT Id
FROM dbo.t
)
SELECT t2.Id
FROM cte
CROSS APPLY (
SELECT TOP (1) t2.Id
FROM dbo.t2 t2
WHERE t2.Idt = cte.Id
ORDER BY t2.Id DESC
) t2;
GO
DROP FUNCTION dbo.ufnGetT2;
DROP TABLE dbo.t, dbo.t2;
--<------------
Id
-----------
1
2
3
che andrebbe meglio riscritto in un DISTINCT
visto che in effetti l'optimizer cosi' riscrive
la query stessa.. vedi ad esempio il piano di esecuzione
Id
-----------
1
2
3
1
Id
-----------
1
2
Id
-----------
3
3
Id
-----------
6
Id
-----------
1
3
6
che senza ufn si puo' anche riscrivere in
Id
-----------
1
3
6
ho prima semplificato la tua aggregazione, che di aggregazione ha solo l'indicazione mentre semanticamente tecnicamente si risolve in un DISTINCT, come puoi benissimo riscontrare anche dal piano di esecuzione comunque generato in vece del tuo GROUP BY, anche se si addiviene allo stesso risultato..
successivamente ho dimostrato la funzionalita' del cursore stesso, che comunque viene surclassato sia in eleganza che in performance e utilizzo di risorse dalle soluzioni successive..
una utilizza una funzione utente che restituisce una tabella composta da una singola riga relativa alla riga referenziante la prima tabella con l'id piu' alto (giusto per complicare le cose), dove la seconda utilizza una subquery con il medesimo risultato, e successivamente a tale risultato viene imposto l'operatore CROSS APPLY per l'esecuzione "riga per riga" relativamente al primo risultato derivante dal DISTINCT della tabella referenziata..
come vedi, se ho capito la tua esigenza, non ti serve affatto la bruttura del cursore per ottenere, per ciascun gruppo di fornitura, i riferimenti all'anagrafica fornitore..
saluti