Am incercat varianta cu cursor, insa este de 4-5 ori mai lenta decat varianta cu select (asa cum era initial). Codul sursa pentru cursor este afisat mai jos:
--drop table A_tmplstFisaCont
select *, cast(0 as decimal(28,6)) as Sold into A_tmplstFisaCont from A_lstFisaCont order by cont, datainr, nds
update A_tmplstFisaCont set sold = 0
DECLARE @cont varchar(16), @datainr datetime, @nds int, @coduser int, @debit decimal(28,6), @credit decimal(28,6), @sold decimal(28,6)
DECLARE abc CURSOR FOR
SELECT cont, datainr, nds, coduser, debit, credit, sold
FROM A_tmplstFisaCont
--ORDER BY cont, datainr, nds --daca pun order by, cursorul este read-only si nu pot face update pe el
OPEN abc
FETCH NEXT FROM abc
INTO @cont, @datainr, @nds, @coduser, @debit, @credit, @sold
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE A_tmplstFisaCont SET Sold = isnull((select top 1 sold from A_tmplstFisaCont where cont = @cont and coduser = 1),0) + debit - credit
WHERE CURRENT OF abc
FETCH NEXT FROM abc
INTO @cont, @datainr, @nds, @coduser, @debit, @credit, @sold
END
CLOSE abc
DEALLOCATE abc
GO
(Sunt ceva greseli in cod in sensul ca nu-mi calculkeaza soldul, inca nu mi-am dat seama unde, dar nici nu am cautat din moment ce ma intereseaza in primul rand sa fac algoritmul sa ruleze mai rapid.)
Am incercat si varianta cu FAST_FORWARD, dar tot fara rezultat. Codul este si el foarte lent in comparatie cu SELECT in SELECT:
drop table A_tmplstFisaCont
select *, cast(0 as decimal(28,6)) as Sold into A_tmplstFisaCont from A_lstFisaCont order by cont, datainr, nds
alter table A_tmplstFisaCont add [iId] [int] IDENTITY (1, 1) NOT NULL
go
CREATE CLUSTERED
INDEX [iIdIdx] ON [dbo].[A_tmplstFisaCont] ([iId])
ON [PRIMARY]
GO
update A_tmplstFisaCont set sold = 0
DECLARE @id int, @cont varchar(16), @datainr datetime, @nds int, @coduser int, @debit decimal(28,6), @credit decimal(28,6), @sold decimal(28,6)
DECLARE abc CURSOR FAST_FORWARD READ_ONLY
FOR
SELECT iid, cont, datainr, nds, coduser, debit, credit, sold
FROM A_tmplstFisaCont
ORDER BY iid
OPEN abc
FETCH NEXT FROM abc
INTO @id, @cont, @datainr, @nds, @coduser, @debit, @credit, @sold
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE A_tmplstFisaCont SET Sold = isnull((select top 1 sold from A_tmplstFisaCont where cont = @cont and coduser = 1),0) + debit - credit
where iid=@id
-- WHERE CURRENT OF abc
FETCH NEXT FROM abc
INTO @id, @cont, @datainr, @nds, @coduser, @debit, @credit, @sold
END
CLOSE abc
DEALLOCATE abc
GO
PS: Am inlocuit money cu decimal(28,6) pentru ca asa apare in BD mea.
Alte idei ar mai fi?