SQL Server 2016, cursor

CorePress2024-01-24  6

Me gustaría usar un cursor de SQL Server para saltar a través de los registros de una tabla (tblSummary) y, en función de los valores de esa tabla, actualizar la columna EndValues ​​en una segunda tabla (tblDetails).

Se puede alcanzar el resultado deseado mediante la siguiente consulta, pero necesito el cursor:

SELECT d.id, d.subgroup, d.fraq, d.subaccount, EndValues = d.fraq*s.amount
FROM tblDetails d
LEFT JOIN tblSummary s ON d.ID = s.id 
                       AND LEFT(d.SubAccount,2) = s.mainAccount

Adjunto dos scripts .sql, uno prepara todos los datos necesarios (Configuración de datos) y el otro con el cursor precargado (cursor.sql). ¿Alguien puede actualizar el cursor de tal manera que pueda obtener el mismo resultado que la consulta anterior?

--Configuración de datos

--CREATE TABLES
CREATE TABLE tblSummary
(
    ID varchar(11),
    [MainAccount] varchar(12),
    [Amount] numeric (10, 3)
) 

CREATE TABLE tblDetails
(
    ID varchar(11),
    SubGroup varchar(30),
    Fraq numeric (10, 3),
    SubAccount int,
    EndValues numeric (10, 3) NULL
)

--POPULATE TABLES
INSERT INTO tblDetails (ID, SubGroup, Fraq, SubAccount, EndValues) 
VALUES
('Garden', 'Sub1', 0.2,101,NULL),
('Garden', 'Sub2', 0.5,102,NULL),
('Garden', 'Sub3', 0.3,103,NULL),
('Garden', 'Sub1', 0.1,201,NULL),
('Garden', 'Sub2', 0.5,202,NULL),
('Garden', 'Sub3', 0.9,203,NULL),
('Home', 'Sub1', 0.1,101,NULL),
('Home', 'Sub2', 0.3,102,NULL),
('Home', 'Sub3', 0.5,103,NULL),
('Home', 'Sub1', 0.8,201,NULL),
('Home', 'Sub2', 0.1,202,NULL),
('Home', 'Sub3', 0.1,203,NULL)



INSERT INTO tblSummary (ID, MainAccount, Amount) VALUES 
('Garden',10,1000),
('Garden',20,1200),
('Home',10,2000),
('Home',20,2500)


--DESIRED OUTPUT
SELECT d.id, d.subgroup, d.fraq, d.subaccount,EndValues=d.fraq*s.amount
FROM tblDetails d
LEFT JOIN tblSummary s 
ON d.ID=s.id and LEFT(d.SubAccount,2) = s.mainAccount

--CURSOR

DECLARE @ID VARCHAR(11)
DECLARE @MainAccount  VARCHAR(11)
DECLARE @Amount numeric (10,3)


DECLARE My_cursor CURSOR 
FOR SELECT 
       ID
       ,MainAccount   
       ,Amount
FROM tblSummary

 
OPEN My_cursor

FETCH NEXT FROM My_cursor INTO @ID, @MainAccount, @AMOUNT

WHILE @@FETCH_STATUS = 0
BEGIN
--CODE TO ENTER
    FETCH NEXT FROM My_cursor INTO @ID, @MainAccount, @AMOUNT
END
 
CLOSE My_cursor
DEALLOCATE My_cursor

1

Explica por qué crees que necesitas un cursor. Los cursores son generalmente raros en un tsql bien escrito, pero a menudo son un artefacto de alguien que tiene problemas con la codificación basada en conjuntos.

- SMor

27 de marzo de 2021 a las 12:36



------------------------------------

Fallo, así que mira por qué necesitas un cursor, ¡nadie casi nunca necesita un cursor!

¿Quiere actualizar la columna EndValues ​​con el cálculo de su consulta de selección?

Ya tienes la respuesta frente a ti, así que, a menos que haya algo que no entiendo sobre tu problema, simplemente haz esto

update d set
    d.EndValues=d.Fraq*s.Amount
from tblDetails d
left join tblSummary s 
on d.ID=s.ID and Left(d.SubAccount,2) = s.MainAccount



------------------------------------

No estoy seguro, realmente te entiendo el problema, pero puedes tomar tu consulta tal como está y declarar un cursor para ella

DECLARE my_second_cursor CURSOR FOR
SELECT d.id, d.subgroup, d.fraq, d.subaccount,EndValues=d.fraq*s.amount
  FROM tblDetails d
  LEFT JOIN tblSummary s 
  ON d.ID=s.id and LEFT(d.SubAccount,2) = s.mainAccount

FETCH NEXT FROM my_second_cursor into @id, @subgroup, @fraq, @subacount, @endvalues

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare